ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Android framework 应用进程如何启动binder机制

2019-06-03 16:52:15  阅读:330  来源: 互联网

标签:framework 启动 AP binder 线程 ProcessState mOut Android


慕课网 剖析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条

标签:framework,启动,AP,binder,线程,ProcessState,mOut,Android
来源: https://blog.csdn.net/u012654756/article/details/90754322

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有