Step 15. talkWithDriver 这个函数定义在frameworks/base/libs/binder/IPCThreadState.cpp文件中:
        
  1. status_tIPCThreadState::talkWithDriver(booldoReceive)
  2. {
  3. ......
  4. binder_write_readbwr;
  5. //Isthereadbufferempty?
  6. constboolneedRead=mIn.dataPosition()>=mIn.dataSize();
  7. //Wedon'twanttowriteanythingifwearestillreading
  8. //fromdataleftintheinputbufferandthecaller
  9. //hasrequestedtoreadthenextdata.
  10. constsize_toutAvail=(!doReceive||needRead)?mOut.dataSize():0;
  11. bwr.write_size=outAvail;
  12. bwr.write_buffer=(longunsignedint)mOut.data();
  13. //Thisiswhatwe'llread.
  14. if(doReceive&&needRead){
  15. bwr.read_size=mIn.dataCapacity();
  16. bwr.read_buffer=(longunsignedint)mIn.data();
  17. }else{
  18. bwr.read_size=0;
  19. }
  20. ......
  21. //Returnimmediatelyifthereisnothingtodo.
  22. if((bwr.write_size==0)&&(bwr.read_size==0))returnNO_ERROR;
  23. bwr.write_consumed=0;
  24. bwr.read_consumed=0;
  25. status_terr;
  26. do{
  27. ......
  28. #ifdefined(HAVE_ANDROID_OS)
  29. if(ioctl(mProcess->mDriverFD,BINDER_WRITE_READ,&bwr)>=0)
  30. err=NO_ERROR;
  31. else
  32. err=-errno;
  33. #else
  34. err=INVALID_OPERATION;
  35. #endif
  36. ......
  37. }
  38. }while(err==-EINTR);
  39. ....
  40. if(err>=NO_ERROR){
  41. if(bwr..write_consumed>0){
  42. if(bwr.write_consumed<(ssize_t)mOut.dataSize())
  43. mOut.remove(0,bwr.write_consumed);
  44. else
  45. mOut.setDataSize(0);
  46. }
  47. if(bwr.read_consumed>0){
  48. mIn.setDataSize(bwr.read_consumed);
  49. mIn.setDataPosition(0);
  50. }
  51. ......
  52. returnNO_ERROR;
  53. }
  54. returnerr;
  55. }
这个函数的具体作用可以参考 Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析 一文,它只要就是通过ioctl文件操作函数来和Binder驱动程序交互的了: [cpp] view plain copy
  1. ioctl(mProcess->mDriverFD,BINDER_WRITE_READ,&bwr)
有了这个线程池之后,我们在开发Android应用程序的时候,当我们要和其它进程中进行通信时,只要定义自己的Binder对象,然后把这个Binder对象的远程接口通过其它途径传给其它进程后,其它进程就可以通过这个Binder对象的远程接口来调用我们的应用程序进程的函数了,它不像我们在C++层实现Binder进程间通信机制的Server时,必须要手动调用IPCThreadState.joinThreadPool函数来进入一个无限循环中与Binder驱动程序交互以便获得Client端的请求,这样就实现了我们在文章开头处说的Android应用程序进程天然地支持Binder进程间通信机制。 细心的读者可能会发现,从Step 1到Step 9,都是在Android应用程序框架层运行的,而从Step 10到Step 15,都是在Android系统运行时库层运行的,这两个层次中的Binder进程间通信机制的接口一个是用Java来实现的,而别一个是用C++来实现的,这两者是如何协作的呢?这就是通过JNI层来实现的了,具体可以参考 Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析 一文。 回到Step 8中的RuntimeInit.zygoteInit函数中,在初始化完成Binder进程间通信机制的基础设施后,它接着就要进入进程的入口函数了。 Step 16.RuntimeInit.invokeStaticMain 这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
        
  1. publicclassZygoteInit{
  2. ......
  3. staticvoidinvokeStaticMain(ClassLoaderloader,
  4. StringclassName,String[]argv)
  5. throwsZygoteInit.MethodAndArgsCaller{
  6. Class<?>cl;
  7. try{
  8. cl=loader.loadClass(className);
  9. }catch(ClassNotFoundExceptionex){
  10. ......
  11. }
  12. Methodm;
  13. try{
  14. m=cl.getMethod("main",newClass[]{String[].class});
  15. }catch(NoSuchMethodExceptionex){
  16. ......
  17. }catch(SecurityExceptionex){
  18. ......
  19. }
  20. intmodifiers=m.getModifiers();
  21. ......
  22. /*
  23. *ThisthrowgetscaughtinZygoteInit.main(),whichresponds
  24. *byinvokingtheexception'srun()method.Thisarrangement
  25. *clearsupallthestackframesthatwererequiredinsetting
  26. *uptheprocess.
  27. */
  28. thrownewZygoteInit.MethodAndArgsCaller(m,argv);
  29. }
  30. ......
  31. }
前面我们说过,这里传进来的参数className字符串值为"android.app.ActivityThread",这里就通ClassLoader.loadClass函数将它加载到进程中: [java] view plain copy
  1. cl=loader.loadClass(className);
