参考:Android_BootTime_introduction_20140215.pptx
第1 章 阅读前的准备工作
1.1 系统架构
1.1.1 Android 的系统架构
1.1.2 本书的架构
1.2 搭建开发环境
1.2.1 下载原代码
1.2.2 编译原代码
1.3 工具介绍
1.3.1 source insight
1.3.2 busybox
第2 章 深入理解JNI
2.1 JNI 概述
2.2 学习JNI的实列:mediascanner
libmedia_jni.so,JNI库名.下划线前的media是native 层库的名字.
2.3 Java层mediascanner的分析
包括三个部分 1)加载JNI库,2)非native的实现,3)native 函数的申明
2.4 JNI层mediascanner的分析
2.4.1 注册JNI
(1) 通过javah工具//静态方式
javah -o output packagename.classname 生产output.h,实现对应的funtion.
(2) 通过Android 虚拟机 jint JNI_onload( JavaVM*,void reserved)//动态方式.
registerNativeMethod(JNIEnv *env,cost char *ClassName const JNINativeMethod*gMethods, int numMethods)
typedef struct
{
const char*name//native 函数名
const char*signature//参数类型和返回值类型组合的签名信息
void *fnptr//JNI 层对应的函数指针
}JNINativeMethod
2.4.2 数据类型的转换
基本数据类型的数组,class,string,thowable有对应的J*外,其他Jobject
2.4.3 JNIEnv的介绍
JNIEnv是线程相关的变量.JavaVM全局变量,通过attachCurrentThread/detachcurrentthread来改变JNIEnv
2.4.4 通过JNIEnv操作Jobject.调用java对象的函数
成员变量->jFielID// get<type>field/set<type>field
成员函数->jmethodID//通过JNIenv 输出call<type>method<JNIEnv*env,Jobject obj,jmethod...>
2.4.5 jstring介绍
(1) native 字符转换成java对象
env->NewString/env->NewStringUFT
(2) java string 对象转换成native 字符.
env->GetStringChars/env->GetStringUFTChars
(3)JVM资源的释放
env->ReleaseStringUFTchars/env->ReleaseStringchars
2.4.6 JNI类型签名介绍
使用工具:javap -s -p xx
2.4.7 垃圾回收
(1) local reference //通过env->DeleteLocalRef 来释放
(2) Global reference//通过env->NewGlobalRef/env->DeleteGlobalRef
2.4.8 JNI中的异常处理
env->ExceptionOccure
env->ExceptionClear
env->Thrownew
Q:在java中怎么找到class 中native 函数的实现呢?
A:第一步:sourceinsight搜索 class,
第二步: 找到对应JNI register函数.找到 gmethod数组.
第三步: 再找对应native 方法的实现.
Q:java world怎么调到native world
A:
Q:native world怎么调回到 java world.
A:
Q:JNIenv 的实现原理
A:
第3 章 深入理解init
3.1 概述
3.2 init分析
\system\core\init\init.c
1. 解析两个配置文件 init.rc/init.$hardware.rc
2. 创建zygote
3. property_init
4. 进入一个循环 等待是否有重启行为.
3.2.1 解析配置文件 init.rc
通过 init_parse_config_file(const char *fn)解析*.rc文件.
(1)*.rc文件主要由3部分组成,定义在keyword.h中
1: SECTION:如,Service,on,import
2: COMMAND; class_start
3: OPTION ;socket,
3.2.2 分析service
(1)通过parse_service和parse_line_service解析如下Service 结构体.
通过parse_action和parse_line_action 解析action/command.
通过parse_import导入其他*.rc
如下是解析zygote Service.得到struct service
(2) init 控制 service
a:queue_builtin_action 把action加到队列中,通过action_for_each_trigger 把section中 队列tigger起来.
如 class_start XXXX,调起XXX Service.
如:do_class_start,
从而start init.rc中Service.
b:重启zygote
在sigal_init创建socket,当zygote退出时,父进程init会调用sigchld_Handler写 signal_fd,同时在父进程init poll函数检测此文件, 来重启onrestart的Service.
3.2.4 属性服务setprop/getprop
(1)属性服务端的初始化/ property_init
a:通过open "/dev/__properties__,"后mmp到共享内存,
b:通过gcc constructor 属性中libc_prenit函数完成共享内存到进程本地映射工作,供所有进程使用.
C: 通过property_load_boot_default 来load配置文件.
(2) 启动属性服务端/start_property_Service
a:load 相关的配置文件
b;创建socket文件.
(3) 属性服务端处理/hanle_property_set_fd
a: 在init.c main函数中监听property_fd事件,call hanle_property_set_fd 处理属性请求.
(4) 客户端通过properties.c中,set/get/list来操作.
客户端通过从connect/send msg到socket,服务端监听property_fd,来处理属性请求.
第4 章 深入zygote
4.1 概述
4.2 zygote 分析
zygote 是app_process进程的别名,通过main 函数中AppRuntime .start 0
4.2.1 appRuntime 分析
其中androidRuntime start完成3个任务:
1)startvm
2)startreg
3)通过callStaticVoidMethod call java 世界的main.
4.2.2 ZygoteInit main函数分析
1) registerZygoteSocket//建立通信IPC server 端
2) preload//预加载类和资源,比较耗时.
3)startsystemServer// 启动系统服务.
4)runSelectLoopMode//处理客户连接和客户请求
4.3 systemserver分析
4.3.1 systemserver的诞生
通过zygote.forsystemserver()调用native函数:
dalvik_dalvik_system_zygote_forsystemserver().//???? 在java中怎么找到class 中native 函数的实现呢?
4.3.2 systemserver的职责
调用runtimeInit.java中zygoteInit()
1) 调用nativeZygoteInit 建立Binder 通信.
2)通过ApplicationInit 中的invokeStaticMain call class中的main函数.//通过截获methodandargscaller
3)systemserver的启动.
4.3.3 systemserver的总结
4.4 zygote 分裂
(1) 如ActivityService通过process.start(),建立socket与zygote通信.发送请求
(2)zygote处理请求:
zygoteinit.java 中的runselectLoopmode()来得到请求.Zygoteconnect.java中runOnce处理请求!
4.5 zygote 分裂总结
4.6 watchdog
1) watchdog创建和初始化:创建一个Handler类 处理消息
2)watchdog的启动.systemservercall init/run.
3)watchdog使用.Service调用addmonitor 实现monitor接口//如powermanagerserver
第5 章 深入常见类
5.1 概述
5.2 Refbase类
SP(strong pointer),WP(weak pointer)
class A:public Refbase 会同时创建一个实际对象和一个影子对象.
5.2.1 先sp化,后wp 化
class A: public Refbase
{
A*pA=new A
{
sp<A> spA(pA);//先sp 化pA,再wp 化 spA
wp<A>wpA(spA);
// 先析构wp,后析构sp.
}
}
1)Refbase中有一个隐含的影子对象,该影子对象内部有一个强弱引用计数器
2)sp化后强弱引用计数器加1,析构后强弱引用计数器减1
3)当flag=0 强引用计数器=0 delete 实际对象
当flag=0 弱引用计数器=0 delete 影子对象.
5.2.2 先wp化,后sp 化
class A: public Refbase
{
A*pA=new A
{
wp<A>wpA(pA);
sp<A> spA=wpA.promote();
}
}
1)有弱生强后,影子对象强引用计数器1,弱引用计数器2
5.2.3 生死难题
5.3 Thread 类
5.3.1 thread.cpp分析:
(1)mcancallJava的使用
true时.
1.在调用线程函数之前会attach到JNI 环境中,可以使用JNI 函数了
2.退出时,从JNI 环境detach,shift资源
(2)_threadloop介绍
在子类threadloop 返回false(主动退出),mExitpengding=true (被动退出).
5.3.2 常用的同步类:
(1)mutex
(2)condition
(3)atomic
5.4 looper和handler类分析.
5.4.1 looper类的分析
第一步:定义looperthread 类,在run 函数总call
looper.prepare//new一个looper 对象,设置这个对象在本地线程存储(TLS)
looper.loop//获取msg,分发msg
第二步:在应用程序用code looperthread .start()
5.4.2 Handler类的分析
(1) 构造函数Handler()//msg looper.callback函数设置
(2) 发送msg函数 sendMessage()//设置msg.target为Handler 对象
(3) 处理msg函数 dispatchmessage()//优先级:message自己带的callback>Handler.mcallba>子类 Handler(一般用法)
5.4.3 looper与Handler同步
hanlerthread 处理多线程同步问题.
第6 章 深入理解Binder
6.1 概述
6.2 通过native MediaServer 解析Binder
6.2.2 进程ProcessStatate
1)采用单列模式 ProcessState//Q:什么叫做进程的单列模式呢?
2) ProcessState 构造函数.
打开/dev/Binder 设备.
6.2.3 得到defaultservermanager:
(1)调用流程:
gdefaultServiceManager=interface_cast<IServiceManager>(ProcessState:self->getContextobject(null));
ProcessState:self->getContextobject(null)=getStrongProxyForHandle(0);
getStrongProxyForHandle(0)=new BpBinder(0);
(2):BpBinder/BBinder的关系:P:Proxy,
(3) interface_cast模板
template<typename INTERFACE>
inline sp<INTERFACE>interface_cast(const sp<>)
{
return INTERFACE::asInterface(obj);
}
因此:
interface_cast<IServiceManager>(ProcessState:self->getContextobject(null))
等价:
IServiceManager::asInterface(new BpBinder(0))
(4) IServiceManager
1):两个关键的define
DECLARE_META_INTERFACE(INTERFACE)
IMPLEMENT_META_INTFACE(INTERFACE,NAME)
1:定义实现字符描述符,2.定义实现asinterface,3.定义实现字符描述符.4.定义实现构造/析构函数.
2) IServiceManager 家谱.
注意BnServiceManager从BBinder和IServiceManager派生,
但是BpServiceManager仅从IServiceManager派生.通过形参与传入BpServiceManager与BpBinder联 系.
3)把IServiceManager替换到IMPLEMENT_META_INTFACE中的asinterface中
IServiceManager:asInterface(const android::sp<android::IBinder>&obj)
{
android::sp<IServiceManager>intr
if(obj!=null)
{
intr=static_cast<IServiceManager*>(obj->querylocalinterface (IServiceManager::description).get());
if(intr=Null)
{
intr=new bpServiceManager(obj);//即bpServiceManager(new BpBinder(0));
}
}
}
4) bpServiceManager构造函数是调基类的构造函数.
bpServiceManager(new BpBinder(0))=Bpinterface<IServiceManager>(new BpBinder(0));
Bpinterface<IServiceManager>(new BpBinder(0))=BpRefBase(new BpBinder(0))\
即:mRemote指向new BpBinder(0)对象.
6.2.4 注册MediaPlayerService
1)业务层的工作
注册过程:
addservice>
remote->transact/bpBinder->transact>
IPCThreadState->transact>
IPCThreadState->writeTransactiondata
2)通信层的工作//IPCThreadState
1:self 函数//TLS thread local storage
2:构造函数;
3:transact 中writeTransactiondata 往Binder 发送data,waitforresponse接受回复.
回应过程:
IPCThreadState->waitforresponse>
IPCThreadState->excutecommand(cmd)>
BBbinder->transact>bnServiceManager->transact(图6.3.bnServiceManager 从BBbinder派生,实现 transact虚函数.)
3)IPCThreadState->talwithDriver 中mOut/mIn与"/dev/Binder"交互.
6.2.5 ProcessState中startThreadPool
6.2.6 IPCThreadState中joinThreadPool
6.3 服务总管ServiceManager
6.3.1 ServiceManager原理分析//ServiceManager.c
1.打开设备
2.变成manager
3.注册回调函数.
6.3.2 回调函数Service的注册.
6.3.3 ServiceManager的意义
6.4 MediaPlayerService的client.//使用使用Service.
1:通过defaultServiceManager 得到ServiceManager
2:注册death notify
3:通过interface_cast得到Service的bpServiceXX.
6.5 拓展思考
6.5.1 Binder与线程的关系:
Binder设备与发送请求的线程栓,得到回复才离开.
6.5.2 Binder的notifier(讣告)
(1)注册讣告
(2)实现讣告
(3)注销讣告
(4)讣告实现原理(reg callback函数)//IPCThreaState.cpp
6.5.3 匿名Service//未注册到ServiceManager的Service
在client 调用creat 函数,在Service端实现一个对象.这样client就可以跨线程调用对象的业务函数了.
6.6 学以致用//实现一个binder client/Service.
6.6.1纯native的Service
(1) main函数:
int main()
{
SP<ProcessState>proc(ProcessState::self());
SP<IServiceManager>sm=defaultServiceManager();
sm->addService("Service name",new test());//注册Service
ProcessState::self()->startthreadpool;
ProcessState::self()->jointhreadpool;
}
(2)定义接口类:
ITest.h
class ITest:public Interface
{
DECLARE_META_INTERFACE( test);//神奇
virtual void gettest;//
virtual void Settest;// 定义业务函数
}
(3)从ITest interface派生服务端Bntest类
主要实现 ontranact,IMPLEMENT_META_INTERFACE宏
class Bntest:public Bntest interface<Itest>
{
IMPLEMENT_META_INTERFACE(test,"android.test.ITest");
status_t Bntest:: ontransact(unit32_t code,const Parcel&date,parcel*reply uin32_t flag)
{
swtich(code){
case GET_TEST:
CHECK_INTERFACE()
gettest()
....
case SET_TEST:
....
}
}
}
(4)从ITest interface派生客户Bptest类:
class Bptest:public Bpinterface<ITest>
{
pubic:
BpXXX(const sp<IBinder>&impl):Bpinterface<ITest>(impl);
{
}
vitural get()
{
......
}
vitural Set()
{
......
}
}
6.6.2 ADIL
(1) 实现AIDL
(2) 实现服务端
(3) 实现client端
(4)复杂数据的传递
第7 章 深入理解Audio系统
7.1 概述
7.2 Audio Track的破解
7.2.1 用列介绍
1: 数据的加载模式:MODE_STREAM/MODE_STATIC
2: 音频流类型:STREAM_ALARM,STREAM_MUSIC,STREAM_RING,STREAM_SYSTEM,STREAM_VOCIE_CALL.
3: Buffersize.的分配和计算.
7.2.2 Audiotrack分析(Java 层)
构建函数:
1: AudioTrackJNIStorage
(1) :new 一个audiotrack,使用无参的构造函数
(2):调用 set 函数,把JAVA 层的参数传进去,设置audiocallback函数
(3):调用audio track.start 函数
(4):调用audio track.stop 函数
(5):调用audio track.delete 函数
7.2.2 Audiotrack分析(Native 层)
1:Audiotrack.set 分析
(1) 创建 AudioTrackThread(),启动线程,//
(2) 调用 createTrack_L,
1:创建IAudioTrack
2: 得到mcblk(control block).
Q:mcblk=static_cast<audio_track_cblk_t * >(cblk->pointer()) 为什么这边做呢?
2:Audiotrack.write 分析
(1) 通过obtainBuffer/releaseBuffer,audiotrack 与control block 交互.
3:Audiotrack.析构函数.
7.2.3 Audiotrack的总结
7.3 AudioFlinger的破解
7.3.1 AudioFlinger 常驻MediaServer 进程中
7.3.2 通过流程分析AudioFlinger
(1) 流程: AudioFlinger.cpp:createTrack-->AudioFlinger.cpp:createTrack_l-->track::trackBase
(2) AudioFlinger object.
1:Client 对象
2:thread 对象
(1)PlaybackThread 回放线程AudioStreamOutput 与输出音频设备
(2)RecordThread 录音线程AudioStreamInput 与输入音频设备
(3)DirectOuputThread
(4)Mixerthread
(6) Duplication多路输出线程
3:track对象
4:以Mixthread 类分析音频数据的处理// 重点和难点
(1)通过output的值找到对应的thread
(2)创建Mixthread
(3)Mixthread.start 和消费数据
(4)Mixthread.stop 和消费数据
7.3.3 audio_track_cblk_t 分析
1. 数据生产者(写入),AT:->frameAvailable->buffer.->setuser
2. 数据的消费者(读取) AF:->framesReady->stepserver.
7.3.4 关于Audioflinger 的总结
7.4 AudioPolicyService的破解
7.4.1 AudioPolicyService的创建
AudioPolicyService 找到对应的MixThread,给他发送控制信息,再发给音频设备HAL.
7.4.2 重合AudioTrack
1 .set 函数:获取工作线程索引号
2 stat/stop函数:路由切换
7.4.3 声音路由切换实列分析(耳机插拔)
Q:怎么对接不同硬件平台
7.5 拓展思考
7.5.1 duplicationThread 破解
7.6 Audio系统小结:
第8 章 深入理解surface系统
8.1 概述
第9 章 深入理解vold/Rild
第10章 深入理解Mediascanner
275页