您的位置:首页 > 其它

Activity启动流程(源码分析)

2017-03-20 12:12 267 查看
activity作为android四大组件之一,也是android app中最为重要的一个部分,很多时候我们开启一个activity 只需调用startActivity即可,却不知背后系统为我们做了哪些事。而这个流程可以说相当复杂,其中进行了多次进程间通信,下面我们来分析一下。



1,首先在actvity中调用startActivity(Intent intent); Intent作为意图对象,就相当于一个路由地址一样,我们要选择哪个activity,向这个activity传递什么样的数据,都是通过Intent来决定的。

2,在activity源码中,我们发现startActivity 紧接着调用的是startActivityForResult(),在startActivityForResult中,又通过Instrumentation,它只是一个单纯的类,并且它是activity的直接操作者,activity的生命周期都是通过Instrumentation这个类来处理的,但他并不是控制者.

3,Instrumentation调用execStartActivity,这个方法还未跨进程调用,而在方法中获取到一个服务类(ActivityManagerNative.getDefault(),这个服务类是怎么拿到的呢?其实在我们app运行时这个服务类已经被装进ActivityManagerNative里了,它是一个静态类,从代码中可以看到ServiceManager.getService("activity"),其实这个服务类就是在整个android系统中至关重要的ActivityManagerService(AMS),而AMS本身就是一个binder接口,所以我们拿到的是一个AMS的分身,我们通过AMS分身调用startActivity(),至于为什么是分身,那就是AIDL原理的知识了.

4.我们通过Ams调用startActivity,走到这里其实已经是在跨进程通信了,Ams是运行在systemServer进程中的,而我们app中startActivity是运行在我们应用程序进程中的,所以ams调用startActivity后,就进入了Ams这个类,ams类调用startActivity()->startActivityAsUser()然后又交给了(ASP) mStackSupervisor.startActivityMayWait();

5.ActivityStackSupervisor(ASP)是个什么东西?通过源码获知,它管理了整个activity的任务栈,android中会有不同app,不同app默认又运行在不同的栈中,为什么由它来管理呢?如果我们app本身就能管理栈,那不同栈之间岂不是要互相通信,很显然app之间通信会造成不安全,所以ams通过mStackSupervisor来管理所有app的任务栈,app没有管理的权限。 紧接着我们调用ASP的startActivityMayWait(),这里边就是根据Intent去找出相对应的activity信息.

6.ASP去拿到PageManagerService的binder分身去解析Intent,得到符合条件的Acticitys,pms与ams同属systemServer进程, 在这里还是透过binder通信,说明binder在android中无处不在。接着ASP调用startActivityLocked(),在这个方法中进行了Intent验证,权限的检测等,然后调用startActivityUncheckedLocked(),这个方法检测activity启动模式,根据启动模式分配或者创建任务栈ActivityStack,而这个ActivityStack即Activity的直接管理对象,接着通过ActivityStack调用startActivityLocked();

7.ActivityStack调用startActivityLocked其实这个方法里并没有找到开启新activity的代码,而是去查找要要pause掉的activity,通过函数resumeTopActivityLocked(),然后调用startPausingLocked方法

8.startPausingLocked调用ApplicationThread(它也是一个binder分身)拿到要pause的那个activity所在进程ApplicationThread执行shedulePauseActivity()方法,又是一轮跨进程通信。而ApplicationThread是ActivityThread的内部类,ApplicationThread向消息队列里发了条消息.ActivityThread收到后调用自身的handlePauseActivity方法

9.接着handlePauseActivity方法中除了管理那个被pause的Activity的同时又与ams做了一个跨进程通信来告诉ams我已经pause了,所以调用ams的ActivityPaused方法

10.ams收到activity被pause的消息,然后调用activityStack的activityPauseLocked方法,然后有ASP去执行了resumeTopActivitiesLocked();

11.Asp在resumeTopActivitiesLocked方法中去判断app进程是不是已经存在了,如果不存在他就与另一个进程通信,那就是孵化器进程,而与孵化器进程通信的方式并不是采用binder方式,而是直接用socket通信,让其复制一个进程出来,调用startProccessLocked()

12.在app进程已经存在的情况下则调用startSecificActivityLocked()方法紧接着又是跨进程通知app进程执行scheduleLaunchActivity->交由Instrumentation创建activity并执行onCreate函数.

总结:以上我们看到一个activity启动流程如此复杂,但是分析源码还是能摸清套路的,这种架构就是典型的C/S架构,我们所看到的activity只是最浅显的东西,而其实activity的真身并不在我们app内,而是由AMS直接管理并操控着,所以google没有给app开发人员任何控制点,里边环环相扣,形成一张巨网。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: