本文参考《Android系统源代码情景分析》,作者罗升阳

一、测试代码:

~/Android/external/binder/server

----FregServer.cpp

~/Android/external/binder/common

----IFregService.cpp

----IFregService.h

~/Android/external/binder/client

----FregClient.cpp


Binder库(libbinder)代码:

~/Android/frameworks/base/libs/binder

----BpBinder.cpp

----Parcel.cpp

----ProcessState.cpp

----Binder.cpp

----IInterface.cpp

----IPCThreadState.cpp

----IServiceManager.cpp

----Static.cpp

~/Android/frameworks/base/include/binder

----Binder.h

----BpBinder.h

----IInterface.h

----IPCThreadState.h

----IServiceManager.h

----IBinder.h

----Parcel.h

----ProcessState.h


驱动层代码:

~/Android//kernel/goldfish/drivers/staging/android

----binder.c

----binder.h


二、源码分析

继续上一篇Android Binder进程间通信---FregServer进程,处理BC_REPLY,返回BR_REPLYhttp://blog.csdn.net/jltxgcy/article/details/26339313,执行完waitForResponse函数,参考Android Binder进程间通信---FregServer进程,发送BC_TRANSACTION,睡眠等待http://blog.csdn.net/jltxgcy/article/details/26076149。应该返回IPCThreadState类的transact方法,再返回BpBinder类的transact函数,最后返回BpServiceManager类addService函数。最后再返回FregService类的main函数,实现如下:

~/Android/external/binder/server

----FregServer.cpp

int main(int argc, char** argv){FregService::instantiate();ProcessState::self()->startThreadPool();//启动一个Binder线程池IPCThreadState::self()->joinThreadPool();//主线程加入线程池return 0;}
首先当前进程的ProcessState对象的成员函数startThreadPool来启动一个Binder线程池,接着继续调用当前线程的IPCThreadState对象的成员函数joinThreadPool,将当前线程加入到前面所启动的Binder线程池中去等待和处理来自Client进程的进程间通信请求。

下面我们就分析ProcessState类的成员函数startThreadPool的实现,在分析过程中,同时也会分析IPCThreadState类的成员函数joinThreadPool的实现。

ProcessState类的成员函数startThreadPool的实现如下:

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

void ProcessState::startThreadPool(){    AutoMutex _l(mLock);    if (!mThreadPoolStarted) {//默认值为false        mThreadPoolStarted = true;//防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池        spawnPooledThread(true);    }}
当前进程的ProcessState对象的成员变量mThreadPoolStarted被初始化为false,当它将一个Binder线程池启动起来之后,就会将内部的成员变量mThreadPoolStarted的值设置为true,防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池。spawnPooledThread函数实现如下:

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

void ProcessState::spawnPooledThread(bool isMain){    if (mThreadPoolStarted) {        int32_t s = android_atomic_add(1, &mThreadPoolSeq);        char buf[32];        sprintf(buf, "Binder Thread #%d", s);        LOGV("Spawning new pooled thread, name=%s\n", buf);        sp<Thread> t = new PoolThread(isMain);//isMain为true        t->run(buf);//启动一个新的线程    }}
创建了一个PoolThread对象t,调用它的成员函数run来启动一个新的线程。

PoolThread类继承了线程类Thread,并且重写了它的线程入口成员函数threadLoop,因此当一个PoolThread对象t所对应的线程启动起来之后,它的成员函数threadLoop就会被调用。实现如下:

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

class PoolThread : public Thread{public:    PoolThread(bool isMain)        : mIsMain(isMain)//isMain为true    {    }    protected:    virtual bool threadLoop()    {        IPCThreadState::self()->joinThreadPool(mIsMain);//isMain为true        return false;    }        const bool mIsMain;};
和主线程一样调用了IPCThreadState类的成员函数joinThreadPool。实现如下:

~/Android/frameworks/base/libs/binder

----IPCThreadState.cpp

void IPCThreadState::joinThreadPool(bool isMain)//默认值为true{    .........    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);//isMain为true,BC_ENTER_LOOPER        ........            status_t result;    do {        int32_t cmd;                .......        result = talkWithDriver();//将自己注册到Binder线程池中,一个无线循环中不断等待进程间通信请求        if (result >= NO_ERROR) {            size_t IN = mIn.dataAvail();            if (IN < sizeof(int32_t)) continue;            cmd = mIn.readInt32();            ........            result = executeCommand(cmd);//处理进程间通信请求        }               .........        if(result == TIMED_OUT && !isMain) {//一直为false,因为isMain为true            break;        }    } while (result != -ECONNREFUSED && result != -EBADF);    ........        mOut.writeInt32(BC_EXIT_LOOPER);//退出Binder线程池    talkWithDriver(false);}
参数isMain是一个默认参数,它的默认值为true。从前面的调用过程可以知道,无论是FregServer进程的主线程,还是FregServer进程刚才所创建的线程,它们都是主动(isMain为true)请求加入到Binder线程池的,即它们都不是由于Binder驱动程序请求创建而加入到Binder线程池的。

一个Binder线程的生命周期可以划分为三个阶段:

第一阶段是将自己注册到Binder线程池中;

第二阶段是一个无线循环中不断等待和处理进程间通信请求;
第三阶段是退出Binder线程池。

最后执行完的结果是FregServer有两个线程,睡眠等待进程间通信数据的到来。

更多相关文章

  1. Android JNI char* 和jstring类型相互转换函数。
  2. android]Android 线程优先级修改
  3. 【Android】线程/进程绑定指定CPU核
  4. Service Manager进程启动,睡眠等待在进程proc->wait
  5. Android JNI 开启子线程后调用 Activity 方法更新UI
  6. Android多线程
  7. Android启动各种系统服务线程
  8. Android使用AIDL实现进程间通信

随机推荐

  1. 更大的舞台在等你
  2. sql server查看表空间
  3. 条件复杂的sql语句查询
  4. 根据(var2) (var3) (var3)极限X (var3)对
  5. 条件SQL选择-当返回集为空时,执行另一个选
  6. ORACLE PL/SQL编程详解之二:PL/SQL块结构
  7. SQL优化(待完善)
  8. Python自动化拉取Mysql数据并装载到Oracl
  9. 最新MySQL安装配置教程
  10. mysql获取当前时间、秒数