当前位置:   article > 正文

android framework之Applicataion启动流程分析_安卓 application启动

安卓 application启动

  • Application启动流程框架分析

启动方式一:通过Launcher启动app
启动方式二:在某一个app里启动第二个app的Activity.
以上两种方式均可触发app进程的启动。但无论哪种方式,最终通过通过调用AMS的startActivity()来启动application的。
  

根据上图分析, 要启动一个Application,需要涉及五个进程,Launcher进程,SystemServer进程,Zygote进程,和要启动的目标Application进程,最后还有一个ServiceManager进程。通过Launcher进程是无法直接启动app的,因为启动是通过AMS或ATMS完成的。

所以第一步,Launcher必须要拿到AMS的Binder,而AMS的Binder(如上图左侧)在Launcher中的代理则是ActivityManagerProxy,它是Launcher从ServiceManager中查询获取而得到的,然后基于这个代理,向SystemServer进程中的AMS去请求startActivity().


这个过程是通过ActivityManagerProxy这个Binder远程调用了AMS的服务,让AMS去startActivity. 但是AMS在启动之前肯定要先判断一下这个Activity对应的Application进程是否已经存在。如果进程存在, 直接走上面的第五步,这一步的处理过程也是跨进程通信的,通过获取APP进程在AMS中的客户端代理即ApplicationThreadProxy, 通过这个代理Binder远程调用app进程的scheduleLauncherActivity()方法直接启动进程中的Activity,这个流程是基于APP进程已经存在了,所以走的是第5和6步分支。

但是现在要讨论的是APP进程不存在的时候,这个APP的启动流程,这种启动方式会覆盖所有app的启动流程。所以AMS当发现进程不存在时,它首先会走第2步,向Zygote进程发送创建进程的请求,这一步采用的是socket通信方式来操作的,zygote收到socket指令后,是通过调用fork()的方式来启动复制创建一个application进程的,这个就是第三步。一旦这个Application被创建,它不会立刻运行,因为它是由AMS来负责的,所以它会先将自身的Binder代理对象发给AMS,这个是第四步,它是利用ActivityManager在Application的Binder对象ActivityManagerProxy来远程调用其attach_application()方法来传递自身Binder。这样AMS也就保存了这个Application的Binder对象,
然后才是走第5步,在第5步中如上面的分析(app进程已经存在的情况下),利用Application在AMS的Binder代理即ApplicationThreadProxy进行启动,最后执行到第8步,调用Activity.onCreate方法。

  • Application进程启动流程代码分析

 现在来分析App进程的启动流程,这边分两块,一个是Application的启动流程,一个是Activity的启动,Application的启动是通过Zygote fork()创建启动的,所以它的启动只有一次,但是Activity的启动可以是多次,而且有不同的启动方式,比如通过Launcher启动,通过进程内的ActivityA->AcitityB,或由其它另外一个进程来启动这个进程的Activity,等等。因此我们这边分析的是最全的覆盖最大的Activity启动方法,其它启动方式基本类似,按此作为参考。

Application进程的启动:

