• android framework之Applicataion启动流程分析(二)


    上一篇讲了Zygote是如何收到启动Application的启动消息,并一步步进入Fork(),下面来分析zygote fork启动application后,application进程后续处理操作,是如何真正的启动的。

    1. ZygoteInit.main():
    2. -->...
    3. caller = ZygoteServer.runSelectLoop();
    4. -->while(true) //死循环
    5. -->Zygoteconnection connection = peers.get();
    6. Runnable command = connection.processOneCommand();//进行进程的处理,创建新进程
    7. -->args = Zygote.readArgumentList(mSocketReader);//获取socket命令参数
    8. ZygoteArguments parsedArgs = new ZygoteArguments();
    9. ...各种参数解析中...
    10. pid = zygote.forkAndSpecialize();//Fork子进程,得到一个新的pid.
    11. -->pid = nativeForkAndSpecialize(); //调用native层接口去fork
    12. if(pid == 0){ //子进程
    13. }
    14. return pid;
    15. if(pid == 0) //子进程:Application进程
    16. {
    17. //关闭Zygote服务Socket:因为fork时复制出来的socket,对Application进程来说,它没有用。
    18. zygoteServer.closeServerSocket();
    19. //application进程可以正常运行了。
    20. return handleProcessChild();
    21. -->ZygoteConnection.java:
    22. ZygoteInit.zygoteInit(parseArgs.xxx); //app进程的启动
    23. -->ZygoteInit.java:
    24. RuntimeInit.commonInit(); //初始化运行环境
    25. ZygoteInit.nativeZygoteInit();//启动Binder, 并在androidRuntime.cpp中注册
    26. -->com_android_internal_os_ZygoetInit_ativeZygoteInit():
    27. -->gCurRuntime->onZygoteInit(); //通过JNI进入Native
    28. -->//进入app_main.cpp.onZygoteInit();
    29. //下面ProcessState对应Application这个进程实例,里面会初始化Binder
    30. -->sp<ProcessState> proc = ProcessState::self();
    31. -->在C++构造函数初始化列表中:mDriverFD(open_driver(driver))
    32. //这里总结下,Application被Zygote Fork出来之后,进入到Native层处理的目的是为了构建Binder.
    33. //因为后续的跨进程通信,都需要借助Binder.后续将此Binder发给AMS,AMS拿到App的IBinder,才能
    34. //够通过AMS的服务来与APP通信。
    35. proc->startThreadPool(); //启动Binder线程池
    36. //里面通过反射创建程序入口函数的Method对象,并返回Runnable对象
    37. return RuntimeInit.applicationInit();
    38. //类名字,类参数,加载器
    39. -->return findStaticMain(args.startClass, args.startArgs,classLoader);
    40. //通过反射拿到对应类的main方法的Method对象:找到的就是ActivityThread.java.main();
    41. -->m = cl.getMethod("main",new class[]{string[].class});
    42. return 近回一个Runnable 对象。
    43. }else{ //zygote 进程
    44. }
    45. ...
    46. //Runnable对象返回到这里,对应上面代码中的Runnable command = connection.processOneCommand();后面
    47. //继续接着返回,最后返回到上面代码的caller = ZygoteServer.runSelectLoop();
    48. if(caller != null)
    49. caller.run(); //执行返回的Runnable对象,进入子进程。
    50. -->RuntimeInit.java.MethodAndArgsCaller->run();
    51. -->mMethod.invoke();//java反射原理。(执行的是ActivityThread.java的main())

    分析时需要注意的是,底层调用linux fork()接口之后,会有两个返回值,如果pid =0,表示返回的是子进程,如果pid >0,返回的是父进程(即zygote的程序运行路线),父进程(zygote进程)可以得知子进程的pid号。

    补充一个要点:ApplicationThread是什么?它其实是一个IApplicationThread.Stub对象,通过IBinder对象进行跨进程通信访问时,ApplicationThread本质就是Binder线程池中的一个线程(关联到上面代码中的proc->startThreadPool() )

  • 相关阅读:
    MySQL InnoDB存储引擎的优点有哪些?
    【023】Springboot+vue+mysql员工考勤管理系统(多角色登录、请假、打卡)(含源码、数据库、运行教程)
    java springboot在测试类中构建虚拟MVC环境并发送请求
    Linux多线程(线程池与单例模式)
    Jwt的基础入门,详细讲解
    tez作业运行慢
    【C++深入浅出】类和对象下篇
    【目标检测】SPP-Net中候选区域在原图和feature map之间的映射关系
    NAACL 2022 | TAMT:通过下游任务无关掩码训练搜索可迁移的BERT子网络
    前端开发重装系统,软件安装清单
  • 原文地址:https://blog.csdn.net/ab198604/article/details/132596012