慕课网 剖析framework 笔记
3-2 应用是怎么启动binder机制的?
考察:
了解binder是干嘛的? 跨进程通信的
AP哪些地方用了binder机制? 调用系统服务,启动Activity,发广播,涉及到应用组件都要和AMS交互,就涉及binder机制。
AP的启动流程? 因为binder机制是在AP启动过程中启动的
进程怎么启动binder机制?
一,什么时候开始支持binder机制的?
回忆下什么时候开始使用binder的,
AP在启动1st Activity时,在Acitivity.onCreate()里面,就可以通过GetSystemService拿到系统服务了,这里就用到了binder,
再往前,在Application.onCreate()里面一样可以调用到系统服务,
说明AP启动binder机制比他们都要早
看看AP启动流程,之前说过:
AMS想要启动一个应用组件如Activity,但是发现组件所在进程还没启动,
AMS会向zygote发请求,启动进程,
zygote启动好进程,AP会报告给AMS,
所以AP启动binder最可能在什么环节?看看第一次跨进程通信:AP启动后通知AMS时
那启动binder机制就比他更早,可能是zygote启动进程时做的,
还是看zygote的runOnce(),讲了好几次了,
zygote收到AMS的请求,调用runOnce,
它先readArgumentList()读取参数列表,参数就是AMS发过来的,
然后调用forkAndSpecialize()创建进程
在子进程调用handleChildProc()
handleChildProc会执行zygoteInit(),前面讲过,里面有3个init,最重要的是nativeZygoteInit(),
它是一个native函数
void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, ...){
gCutRuntime->onZyoteInit();
}
virtual void onZygoteInit(){
//拿到当前的ProcessState,看看它的self
sp<ProcessState> proc = ProcessState::self();
//启动线程池
proc->startThreadPool();
}
//这是典型的单例模式,就像java的getInstance
sp<ProcessState> ProcessState::self(){
if(gProcess != NULL){
return gProcess;
}
gProcess = new ProcessState;
return gProcess;
}
//再看ProcessState的构造函数
ProcessState::ProcessState()
//这里有一个成员变量叫mDriverFD,它是通过open_driver返回的,open_Driver做了什么?
//open("/dev/biner",O_RDWR);所以ProcessState打开的binder驱动
:mDriverFD(open_driver()),...{
if(mDriverFD >= 0){
//DriverFB有效,就把它映射到当前进程的内存空间,
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, ..., mDriverFD, 0);
}
}
再看看ProcessState::startThreadPool()函数,看看它是怎么启动线程池的
spawn:产卵
void ProcessState::startThreadPool(){
//布尔变量做防御,防止里面调2次
if(!mThreadPoolStarted){
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
void ProcessState::spawnPooledThread(bool isMain){
if(mTheadPoolStarted){
//new一个PoolThread然后run起来,
//原来线程池里就这么一个线程,名不副实
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
//再看看poolThread
//继承了thread类,
class PoolThread:public Thread{
//调用threadLoop函数
virtual bool threadLoop(){
//这里出现了一个IPCTthreadState,它也是单例
//但是是线程里面的单例,而不是进程里面的单例
//joinThreadPool
IPCThreadState::self()->joinThreadPool(mlsMain);
return false;
}
}
void IPCThreadSttate::joinThreadPool(bool isMain){
//往mOut写了一个BC_ENTER_LOOPER,mOut是什么?
//IPCTHreadState里面有两个parce,一个是mIn,一个mOut,
//如果有什么数据要写到Binder驱动,就写到mOut,
//如果有数据返回回来,数据就放在mIn里面
mOut.writeInt32(isMain?BC_ENTER_LOOPER:BC_REGISTER_LOOPER);
do{
//循环,不会退出,
//getAndExecuteCommand是核心函数
result = getAndExecuteCommand();
...
}while(result != -ECONNREFUSED && result != -EBADF);
}
status_t IPCThreadState::getAndExecuteCommand(){
//可以能驱动写,也可能从驱动读,
//对于binder线程,一般是等待从binder驱动发过来的binder transact请求,读完再回复请求
talkWithDriver();
//读cmd并且处理cmd,所以这里是根据binder发过来的指令执行不同的操作。
cmd = mln.readInt32();
executeCommand(cmd);
return result;
}
//IPCTHreadState里面有两个parce,一个是mIn,一个mOut,
//如果有什么数据要写到Binder驱动,就写到mOut,
//如果有数据返回回来,数据就放在mIn里面
。。。。
总结,怎么启用binder机制
打开binder驱动
映射内存,分配缓冲区
注册binder线程
进入binder loop,不断的和binder驱动交互
问题:应用是怎么启用binder机制的?
1,什么时候启用binder机制,启用时机是什么,
说下AP启动流程
2,怎么启用binder机制,就是上面列出的4条