然后获得它的静态成员函数main: [java] view plain copy
  1. m=cl.getMethod("main",newClass[]{String[].class});
函数最后并没有直接调用这个静态成员函数main,而是通过抛出一个异常ZygoteInit.MethodAndArgsCaller,然后让ZygoteInit.main函数在捕获这个异常的时候再调用android.app.ActivityThread类的main函数。为什么要这样做呢?注释里面已经讲得很清楚了,它是为了清理堆栈的,这样就会让android.app.ActivityThread类的main函数觉得自己是进程的入口函数,而事实上,在执行android.app.ActivityThread类的main函数之前,已经做了大量的工作了。 我们看看ZygoteInit.main函数在捕获到这个异常的时候做了什么事:
        
  1. publicclassZygoteInit{
  2. ......
  3. publicstaticvoidmain(Stringargv[]){
  4. try{
  5. ......
  6. }catch(MethodAndArgsCallercaller){
  7. caller.run();
  8. }catch(RuntimeExceptionex){
  9. ......
  10. }
  11. }
  12. ......
  13. }
它执行MethodAndArgsCaller的run函数:
        
  1. publicclassZygoteInit{
  2. ......
  3. publicstaticclassMethodAndArgsCallerextendsException
  4. implementsRunnable{
  5. /**methodtocall*/
  6. privatefinalMethodmMethod;
  7. /**argumentarray*/
  8. privatefinalString[]mArgs;
  9. publicMethodAndArgsCaller(Methodmethod,String[]args){
  10. mMethod=method;
  11. mArgs=args;
  12. }
  13. publicvoidrun(){
  14. try{
  15. mMethod.invoke(null,newObject[]{mArgs});
  16. }catch(IllegalAccessExceptionex){
  17. ......
  18. }catch(InvocationTargetExceptionex){
  19. ......
  20. }
  21. }
  22. }
  23. ......
  24. }
这里的成员变量mMethod和mArgs都是在前面构造异常对象时传进来的,这里的mMethod就对应android.app.ActivityThread类的main函数了,于是最后就通过下面语句执行这个函数: [java] view plain copy
  1. mMethod.invoke(null,newObject[]{mArgs});
这样,android.app.ActivityThread类的main函数就被执行了。 Step 17.ActivityThread.main 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
        
  1. publicfinalclassActivityThread{
  2. ......
  3. publicstaticfinalvoidmain(String[]args){
  4. SamplingProfilerIntegration.start();
  5. Process.setArgV0("<pre-initialized>");
  6. Looper.prepareMainLooper();
  7. if(sMainThreadHandler==null){
  8. sMainThreadHandler=newHandler();
  9. }
  10. ActivityThreadthread=newActivityThread();
  11. thread.attach(false);
  12. if(false){
  13. Looper.myLooper().setMessageLogging(new
  14. LogPrinter(Log.DEBUG,"ActivityThread"));
  15. }
  16. Looper.loop();
  17. if(Process.supportsProcesses()){
  18. thrownewRuntimeException("Mainthreadloopunexpectedlyexited");
  19. }
  20. thread.detach();
  21. Stringname=(thread.mInitialApplication!=null)
  22. ?thread.mInitialApplication.getPackageName()
  23. :"<unknown>";
  24. Slog.i(TAG,"Mainthreadof"+name+"isnowexiting");
  25. }
  26. ......
  27. }
从这里我们可以看出,这个函数首先会在进程中创建一个ActivityThread对象: [java] view plain copy
  1. ActivityThreadthread=newActivityThread();
然后进入消息循环中: [java] view plain copy
  1. Looper.loop();
这样,我们以后就可以在这个进程中启动Activity或者Service了。 至此,Android应用程序进程启动过程的源代码就分析完成了,它除了指定新的进程的入口函数是ActivityThread的main函数之外,还为进程内的Binder对象提供了Binder进程间通信机制的基础设施,由此可见,Binder进程间通信机制在Android系统中是何等的重要,而且是无处不在,想进一步学习Android系统的Binder进程间通信机制,请参考 Android进程间通信(IPC)机制Binder简要介绍和学习计划 一文。

更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. 浅析android通过jni控制service服务程序的简易流程
  4. Android(安卓)bluetooth介绍(四): a2dp connect流程分析
  5. Android架构分析之使用自定义硬件抽象层(HAL)模块
  6. 2011年Android(安卓)Camera学习笔记之一
  7. [置顶] Android(安卓)跨进程通信Aidl的使用及注意事项
  8. Android执行shell命令
  9. Android中OpenMax的适配层

随机推荐

  1. 神经拟态技术会与 AI 芯片形成竞争吗?
  2. 红帽高管Stephanos Bacon:基于开源社区协
  3. 换协议、改代码,Elastic 要逼开发者二选一
  4. 软件架构设计原则和模式之分层架构设计
  5. 关于大数据规模化,管理层应思考的战略及团
  6. 关于 Linux中NFS的一些笔记
  7. 意派Epub360丨有了这款H5模板,春节虎头帽
  8. JavaScript 之 Proxy
  9. vue 项目中使用websocket的正确姿势
  10. 详解Java创建线程的五种常见方式