• git、repo、JNI、NDK和AudioSystem


    how to use git and repo

    git中常见的指令

    新建一个仓库

    • git init

    • git clone <url>

    对仓库内内容的保存与判断

    git中使用的判断条件是:SHA-1校验和

    仓库中文件转换

    File Status Lifecycle

    • git add <file>

    Untracked

    使用add命令能够将untracked文件track,而通过reset命令能够将tracked转换成untracked

    add之后再查看文件状态

    tracked

    git fetch and pull

    指令示意图

    • git fetch:将远程主机的最新内容拉取到本地,用户在检查了以后决定是否合并到工作本机分支当中

    • git pull:将远程主机的最新内容拉取下来直接合并。即:git pull = git fetch + git merge

    git rebase and git merge

    • git rebase

    rebase 会把你当前分支的 commit 放到公共分支的最后面

    rebase示意图

    • git merge

    merge 会把公共分支和你当前的commit 合并在一起,形成一个新的 commit 提交

    merge示意图

    大串讲

    什么是JNI

    Java Native Interface

    作用:java通过JNI能够调用C++中的代码

    JNI 开发流程

    • 在Java中声明native方法

    • 编译Java源文件得到class文件,然后通过javah命令导出JNI头文件

    • 实现JNI方法

    • 编译so库并在Java中调用

    什么是NDK

    Native Development Kit -> 一种android的开发工具包

    作用:快速开发C、C++的动态库,可通过NDK在android中使用JNI与本地代码(C、C++)交互

    NDK 开发流程

    • 下载并配置NDK

    • 创建一个android项目,并声明所需的native方法

    • 实现android项目中所声明的native方法

    • 切换到JNI目录的父目录,然后通过ndk-build命令编译产生so库

    JNI方式的Audio数据梳理

    音频系统主要分为连个部分:数据流策略

    • 数据流: AudioTrackAudioFlinger就是数据流,描述了音频数据从数据源流向目的地的流程。

    • 策略: AudioPolicyServiceAudioService都是策略的范畴,管理及控制数据流的路径与呈现方式。

    Audio管理环节 Audio输出 Audio输入
    Java层 android.media.AudioSystem android.media.AudioTrack android.media.AudioRecorder
    本地框架层 AudioSystem AudioTrack AudioRecorder
    AudioFlinger IAudioFlinger IAudioTrack IAudioRecorder
    硬件抽象层 AudioHardwareInterface AudioSteamOut AudioStreamIn

    总通信方式大致如下:
    android通信方式

    Android音频系统的核心是Audio系统

    Audio系统框架结构

    在Java层中,AudioSystem的最上层是AudioService、AudioSystem进行着Audio相关的管理,下面是AudioService.java所在的路径。

    AudioService路径

    以其中一个为例子,isAudioServerRunning方法用来判断音频系统是否工作,可以看到,中间的checkMonitorAudioServerStatePermission()方法是用来判断是否给予权限,而实际上的判断语句是return后面AudioSystem.checkAudioFlinger进行比较的。

    AudioService中方法

    使用OpenGrok,我们可以追踪到AudioSystem.java文件所在的路径。

    PYUED.png

    在该类中,我们可以发现,其通过JNI的方式,声明了checkAudioFlinger()的方法。我们就可以通过该方法去JNI层去寻找C++中实现的类。

    AudioSystem中checkAudioFlinger

    可以看到,在core/jin/的包下,有一个android_media_AudioSystem.cpp的对应的文件进行实现JNI层提供的checkAudioFlinger()的接口。

    问:Java中如何通过方法名就能够找到native层中的函数呢?

    答:native层的函数名遵循如下规则:Java_包名_类名_方法名

    android_media_AudioSystem路径

    在android_media_AudioSystem.cpp中具体的实现方法如下:

    android_media_AudioSystem实现方式

    可以看到其中的具体实现是check_AudioSystem_Command()函数中实现的, 然后传入了AudioSystem中的CheckAudioFlinger()函数的返回值。下图显示的是AudioSystem类中的checkAudioFlinger()函数的实现。

    • NO_ERROR = 0

    checkAudioFlinger()方法

    check_AudioSystem_Command()函数中可以看到最终也是返回一个状态值。

    check_AudioSystem_Command()

    defaultServiceManager()是一个位于binder下IServiceManager.cpp中的一个函数

    defaultServiceManager智能指针

    注: sp指的是shared_ptr,C++11后推出的智能指针的概念。shared_ptr是实现共享式拥有概念。多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用被销毁”时候释放。

    总结

    以上只是一种从上层Java层一路追溯到native层中C++的实现方式。而这也侧面的证明了Java层与native层的数据通信的方式是通过Binder实现的。

    在native层中的AudioSystem.cpp中就属于一个中间件的作用,进行了承上启下,在AudioSystem.cpp中,有AudioFlinger相关的智能指针,如下图所示:

    AudioSystem中与AudioFlinger相关指针

    • gAudioFlinger作为AudioFlinger的代理端句柄可以输入输出设备进行相关控制。

    get_audio_policy_service函数

    • gAudioPolicyService作为AudioPolicyService服务代理端的句柄提可以对策略相关业务流程进行调度。
  • 相关阅读:
    Poj 3713 Transferring Sylla 3-连通
    SPOJ 7758 Growing Strings AC自动机DP
    ural 1209. 1,10,100,1000.....
    ural 1197. Lonesome Knight
    ural 1149. Sinus Dances
    优先级队列
    Codeforces Round #384 (Div. 2) C. Vladik and fractions
    Codeforces Round #384 (Div. 2) B. Chloe and the sequence
    Codeforces Round #384 (Div. 2) A. Vladik and flights
    POJ 1246 Find The Multiple
  • 原文地址:https://www.cnblogs.com/johnnytan/p/13405718.html
Copyright © 2020-2023  润新知