多嘴一句 本文件创建于2017-12-01 10:04:40
完成于2018-01-28 19:11:46
哭了
相关知识
在学习整体流程之前先介绍几个和Activity关系比较密切的类。
SystemServer
之前分析的zygote进程的启动流程,最后是启动了app_process
这个进程,那么启动之后是怎么样的呢,贴张老罗的图:
具体源码流程就略过,最后是启动了SystemServer这个进程,main
方法如下:
1 | 167 public static void main(String[] args) { |
- startBootstrapServices() 启动一些重量级服务 如AMS
- startCoreServices() 启动一些核心服务 如电池管理
- startOtherServices() 启动一些有的没的杂七杂八服务
在startOtherServices
中,最后会调用
1 | 1096 mActivityManagerService.systemReady(new Runnable() {...} |
在AMS中又调用startHomeActivityLocked
来启动Launcher组件(桌面)
1 | 11719 public void systemReady(final Runnable goingCallback) { |
至于startHomeActivityLocked
怎么搞的,相信看完这篇文章心里大概就有数了。
ActivityManagerService(AMS)
上面废话说了一堆,还是没说AMS是啥,直译就是Activity管理服务,实际上也是起到这么一个功能。
划重点了,要考的
在Android的跨进程通信中,都有这么一个命名套路。有兴趣的可以看看源码,很容易理清楚。
- xxxNative:一般为抽象类,如ActivityManagerNative,继承自IActivityManager。实现了一些Binder服务端的一些方法,类似于base的功能吧。
- xxxService:如ActivityManagerService,继承自ActivityManagerNative。实现了IActivityManager中声明的所有这个Binder远程服务提供的方法,是远程服务实现类。一些默认实现也会写在AMNative中。
- xxxProxy:如ActivityManagerProxy,为AMNative内部类,通常是外部xxxNative的
getDefault
方法返回值。这个就是AIDL中对应的Proxy类,是远程服务在本地进程的代理,在本地进程我们都是通过xxxNative.getDefault,然后执行某些特定的方法来调用到远程的服务。
这个AMS、AMN、AMP在下面的分析经常会见到,同理ApplicationThreadNative、ApplicationThread(没有Service。。)和ApplicationThreadProxy。
可以参考从ActivityManagerNative看Android系统AIDL的实现
ActivityThread
ActivityThread代表了一个安卓应用的进程。
Android应用的入口是Application的onCreate
吗?no!是ActivityThread的main
,这么一回答,B格是不是就上去了。
再看一下ActivityThread这个类的几个相关的成员变量:
1 | final ApplicationThread mAppThread = new ApplicationThread(); |
主要关注一下ApplicationThread,后续流程AMS会通过ApplicationThreadProxy,来调用ApplicationThread的服务,从而调用到ApplicationThread外部类,ActivityThread的相关方法来达到控制Activity生命周期的功能。
ApplicationThread
1 | 574 private class ApplicationThread extends ApplicationThreadNative {...} |
ActivityStack和ActivityStackSupervisor:
每一个ActivityRecord都会有一个Activity与之对应,一个Activity可能会有多个ActivityRecord,因为Activity可以被多次实例化,取决于其launchmode。一系列相关的ActivityRecord组成了一个TaskRecord,TaskRecord是存在于ActivityStack中,ActivityStackSupervisor是用来管理这些ActivityStack的。
ActivityStack和ActivityRecord的关系如下:
先说个关于ProcessRecord的知识:
在AMS中每个ProcessRecord代表一个应用程序进程,AMS的成员ActivityStackSupervisor(ASS)在startActivityMayWait
中通过caller(IApplicationThread)这个参数,向他的成员mService(指向AMS)调用getRecordForAppLocked
来获取caller对应的ProcessRecord,包含了对应进程的信息pid、uid等。
ActivityRecord TaskRecord ProcessRecord三者关系图
Launcher启动Activity过程概述
Launcher——Activity——Instrumentation——AMP
Launcher逐级调用到Instrumentation,利用ActivityManagerNative.getDefault()
得到ActivityManagerProxy(AMS的Binder代理)并调用其startActivity
方法。
AMP——AMS——ActivityStack
AMP通过Binder来与AMS通信,调用AMS的成员ActivityStackSupervisor(ActivityStackSupervisor内部持有一个ActivityStack)
在ActivityStack中有TaskRecord和ActivityRecord来记录已经启动的Activity的信息
1 | 154 /** |
AMS调用ActivityStack来执行启动Activity操作,先使用PackageManagerService
去解析启动参数Intent中各种信息(判断启动flag啊,获取caller的ProcessRecord进程信息,是否需要新建一个ProcessRecord等等)。之后再根据Intent的信息(newTask)来判断是否要把即将启动的Activity放到上述的ActivityStack成员mTaskHistory的顶部。后续检查一些是否mResumeActivity就是要启动,是否有结束Activity动作发生,关机等等等。都OK的话才会通知当前的Activity-mResumeActivity(如果从桌面启动的话就是Launcher组件)来进入onPaused流程。
ApplicationThreadProxy——ApplicationThread——ActivityThread
接上面的,mResumeActivity的onPaused流程是怎么通知的呢。这样就要说到上述的ActivityRecord的成员app(ProcessRecord)的又一个成员变量thread(ApplicationThreadProxy),看这个类型就知道是干嘛的,Binder。
插入介绍一下AppTP、AppTN、AppT吧。
ApplicationThread是ActivityThread的内部类,继承自AppTN,其实就跟AMS继承AMN以及AMP代理的关系一样。
1 | private class ApplicationThread extends ApplicationThreadNative {...} |
好,继续。AppTP通过Binder通知ApplicationThread处理onPaused,会调用ApplicationThread的外部类ActivityThread的Handler-Message机制来通知ActivityThread,在ActivityThread的处理消息的函数中。
先是让当前的Activity进入onPause
1 | performPauseActivity(token, finished, r.isPreHoneycomb()); |
又通过这么一行代码来通知AMS说我已经让它pause了
1 | ActivityManagerNative.getDefault().activityPaused(token);//ActivityManagerNative.getDefault()=ActivityManagerProxy 详细见下面代码分析 |
艾玛,太高兴了,又回到了ActivityManagerProxy。
AMP——AMS——ActivityStack
通知Stack要进入onPause的mResumeActivity已经被暂停了
ActivityStack——AMS——ActivityThread
mResumeActivity执行完之后,再来启动栈顶Activity。在ActivityStack中检查,PID、UID啥的,是否该Activity所属的进程已经启动了,如果启动了,就通知那个进程来启动Activity,如果没有就以PID和UID新建一个进程,再通知这个新进程启动Activity。
下面假设需要新建ProcessRecord,新建完肯定要保存相应的ProcessRecord到AMS。然后执行ActivityThread的main方法。
ApplicationThread的main方法就是一个App的入口方法
ActivityThread——AMP——AMS——ActivityStack
ActivityThread的main中调用attach,其中通过AMP执行attachApplication,调用到AMS的attachApplication,然后又进入Stack一顿瞎比操作。
跟上面暂停的流程很像,ApplicationThreadProxy通过Binder远程调用ApplicationThread,Handler-Message调用外部类ActivityThread实际函数performLaunchActivity
,在调用mInstrumention.callActivityOnCreate
Activity的启动
以下是无脑跟源码过程,可略!
从Activity的startActivity方法开始一步步跟进,走读Activity的启动流程,子标题为相关类的递进
Activity->Instrumentation->ActivityManagerProxy
一步步跟进Activity的startActivity
方法,最后都是调用的startActivityForResult
1 | 3927 public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) { |
实际上是调用的mInstrumentation.execStartActivity
,跟进
1 | 1604 public ActivityResult execStartActivity( |
注意这里的whoThread
参数,IApplicationThread的实例,在后续会说明
实际上是在try
块中调用ActivityManagerNative.getDefault().startActivity
,那么ActivityManagerNative.getDefault()
是啥捏,去ActivityManagerNative(AMN)里头看看
1 | 2604 private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { |
就是一个单例的IActivityManager IActivityManager是一个继承IInterface的接口,可以基本确定是负责Binder通信的了,内部的方法都和Activity的生命周期相关。
1 | public interface IActivityManager extends IInterface { |
那么上面gDefault中返回的am
到底是那个实现类呢,跟进IActivityManager am = asInterface(b)
1 | 67 static public IActivityManager asInterface(IBinder obj) { |
所以ActivityManagerNative.getDefault()
返回的是ActivityManagerProxy
,是ActivityManagerNative的一个内部类,他俩都实现了IActivityManager这个接口,重点关注一下构造方法,传入的是一个 IBinder 实例
1 | public ActivityManagerProxy(IBinder remote) |
跟进查看
startActivity`方法
1 | 2631 public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, |
很明了,使用mRemote
成员进行Binder通信,通信码START_ACTIVITY_TRANSACTION
。
往上回溯,这个mRemote就是ServiceManager.getService("activity")
的返回值,那么这个的返回值是啥捏
是ActivityManagerService
,让我们进入 ActivityManagerService的代码来找证据
1 | 2172 public void setSystemProcess() { |
Context.java中定义了ACTIVITY_SERVICE=activity
public static final String ACTIVITY_SERVICE = "activity"
ActivityManagerService又把自己注册为activity
这个服务,所以ServiceManager.getService("activity")
的返回值就是ActivityManagerService。所以我们就进入ActivityManagerService
分析一波。
ActivityManagerService->ActivityStackSupervisor
我们是通过mRmote向AMS进行IPC通信,根据Binder的实现原理,会调用到AMS的onTransact
方法
1 | 2452 |
实际上只响应SYSPROPS_TRANSACTION请求码,其他的通过super
调用AMS的父类,ActivityManagerNative来处理,那么查看一下ActivityManagerNative的onTransact
中对应code为START_ACTIVITY_TRANSACTION
的方法块吧
1 | 146 case START_ACTIVITY_TRANSACTION: |
烦不烦啊,怎么又调用startActivity
,但是注意了啊,这个startActivity
是AMS中的,而不是上面的ActivityManagerNative中的方法。
1 | 3848 |
冲啊,跟进代码mStackSupervisor.startActivityMayWait
1 | final int startActivityMayWait(IApplicationThread caller, int callingUid, |
代码太长 删减了许多,有兴趣的自己看源码去,跟进res = startActivityLocked
1 | final int startActivityLocked(IApplicationThread caller, |
代码量实在太多了,对一些信息的封装和检测啥的,真不大懂,无脑跟进,gostartActivityUncheckedLocked
1 | final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord, |
一堆的标记位Flag检测,来判断启动行为,看不懂,放弃,gostartActivityLocked
1 |
|
代码都是多的要死,在startActivityLocked内部主要就是把Activity放到Activity组件堆栈中,然后在激活栈顶的Activity来达到启动Activity的目的。
然后startActivityUncheckedLocked
-> ActivityStack.resumeTopActivityLocked
来通知Activity栈最上层不为Finish态的Activity进入Paused状态->resumeTopActivityInnerLocked
->startPausingLocked
来设置ActivityRecord状态和调用ApplicationThreadProxy的schedulePauseActivity
方法
#ApplicationThreadProxy->ApplicationThread->ActivityThread
ApplicationThreadProxy是ApplicationThreadNative的内部类
1 | public abstract class ApplicationThreadNative extends Binder |
跟之前说的ActivityManagerNative和ActivityManagerProxy异曲同工,ApplicationThreadProxy发送的transact会在ActivityManagerNative的子类ApplicationThreadonTransact
方法处理,ApplicationThread是ActivityThread的内部类,同时也没有覆盖onTransact
方法。
1 | // ApplicationThreadProxy.class |
跟进ActivityThread成员函数sendMessage
1 | 2265 private void sendMessage(int what, Object obj, int arg1, int arg2) { |
这就是handler-message机制了,注意这个what字段值为PAUSE_ACTIVITY,跟进handleMessage
方法!!!
1 | 1353 case PAUSE_ACTIVITY: |
1 | 3305 private void handlePauseActivity(IBinder token, boolean finished, |
之前说过了ActivityManagerNative.getDefault()=ActivityManagerProxy,所以就跟进
1 | 3134 public void activityPaused(IBinder token) throws RemoteException |
又是一个Binder通信过程,所以看AMS的onTransact
中code=ACTIVITY_PAUSED_TRANSACTION的代码,实际上在AMS父类AMNative中
1 | 536 case ACTIVITY_PAUSED_TRANSACTION: { |
又调用了AMS的activityPaused
方法,跟进,擦
1 | 6497 |
ActivityStack的activityPausedLocked
1 | 928 final void activityPausedLocked(IBinder token, boolean timeout) { |
completePauseLocked
->StackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
1 | 2727 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, |
ActivityStack.resumeTopActivityLocked
->resumeTopActivityInnerLocked
->StackSupervisor.startspecificactivitylocked
1 | 1365 void startSpecificActivityLocked(ActivityRecord r, |
AMS.startProcessLocked会启动r.processName=ActivityThread这个进程,则会执行ActivityThread.main方法
ActivityThread->
1 | 5379 public static void main(String[] args) { |
attachApplication
,还是一个套路,AMProxy通过Binder发送,AMS来响应的套路,这次的code码为ATTACH_APPLICATION_TRANSACTION
1 | //AMProxy |
AMS.attachApplicationLocked 又调用了Stack.realStartActivityLocked -> ApplicationThreadProxy.scheduleLaunchActivity->ApplicationThread.scheduleLaunchActivity->ActivityThread.sendMessage->H.handleMessage->handleLaunchActivity->ActivityThread.handleLaunchActivity->performLaunchActivity->mInstrumentation.callActivityOnCreate