- 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()这个函数如下所示:
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进程接收到Socket消息处理
分析到这边,可以切换到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文章来源:https://www.toymoban.com/news/detail-678717.html
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,但是进程也有优先级文章来源地址https://www.toymoban.com/news/detail-678717.html
到了这里,关于android framework之Applicataion启动流程分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!