文章目录
- 应用是什么时候支持 binder 机制的
- 应用大致启动流程是什么
- 总结问题
应用是什么时候支持 binder 机制的
- binder 都知道是用来做跨进程服务的,应用内可以通过binder 跟系统组件进行交互。如 AMS Service aidl 等
- 那么可以思考一下,当 Activity onCreate() 的时候,甚至是 Application 的 onCreate() 的时候都可以获取的到系统服务,所以此时 binder 机制一定是初始化好了的。
应用大致启动流程是什么

当系统启动一个组件时,发现其进程未启动会通过 AMS 向 Zygote 发送请求启动应用,zygote 启动应用好了以后,应用会告知 AMS 启动完成,所以,应用通过binder进行通信最早应该是启动好后就已经和 AMS 通信了。所以可以看看再之前启动进程过程中是否启动了 binder 机制。
- 进程启动流程
之前有说过 zygote 进程启动之后会调用 zygoteServer.runSelectLoop(abiList); 开启 loop 等待和处理创建应用的消息。所以我们看看 loop 中获取到消息以后会处理哪些东西;
Android 9.0 当消息到来的时候会执行 Runnable processOneCommand() 方法
Runnable processOneCommand(ZygoteServer zygoteServer) {String args[];Arguments parsedArgs = null;FileDescriptor[] descriptors;try {// 先读取 AMS 发送过来的参数列表args = readArgumentList();descriptors = mSocket.getAncillaryFileDescriptors();} catch (IOException ex) {throw new IllegalStateException("IOException on command socket", ex);}/// 略......int pid = -1;// 通过 forkAndSpecialize 创建应用的进程pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,parsedArgs.instructionSet, parsedArgs.appDataDir);/// 略......try {// pid == 0 代表子进程if (pid == 0) {// in childzygoteServer.setForkChild();zygoteServer.closeServerSocket();IoUtils.closeQuietly(serverPipeFd);serverPipeFd = null;// handleChildProc 内部会关闭 socket 后执行 ZygoteInit.zygoteInit() 函数return handleChildProc(parsedArgs, descriptors, childPipeFd,parsedArgs.startChildZygote);} else {return null;}} finally {}
}
ZygoteInit.zygoteInit() 函数如下
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {if (RuntimeInit.DEBUG) {Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");}Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");RuntimeInit.redirectLogStreams();// 做一些常规的初始化RuntimeInit.commonInit();ZygoteInit.nativeZygoteInit();return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);}
- ZygoteInit.nativeZygoteInit();
这个是 native 方法 private static final native void nativeZygoteInit(); 调用的是 AndroidRuntime.cpp中的方法
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{gCurRuntime->onZygoteInit();
}
virtual void onZygoteInit(){sp<ProcessState> proc = ProcessState::self();ALOGV("App process: starting thread pool.\n");proc->startThreadPool();}
- ProcessState::self(); 函数
// ProcessState 这是一个单例
sp<ProcessState> ProcessState::self()
{Mutex::Autolock _l(gProcessMutex);if (gProcess != NULL) {return gProcess;}gProcess = new ProcessState("/dev/binder");return gProcess;
}
ProcessState::self() 函数创建了一个 ProcessState() 对象并传入了 “/dev/binder” 参数,然后看一下ProcessState构造函数。
ProcessState::ProcessState(const char *driver): mDriverName(String8(driver)), mDriverFD(open_driver(driver)), mVMStart(MAP_FAILED)// ...., mThreadPoolStarted(false), mThreadPoolSeq(1)
{if (mDriverFD >= 0) {// mmap the binder, providing a chunk of virtual address space to receive transactions.mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);if (mVMStart == MAP_FAILED) {// *sigh*ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());close(mDriverFD);mDriverFD = -1;mDriverName.clear();}}LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
}
上面方法主要有两个 第一个 定义了 mDriverFD(open_driver(driver)) ,通过open_driver() 赋值,open_driver() 就是打开 binder驱动,如果 mDriverFD > 0 则代表有效的,则通过 mmap 映射到对用的内存空间。所以启动binder机制是在进程启动之后初始化ProcessState中启动的
- onZygoteInit() 方法在打开 binder驱动之后会在调用 proc->startThreadPool(); 函数。线程池中只有一个线程,标记成binder线程,然后开启循环一直等待 binder 启动的操作指令进行执行命令。
总结问题
binder机制是如何启动的
- 打开 binder 驱动
- 映射内存分配缓冲区
- 注册binder线程
- 进入binder loop

