进程的启动来自AMS或ATMS代码,由它们触发,但是先抛开Activity前面的启动代码,所以我们从上图中右边的第2步开始进行源码分析,如上图所示Application进程的启动流程是由ATMS发起,在启动activity过程中会经历一个类ActivityStackSupervisor.java,在这个类中会真正的去启动activity, 会先进入startSpecialActivity()这个函数如下所示:

  1. ActivityStackSupervisor.java->startSpecialActivity():
  2. -->//这里面会进行app进程存在与否的判断
  3. if(wpc != null && wpc.hasThread() )
  4. //进程存在时,直接启动activity
  5. -->realStartActivityLocked(); //这个与文章中最前面那张图就对上了。
  6. ...
  7. //下面是进程不存在时,需要创建。
  8. //mService是ActivityTaskServiceManager.java对象
  9. mService.startProcessAsync();//为app启动一个进程。
  10. //ActivityManagerInternal是AMS里的一个内部类:它内部包含了AMS的绝大多数服务的函数
  11. -->Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,...);
  12. mH.sendMessage(m);
  13. 这边过一下ActivityManagerInternal::startProcess这个函数:
  14. -->它是用于启动进程的,启动进程是通过socket,向zygote发送启动进程所需要的一些关键参数,
  15. startProcessLocked();
  16. //app进程相关的核心类有两个:一个是ProcessRecord类,一个是ProcessList进程的核心类,
  17. //在下面进一步描述:AMS通过持有进程的ProcessList列表,通过它来管理(start)进程
  18. -->mProcessList.startProcessLocked();
  19. -->判断处理进程启动前的各种参数和内容
  20. ...
  21. ProcessList.java->startProcessLocked();
  22. -->ProcessList.java->startProcessLocked(app, ApplicationInfo,);//重载的另一个函数
  23. -->ProcessList.java->startProcessLocked();//又是重载 的另一个函数,中间会经历很多个重载的函数
  24. ->...
  25. final Process.ProcessStartResult startResult = startProcess();
  26. -->if(usesWebviewZygote())
  27. startWebView();
  28. else if(usesAppZygote())
  29. appZygote.getProcess().start(); //隔离进程的启动
  30. else
  31. //Process:只是一个工具类(很多静态函数),协助ProcessList或ProcessRecord去管理进程
  32. return Process.start(); //正常app的启动。
  33. //ZYGOTE_PROCESS是ZygoteProcess类对象,也是工具类帮助zygote启动app进程
  34. -->return ZYGOTE_PROCESS.start(); //还是属于SystemServer进程
  35. -->ZygoteProcess.java:startViaZygote();
  36. -->//封装一系列参数
  37. ....
  38. argsForZygote.add(添加参数)
  39. zygoteSendArgsAndGetResult();
  40. -->attempZygoteSendArgsAndGetResult();
  41. -->BufferedWriter usapWriter = new BufferedWrite();
  42. usapWrite.write(msgStr);
  43. usapWrite.flush();//通过socket发给zygote.zygote进程可以接收到并执行。
  • Zygote进程接收到Socket消息处理

分析到这边,可以切换到zygote进程代码,继续分析,大致看一下Zygote进程是如何接收与处理消息的,代码如下:

  1. ZygoteInit.main():
  2. -->...
  3. 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. -->nativeForkAndSpecialize(); //调用native层接口去fork
  • 关于两个重要的数据结构

(1)ProcessRecord数据结构(代表进程运行的各类属性参数):

rocessRecord数据结构(代表进程运行的各类属性参数):
第一类数据:描述身份的数据,描述进程在AMS中的一个存在形式。
内部包括ApplicationInfo, 进程uid, userId, ProcessName, pid,
IApplicationThread(APP存放在AMS中的客户端IBinder对象)等等信息。
IApplicationThread很重要,AMS通过它给apk进程发送异步消息(管理四大组件的消息),
只有这个对象不为空时,才代码apk进程可以使用。

第二类数据:描述进程状态的数据
第三类数据:内存及和运行耗时,CPU时长,交互时长等相关的数据
第四类数据:crash和anr相关的数据。
所以它包含了APP进程的所有信息,通过它可以全方位监控并记录app的运行情况 。

上面说的ProcessRecord是代表着一个进程的所有数据信息,那AMS需要管理系统运行的所有
APP的进程,尤其是正在运行的app进程,这就需要使用一个List容器来进行管理 ,这个数据结构就是ProcessList类,

(2)ProcessList

  1. lass ProcessList{
  2. ...
  3. private final int[] mOomAdj = new int[]{ //这里边存放着进程配置的相关优先级
  4. ...
  5. }
  6. ...
  7. //正在运行的应用ProcessRecord数组,根据最近使用的方式进行排序
  8. final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
  9. //正在运行的isolated(隔离的)进程
  10. final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
  11. }

所以AMS通过ProcessList来持有系统上运行的所有app的ProcessRecord,但是进程也有优先级

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/589761
推荐阅读
相关标签
  

闽ICP备14008679号