本文借鉴自两位大神的原创:https://blog.csdn.net/singwhatiwanna/article/details/18154335
https://blog.csdn.net/qq_23547831/article/details/51224992
这两篇启动流程的总结,个人认为是很有代表性的两个极端总结,第一篇相对简短,只介绍了核心流程,大概五六分钟就能看完;第二篇十分详细,详细到连新进程的启动流程都涉及到了,看完大概需要半个小时甚至更长时间。
首先最好了解一下启动过程中比较重要的几个类,要知道它们的功能作用。
1.Instrumentation
Instrumentation是android系统中启动Activity的一个实际操作类,Activity的onCreate、onStart、onResume等都是由它调用;
2.ActivityThread
启动Activity的核心功能由其内部的scheduleLaunchActivity方法来完成。
3.ActivityManagerService(AMS)
四大组件的大管家,统一调度各应用进程。
Activity的启动分两种,一种是startActivity(intent),另一种是Launcher启动,也就是点击桌面上的图标。
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<!--这个LAUNCHER过滤条件就决定了该Activity是由桌面点击图标启动的-->
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
整体、大致流程
- startActivity方法最终会调用startActivityForResult方法,接着又调用的Instrumentation的execStartActivity方法通知AMS启动下一个Activity;
- AMS记录要启动的Activity信息,并且通知前一个Activity进入pause状态。
- 前一个Activity进入pause状态后,通知AMS已经paused了,可以启动下一个了。
- 如果被启动的Activity的进程不存在,也就是Launcher启动,所以AMS启动新的进程,并且在新进程中创建ActivityThread对象,执行其中的main函数方法。
- 被启动的Activity主线程启动完毕后通知AMS,并传入ApplicationThread以便通讯。
- 被启动的Activity启动后创建和关联Context,最后调用onCreate方法。
Launcher启动只能是隐式的启动,因为Launcher启动Activity会开启一个新的进程,这个进程与Launcher不在同一个进程,所以就无法引用到启动的Activity的字节码(.class),也就无法启动这个Activity。
首先我们要知道Acitivty的启动分为应用进程端的启动和SystemServer服务进程端的启动
应用进程端的启动
1.startActivity()最终调用的是startActivityForResult()
这个方法内部有个mParent的空判断,这个mParent是个ActivityGroup,在Activity嵌套Activity的情况下才不为空,
但这个已经在API13的时候就废弃掉了,改用了Fragment。所以我们只管mParent为空的条件下的逻辑即可。
2.startActivityForResult()内部接着调用了Instrumentation的execStartActivity()
这个方法的第二个参数是mMainThread.getApplicationThread(),核心功能都在这个ApplicationThread中完成;
3.接着又调用ActivityManagerNative.getDefault().startActivity()
第一个参数whoThread是IApplicationThread的实例,它的实现类是ApplicationThread,
启动Activity的核心功能由其内部的scheduleLaunchActivity方法来完成;
它们的关系是:ApplicationThread继承了ApplicationThreadNative,ApplicationThreadNative又继承了Binder,
并实现了IApplicationThread接口。所以ApplicationThread也是Binder的实现类。
这里的ActivityManagerNative是ActivityManagerService在应用进程的一个client(涉及到Binder机制),通过它可以调用 ActivityManagerService的方法。
ActivityManagerNative.getDefault().startActivity();最终会调用ActivityManagerService的startActivity,
此时便进入SystemServer服务进程端的启动
SystemServer服务进程端的启动
系统服务端启动流程调用的方法特别多,大概的流程就是:
先对栈顶Activity执行onPause方法,而这个方法首先判断需要启动的Activity所属的进程是否已经启动,若已经启动则直接调用启动Activity的方法,否则将先启动Activity的应用进程,然后在启动该Activity。
我们主要看几个关键的方法:
1.ActivityStack.startPausingLocked()
执行栈顶Activity的onPause方法,其内部调用了prev.app.thread.schedulePauseActivity();这个prev.app.thread是IAppicationThread类型的对象;实际上这里是通过Binder机制调用ActivityThread中的ApplicationThread的schedulePauseActivity方法;
2.ActivityManagerNative.getDefault().activityPaused(token)
逻辑跟上面的ActivityManagerNative.getDefault().startActivity()一样:ActivityManagerNative作为Binder Client ,AMS作为Binder server,只不过这里是通知AMS上一个Activity已经pause了,可以启动下一个Activity了。这句话最终会调用ActivityManagerService的activityPaused方法;
3.ActivityStack.startSpecificActivityLocked()
这个方法首先会判断一下需要启动的Activity所需要的应用进程是否已经启动,若启动的话,则直接调用realStartAtivityLocked方法,否则调用startProcessLocked方法,用于启动应用进程。
启动新进程时调用了Zygote并通过socket通信的方式让Zygote进程fork出了一个新的进程,并根据我们刚刚传递的”android.app.ActivityThread”字符串,反射出该对象并执行ActivityThread的main方法。这样我们所要启动的应用进程这时候其实已经启动了,但是还没有执行相应的初始化操作。
其实,前一个Activity执行pause的过程中,也涉及到Binder机制,上面我们提到:ActivityManagerNative作为Binder Client调用ActivityManagerService也就是Binder server实现了应用进程与SystemServer进程的通讯;而此时IAppicationThread作为Binder Client调用ActivityThread中的ApplicationThread。也就是Binder server实现了SystemServer进程与应用进程的通讯。
经过一系列的方法调用,最终执行到ActivityThread的scheduleLauncherActivity方法,在这个方法内部构造了一个Activity记录——ActivityClientRecord,此时,启动流程又从SystemServer服务进程端再次回到了应用进程端。
大致流程
ActivityThread接收到SystemServer进程的消息之后会通过其内部的Handler对象分发消息,经过一系列的分发之后调用了ActivityThread的handleLaunchActivity方法,接着又调用了performLauncherActivity方法,这个方法最终返回了一个Activity,也就是说我们需要的Activity对象终于创建出来了,而且是以反射的机制创建的。
具体流程
1.IApplicationThread.scheduleLauncherActivity()
其实这里真正执行的是ActivityThread中的scheduleLauncherActivity(),在这个方法内部构造了一个Activity记录——ActivityClientRecord;
2.ActivityThread.sendMessage()
ActivityThread通过其内部的Handler对象分发消息
3.ActivityThread.handleLauncherActivity()
4.ActivityThread.performLauncherActivity()
这个方法真正构造了一个Activity
performLauncherActivity内部调用了mInstrumentation.newActivity(),用ClassLoader(类加载器)将目标activity的类通过类名加载进来并调用newInstance来实例化一个对象,其实就是通过Activity的无参构造方法来new一个对象,对象就是在这里new出来的。然后调用Instrumentation的callActivityOnCreate方法,最终执行activity的performCreate方法,目标activity的onCreate就被调用了,到此为止,Activity被启动了,接下来的流程就是Activity的生命周期了。