赞
踩
启动方式一:通过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方法。
现在来分析App进程的启动流程,这边分两块,一个是Application的启动流程,一个是Activity的启动,Application的启动是通过Zygote fork()创建启动的,所以它的启动只有一次,但是Activity的启动可以是多次,而且有不同的启动方式,比如通过Launcher启动,通过进程内的ActivityA->AcitityB,或由其它另外一个进程来启动这个进程的Activity,等等。因此我们这边分析的是最全的覆盖最大的Activity启动方法,其它启动方式基本类似,按此作为参考。
Application进程的启动:
进程的启动来自AMS或ATMS代码,由它们触发,但是先抛开Activity前面的启动代码,所以我们从上图中右边的第2步开始进行源码分析,如上图所示Application进程的启动流程是由ATMS发起,在启动activity过程中会经历一个类ActivityStackSupervisor.java,在这个类中会真正的去启动activity, 会先进入startSpecialActivity()这个函数如下所示:
- ActivityStackSupervisor.java->startSpecialActivity():
- -->//这里面会进行app进程存在与否的判断
- if(wpc != null && wpc.hasThread() )
- //进程存在时,直接启动activity
- -->realStartActivityLocked(); //这个与文章中最前面那张图就对上了。
- ...
- //下面是进程不存在时,需要创建。
- //mService是ActivityTaskServiceManager.java对象
- mService.startProcessAsync();//为app启动一个进程。
- //ActivityManagerInternal是AMS里的一个内部类:它内部包含了AMS的绝大多数服务的函数
- -->Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,...);
- mH.sendMessage(m);
-
-
- 这边过一下ActivityManagerInternal::startProcess这个函数:
- -->它是用于启动进程的,启动进程是通过socket,向zygote发送启动进程所需要的一些关键参数,
- startProcessLocked();
- //app进程相关的核心类有两个:一个是ProcessRecord类,一个是ProcessList进程的核心类,
- //在下面进一步描述:AMS通过持有进程的ProcessList列表,通过它来管理(start)进程
- -->mProcessList.startProcessLocked();
- -->判断处理进程启动前的各种参数和内容
- ...
- ProcessList.java->startProcessLocked();
- -->ProcessList.java->startProcessLocked(app, ApplicationInfo,);//重载的另一个函数
- -->ProcessList.java->startProcessLocked();//又是重载 的另一个函数,中间会经历很多个重载的函数
- ->...
- final Process.ProcessStartResult startResult = startProcess();
- -->if(usesWebviewZygote())
- startWebView();
- else if(usesAppZygote())
- appZygote.getProcess().start(); //隔离进程的启动
- else
- //Process:只是一个工具类(很多静态函数),协助ProcessList或ProcessRecord去管理进程
- return Process.start(); //正常app的启动。
- //ZYGOTE_PROCESS是ZygoteProcess类对象,也是工具类帮助zygote启动app进程
- -->return ZYGOTE_PROCESS.start(); //还是属于SystemServer进程
- -->ZygoteProcess.java:startViaZygote();
- -->//封装一系列参数
- ....
- argsForZygote.add(添加参数)
- zygoteSendArgsAndGetResult();
- -->attempZygoteSendArgsAndGetResult();
- -->BufferedWriter usapWriter = new BufferedWrite();
- usapWrite.write(msgStr);
- usapWrite.flush();//通过socket发给zygote.zygote进程可以接收到并执行。
分析到这边,可以切换到zygote进程代码,继续分析,大致看一下Zygote进程是如何接收与处理消息的,代码如下:
- ZygoteInit.main():
- -->...
- runSelectLoop();
- -->while(true) //死循环
- -->Zygoteconnection connection = peers.get();
- Runnable command = connection.processOneCommand();//进行进程的处理,创建新进程
- -->args = Zygote.readArgumentList(mSocketReader);//获取socket命令参数
- ZygoteArguments parsedArgs = new ZygoteArguments();
- ...各种参数解析中...
- pid = zygote.forkAndSpecialize();//Fork子进程,得到一个新的pid.
- -->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
- lass ProcessList{
- ...
- private final int[] mOomAdj = new int[]{ //这里边存放着进程配置的相关优先级
- ...
- }
-
- ...
- //正在运行的应用ProcessRecord数组,根据最近使用的方式进行排序
- final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
- //正在运行的isolated(隔离的)进程
- final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
- }
所以AMS通过ProcessList来持有系统上运行的所有app的ProcessRecord,但是进程也有优先级
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。