上一篇文章讲了应用进程请求AMS启动Activity过程和Activity在AMS中的启动过程,而后Activity启动的代码逻辑就从AMS所在进程,又从新回到了应用进程所在的ApplicationThread中。咱们还留下了一个问题,Activity的生命周期方法是如何被回调的?,下面咱们就带着这个疑问,去走一遍源码,看一下在应用进程中ApplicationThread启动Activity的过程。java
本文基于android8.0,本文相关源码文件位置以下:
frameworks/base/core/java/android/app/Activity.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/Instrumentation.java
复制代码
上文结尾讲到在ActivityStackSupervisor的realStartActivityLocked()中调用了ApplicationThread中的scheduleLaunchActivity方法,这里是Activity启动的开始。ApplicationThread是ActivityThread的内部类,实现了IApplicationThread.stub接口。ActivityThread表明应用程序进程的主线程,它管理着当前应用程序进程的线程。android
咱们来看一下scheduleLaunchActivity的相关源码:git
//ActivityThread::ApplicationThread
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
复制代码
上述方法中只是简单的把从AMS传过来的有关启动Activity的参数,封装成ActivityClientRecord,而后调用sendMessage向H发送LAUNCH_ACTIVITY的消息,而且将ActivityClientRecord做为参数传了过去,H是ActivityThread中的内部类,是Handler类型,有关Activity的启动消息都交给这个Handler处理,为何这里要进行切换到主线程处理消息呢?由于此时这里还运行在Binder的线程池中,不能进行Activity的启动,因此要切换到主线程中才能进行Activity的生命周期的方法回调。github
下面咱们来看看sendMessage方法。缓存
该方法以下:app
//ActivityThread::ApplicationThread
private void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
//...
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
复制代码
能够看到,sendMessage方法中将H.LAUNCH_ACTIVITY与ActivityClientRecord封装成一个Message,而后调用mH的sendMessage方法,mH就是H的实例,以下:async
final H mH = new H();
复制代码
熟悉android消息机制的都知道(不了解的,能够看这一篇文章Android消息机制java层),Handler发送消息后,都会统一到handlerMessage方法中处理。ide
咱们来看一下Handler H对消息的处理。函数
以下:源码分析
//ActivityThread.java
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public static final int PAUSE_ACTIVITY = 101;
public static final int RESUME_ACTIVITY = 107;
public static final int DESTROY_ACTIVITY = 109;
public static final int BIND_APPLICATION = 110;
//...
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
}
break;
//...
}
}
}
复制代码
H中有不少关于四大组件的消息处理的字段,如Activity的启动,这里咱们只关心前面发送过来的LAUNCH_ACTIVITY字段的消息处理,能够看到这里首先把msg中的obj字段转换为ActivityClientRecord,而后为ActivityClientRecord的packageInfo赋值,packageInfo是LoadedApk类型,它表示已加载的APK文件,接下来调用了外部类ActivityThread的handleLaunchActivity方法。
接下来咱们来看一下ActivityThread的handleLaunchActivity方法。
该方法源码以下:
//ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//...
//最终回调Activity的onConfigurationChanged方法
handleConfigurationChanged(null, null);
//这里面获取WindowManager系统服务的本地代理
WindowManagerGlobal.initialize();
//一、关注这里,启动Activity,调用了ActivityThread的performLaunchActivity方法,会最终回调Activity的onCreate,onStart方法
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
//...
//二、关注这里,调用了ActivityThread的handleResumeActivity方法,会最终回调Activity的onResume方法
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
//...
}else {
//若是出错了,这里会告诉AMS中止启动Activity
try {
ActivityManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
复制代码
本文的重点是Activity的生命周期如何被回调,因此上面咱们只须要关注注释一、2。注释1中调用了ActivityThread的performLaunchActivity方法,该方法最终完成了Activity对象的建立和启动过程,若是启动出错就会通知AMS中止启动Activity,而且在注释2中ActivityThread经过handleResumeActivity将被启动的Activity置为Resume状态。
咱们首先看注释1的performLaunchActivity方法。
该方法相关源码以下:
//ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//从ActivityClientRecord中获取ActivityInfo。
ActivityInfo aInfo = r.activityInfo;
//获取packageInfo,packageInfo是前面讲到的LoadedApk类型
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
//获取ComponentName
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//建立要启动Activity的上下文环境
ContextImpl appContext = createBaseContextForActivity(r);
//构造Activity对象,并设置参数
Activity activity = null;
try {
//获取类加载器
java.lang.ClassLoader cl = appContext.getClassLoader();
//经过Instrumentation,用类加载建立该Activity实例
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
//设置相关参数准备初始化Activity
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
//初始化Activity失败
//....
}
try {
//建立Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//...
if (activity != null) {
//构造Configuration对象
Configuration config = new Configuration(mCompatConfiguration);
//...
//把该Activity和ContextImpl关联
appContext.setOuterContext(activity);
//经过attach方法将上述建立的信息保持到Activity内部,用来完成对Activity的初始化,如ContextImpl,Application,Configuration
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
//...
//获取Activity的主题并设置
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
//一、根据是否须要持久化,调用Instrumentation的callActivityOnCreate方法通知Activity已经被建立,里面最终会调用Activity的onCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
//关注这里,走这个分支
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
//...
//没法调用Activity的onCreate方法,抛出异常
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
//二、里面最终会调用Activity的onStart方法
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
//根据是否须要持久化,调用Instrumentation的callActivityOnRestoreInstanceState方法通知Activity已经被建立,里面最终会调用Activity的onRestoreInstanceState方法
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
//...
}
r.paused = true;
//把ActivityClientRecord缓存起来,以便在之后使用。mActivities的定义:ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
//...
} catch (Exception e) {
//...
//抛异常,没法启动Activity
}
return activity;
}
复制代码
该方法的主要代码都贴出来了,并作了注释,它主要作了如下事情:
ActivityInfo类用于存储代码中AndroidManifes设置的activity节点信息,ComponentName类中保存了该Activity的包名和类名
ContextImp是Context的具体实现,Context中的大部分逻辑都是交给ContextImpl来完成,Context中定义了许多与四大组件启动、系统级服务获取、类加载、资源获取等有密切关系的方法,而Activity继承自ContextThemeWrapper,ContextThemeWrapper继承自ContextWrapper,ContextWrapper继承自Context,ContextWrapper内部有一个Context类型的mBase引用,而在Activity的attach方法中会调用attachBaseContext方法把该ContextImp赋值给mBase,因此Activity是ContextImpl的包装类,Activity扩展了Context中的方法。(这里就是一个装饰者模式)
makeApplication方法里面最终是经过Instrumentation的newApplication方法用类加载器建立Application,若是Application已经被建立过了,那么就不会重复建立,若是建立成功,会紧接着经过Instrumentation的callApplicationOnCreate来调用Application的onCreate方法。
Instrumentation是一个用来监控应用程序与系统交互的类,经过它能够建立Activity、Applicationd实例,还与Activity生命周期的回调有关,因此在下文看到mInstrumentation.callActivityOnXX, 通常都是要回调某个Activity的生命周期方法。
在attach方法中会建立Window对象(PhoneWindow)并与Activity自身进行关联,这样当Window接收到外部的输入事件后就能够将事件传递给Activity。第2点讲过,还会把ContextImpl与Activity关联。
这里就是重点关注的注释1,注释还写到这里会根据是否须要持久化来调用不一样参数的mInstrumentation的callActivityOnCreate方法,这个持久化是什么?其实这是在API 21后,Activity新增的一个”persistableMode“属性,在AndroidManifest.xml的activity节点将他它设为android:persistableMode=”persistAcrossReboots,Activity就有了持久化的能力,这时候咱们能够数据保存在outPersistentState(Bundle类型),那么即便是关机,仍然能够恢复这些数据。关于PersistableMode更多信息能够看这篇文章PersistableMode使Activity数据持久化保存,这不是本文的重点。
因此通常状况下咱们没有使用这个属性,就会走到else分支,调用 mInstrumentation.callActivityOnCreate(activity, r.state)方法。
该方法源码以下:
//Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
//一、关注这里,调用了Activity的performCreate方法
activity.performCreate(icicle);
postPerformCreate(activity);
}
复制代码
咱们看注释1,调用了activity的performCreate方法,见名知意。
该方法源码以下:
//Activity.java
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
restoreHasCurrentPermissionRequest(icicle);
//一、看到咱们的主角吧!onCreate方法
onCreate(icicle, persistentState);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
复制代码
看注释1,调用了咱们熟悉的onCreate方法,咱们平时通常在这里面进行Activity的控件、资源等初始化操做。
下面继续回到ActivityThread的performLaunchActivity方法,接着上面的第6点。
这里也就是重点关注的注释2,下面看一下performStart方法。
咱们继续点进去看一下:
//Activity.java
final void performStart() {
//...
mCalled = false;
//一、关注这里,调用了Instrumentation的callActivityOnStart方法
mInstrumentation.callActivityOnStart(this);
if (!mCalled) {
//...
//没法调用Activity的onStart方法,抛出异常
}
//...
}
复制代码
看注释1,该方法仍是同样的套路,调用 mInstrumentation.callActivityOnStart方法,咱们看一下 Instrumentation的callActivityOnStart方法:
该方法以下:
//Instrumentation.java
public void callActivityOnStart(Activity activity) {
//看到咱们的主角吧!onStart方法
activity.onStart();
}
复制代码
很简单的一句代码,调用了咱们熟悉的onStart方法。
继续回到咱们的ActivityThread的performLaunchActivity方法,还有一点没分析完,接下来到了根据须要调用Instrumentation的callActivityOnRestoreInstanceState方法,里面最终会调用Activity的onRestoreInstanceState方法,关于这个方法的做用已经不是本文的重点,但咱们能够得出一个结论,onRestoreInstanceState方法的调用时机是在onStart方法以后。最后ActivityThread把ActivityClientRecord缓存起来。
分析完这个长长的方法,其实跟本文有关也就第六、7点。咱们跳出ActivityThread::performLaunchActivity方法,回到ActivityThread的handleLaunchActivity方法。如今咱们的Activity已经回调了onCreate和onStart方法,接下来应该是onResume方法。
下面咱们咱们接着来看handleLaunchActivity方法中注释2的handleResumeActivity方法。
该方法源码以下:
//ActivityThread.java
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
//从缓存中拿出ActivityClientRecord
ActivityClientRecord r = mActivities.get(token);
//...
//一、主要关注这里,调用了performResumeActivity方法,这里最终会调用Activity的onResume方法
r = performResumeActivity(token, clearHide, reason);
//二、下面if(r != null){}分支里面的逻辑都是把Activity显示出来
if (r != null) {
//拿到Activity
final Activity a = r.activity;
//...
boolean willBeVisible = !a.mStartedActivity;
if (!willBeVisible) {
try {
willBeVisible = ActivityManager.getService().willActivityBeVisible(
a.getActivityToken());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
if (r.window == null && !a.mFinished && willBeVisible) {
//获得Activity关联的Window
r.window = r.activity.getWindow();
//获得Activity的DecorView,即Activity的顶级View
View decor = r.window.getDecorView();
//先把DecorView设为不可见
decor.setVisibility(View.INVISIBLE);
//获得ViewManager,用于添加DecorView
ViewManager wm = a.getWindowManager();
//获得布局参加
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
//下面设置布局参数
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
//...
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
//用ViewManager添加DecorView
wm.addView(decor, l);
}
//...
}
}
//...
//此时用于承载DecorView的Window已经被WM添加了,可是还处于INVISIBLE状态,因此下面就把它值为VISIBLE
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
//...
if (r.activity.mVisibleFromClient) {
//把Activity显示出来
r.activity.makeVisible();
}
}
}else {
//...
//Activity不可以Resume,通知AMS结束掉该Activity
}
}
复制代码
handleResumeActivity方法里面的代码也有点长,这个方法主要是把Activity置为Resume状态,并把Activity显示出来,因此咱们只关注注释1,注释2是把Activity值为VISIBLE状态,你们要明白的是Activity其实也能够说是一个View,它的顶级View叫作DecorView,但系统回调完Activity的onResume函数时,只是说明Activity1已经完成全部的资源准备工做,Activity已经作好显示给用户的准备,因此还要经过相似于setVisible的方式把它显示出来,这个过程涉及到WindowManage的相关知识,为何要这样作?你们能够看这篇文章Window,WindowManager和WindowManagerService之间的关系了解一下,因此注释2不是本文重点就不讲了。
下面咱们来看注释1的performResumeActivity方法。
该方法主要源码以下:
//ActivityThread.java
public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide, String reason) {
//从缓存中拿到ActivityClientRecord
ActivityClientRecord r = mActivities.get(token);
if (r != null && !r.activity.mFinished) {
if (clearHide) {
r.hideForNow = false;
r.activity.mStartedActivity = false;
}
//...
try {
//...
//一、主要关注这里,调用了Activity的performResume方法
r.activity.performResume();
//...
r.paused = false;
r.stopped = false;
r.state = null;
r.persistentState = null;
}catch(Exception e) {
//...
//抛异常,没法resume Activity
}
}
return r;
}
复制代码
主要关注注释1,调用了Activity的performResume,和上面的performCreate,performStart很类似。
下面咱们来看Activity的performResume方法。
该方法主要源码以下:
//Activity.java
final void performResume() {
//这里处理Activity生命周期中的Restart流程
performRestart();
//...
mCalled = false;
//一、关注这里,调用Instrumentation的callActivityOnResume方法
mInstrumentation.callActivityOnResume(this);
if (!mCalled) {
//...
//抛异常,没法调用Activity的onResume方法
}
}
复制代码
在这个方法中咱们看到了 performRestart()方法,这个是根据状况处理Restart流程,里面会执行onReStart() -> onStart() ,到这里就执行onResume(), 因此咱们看到注释1会Instrumentation的callActivityOnResume方法,这个和上面的callActivityOnCreate()、callActivityOnStart()相似。
本着执着的态度,咱们仍是看一下Instrumentation的callActivityOnResume方法。
//Instrumentation.java
public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
//又看到了咱们的主角之一,onResume方法
activity.onResume();
//...
}
复制代码
该方法先把Activity的mResumed 赋值为true,而后回调了咱们熟悉的onResume方法。
咱们跳出ActivityThread的handleResumeActivity方法,回到handleLaunchActivity方法,至此handleLaunchActivity方法分析完,Activity已经显示到用户面前。
到目前为止咱们已经回调了Activity的三个生命周期方法:onCreate -> onStart -> onResume,onRestart也介绍了一下,能够说开头那个问题已经解解决了一半,我先来看一下本文的时序图:
因此如今咱们知道了在应用进程中ApplicationThread启动Activity的过程。
那么还有三个方法:onPause -> onStop -> onDestory 何时被回调呢?你们都知道Activity有7个生命周期方法,除去onRestart,其余3个都是一 一对应的,结合前面那篇文章Activity的启动流程(1)咱们知道:
一、在AMS中含有ApplicatiThread的本地代理,因此AMS所在进程能够经过这个代理与ActivityThread的主线程通讯,也就能调用ApplicatiThread的一些方法。
二、在应用进程中也含有系统服务AMS的本地代理对象,因此应用进程能够经过这个代理与AMS通讯,能够请求AMS启动一个Activity。
三、双方都含有双方的代理,经过Binder,也就创建起双方的通讯通道。
每一个应用都有本身专属Activity任务栈,Activity任务栈的管理是在AMS那边,在本文的状况下,一个Activity已经被启动了,该Activity被加入到栈顶中去,若是此时我按back键返回上一个Activity,那么该Activity就会调用相应的回调onPause -> onStop -> onDestory方法,这个过程在AMS那边对应一个出栈动做,此时AMS也就像启动Activity调用scheduleLaunchActivity方法那样调用ApplicationThread中schedulePauseActivity、scheduleStopActivity、scheduleDestroyActivity方法来结束掉这个Activity,这个调用过程是IPC,因此你们经过本文触类旁通也就明白了Activity的其余生命周期是如何被回调的,这个过程离不开与AMS的交互。
至此咱们已经走完startActivity后发生的流程。在这整个过程当中也发现了本身日常不少遗落的知识点,让我更进一步的认识了Activity。但愿你们也有所收获。
参考资料:
《Android源码分析与实战》