Binder线程是执行Binder服务的载体,只对于服务端才有意义,对请求端来说,是不需要考虑Binder线程的,但Android系统的处理机制其实大部分是互为C/S的。比如APP与AMS进行交互的时候,都互为对方的C与S,这里先不讨论这个问题,先看Binder线程的概念。
Binder线程就是执行Binder实体业务的线程,一个普通线程如何才能成为Binder线程呢?很简单,只要开启一个监听Binder字符设备的Loop线程即可,在Android中有很多种方法,不过归根到底都是监听Binder,换成代码就是通过ioctl来进行监听。
拿ServerManager进程来说,其主线就是Binder线程,其做法是通过binder_loop实现不死线程:
void binder_loop(struct binder_state *bs, binder_handler func) { ... for (;;) { <!--关键点1--> res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); <!--关键点2--> res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func); 。。 } }上面的关键代码1就是阻塞监听客户端请求,2 就是处理请求,并且这是一个死循环,不退出。再来看SystemServer进程中的线程,在Android4.3(6.0以后代码就不一样了)中SystemSever主线程便是Binder线程,同是一个Binder主线程,Binder线程与Binder主线程的区别是:线程是否可以终止Loop,不过目前启动的Binder线程都是无法退出的,其实可以全部看做是Binder主线程,其实现原理是,在SystemServer主线程执行到最后的时候,Loop监听Binder设备,变身死循环线程,关键代码如下:
extern "C" status_t system_init() { ... ALOGI("System server: entering thread pool.\n"); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); ALOGI("System server: exiting thread pool.\n"); return NO_ERROR; }ProcessState::self()->startThreadPool()是新建一个Binder主线程,
而PCThreadState::self()->joinThreadPool()是将当前线程变成Binder主线程。
其实startThreadPool最终也会调用joinThreadPool,看下其关键函数:
void IPCThreadState::joinThreadPool(bool isMain) { ... status_t result; do { int32_t cmd; ...关键点1 result = talkWithDriver(); if (result >= NO_ERROR) { ...关键点2 result = executeCommand(cmd); } // 非主线程的可以退出 if(result == TIMED_OUT && !isMain) { break; } // 死循环,不完结,调用了这个,就好比是开启了Binder监听循环, } while (result != -ECONNREFUSED && result != -EBADF); } status_t IPCThreadState::talkWithDriver(bool doReceive) { do { ...关键点3 if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) }先看关键点1 talkWithDriver,其实质还是去掉用ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)去不断的监听Binder字符设备,获取到Client传输的数据后,再通过executeCommand去执行相应的请求,joinThreadPool是普通线程化身Binder线程最常见的方式。不信,就再看一个MediaService,看一下main_mediaserver的main函数:
int main(int argc, char** argv) { 。。。 sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); ALOGI("ServiceManager: %p", sm.get()); AudioFlinger::instantiate(); MediaPlayerService::instantiate(); CameraService::instantiate(); AudioPolicyService::instantiate(); registerExtensions(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }其实还是通过joinThreadPool变身Binder线程,至于是不是主线程,看一下下面的函数:
void IPCThreadState::joinThreadPool(bool isMain) void ProcessState::spawnPooledThread(bool isMain) { if (mThreadPoolStarted) { String8 name = makeBinderThreadName(); ALOGV("Spawning new pooled thread, name=%s\n", name.string()); sp<Thread> t = new PoolThread(isMain); t->run(name.string()); } }其实关键就是就是传递给joinThreadPool函数的isMain是否是true,不过是否是Binder主线程并没有什么用,因为源码中并没有为这两者的不同处理留入口,感兴趣可以去查看一下binder中的TIMED_OUT。