Activity简介
Activity作为承载Android和用户交互的组件,在开发过程中是必不可少的,作为一个Android开发人员,我们在接触Android开发的第一天肯定就看过这张Google给出的Activity生命周期图:
图中可以很清晰的看到Activity的各个生命周期的调用顺序(on开头的表明在某个节点调用),这里关于每个方法是干嘛用的大家可以网上搜一下,我们关注一下Activity启动过程中是如何按照这个顺序调用的这些方法,我们直接从ActivityThread开始分析;
ActivityThread
main()函数是Java应用程序的入口,在程序运行的时候第一个执行的方法就是main(),这个是在接触Java的时候看到的,但是在写Android应用的时候好像根本没有接触过main()函数,默认的就是 MainActivity
的 onCreate()
方法开始执行了,这似乎和我们刚开始学的有点不一样;
作为程序入口的main()函数我们可以在ActivityThread类里面找到,而我们的Activity创建、销毁等一系列的生命周期的方法都可以在这里面找到;
我们先来看下作为程序入口的main()函数:
// ActivityThread类
public static void main(String[] args) {
// ...
// 创建了ActivityThread对象,并调用attach方法
ActivityThread thread = new ActivityThread();
thread.attach(false);
// ...
}
// ActivityThread类
private void attach(boolean system) {
// ...
// 这里传进来的为false
if (!system) {
final IActivityManager mgr = ActivityManager.getService();
try {
// 这里得到的对象为单例的ActivityManagerService对象
// 因此我们直接转到ActivityManagerService中查看
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
// ...
}
这里我们需要关注一下 mgr.attachApplication(mAppThread);
这行代码中传入的参数为 ApplicationThread
对象,该类为 ActivityThread
的内部类,创建Activity的队列消息将由这个内部类发出;
// ActivityManagerService类
@Override
public final void attachApplication(IApplicationThread thread) {
// ...
// 这里调用了该方法
attachApplicationLocked(thread, callingPid);
// ...
}
// ActivityManagerService类
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// 这个对象将会缓存我们的 thread 参数,即 ApplicationThread 对象
ProcessRecord app;
// ...
// 这里会缓存上一行注释中说的 thread 参数
app.makeActive(thread, mProcessStats);
try {
// ...
// TAG1
// 这里的thread对象我们前面分析过是 ApplicationThread 对象,
// 因此我们直接查看 ApplicationThread 中的 bindApplication() 方法;
if (app.instr != null) {
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
}
} catch (Exception e) {
// ...
return false;
}
if (normalMode) {
try {
// TAG2
// 这个方法将会执行 ApplicationThread 中的 scheduleLaunchActivity() 方法
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
}
}
// ...
return true;
}
上述的源码中我们指定了两个比较关键的点 TAG1 和 TAG2, 接下来我们分别来分析下这两个点:
TAG1
我们平常写项目中都会给项目指定一个Application类,该类也会拥有 onCreate()
等生命周期方法,而且Application的 onCreate
方法会比第一个Activity的onCreate()
方法优先执行,接下来我们从源码的角度来分析下为什么回是这样执行的:
// ActivityThread --> ApplicationThread类
public final void bindApplication(String processName, ApplicationInfo appInfo,
List providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial) {
// ...
// 这里发送了一个队列消息用于绑定Application
// 这里的队列消息由 Handler 的子类 H 类发送,进入方法内部即可查看
// H 类也是 ActivityThread 的内部类
sendMessage(H.BIND_APPLICATION, data);
}
// ActivityThread 类
// 根据上面发送的队列消息,我们追踪到它会执行此方法
private void handleBindApplication(AppBindData data) {
// ...
if (ii != null) {
// ...
} else {
// 这里创建了 mInstrumentation 对象,
// 该对象在我们后面Activity的生命周期方法调用中起着非常重要的作用
mInstrumentation = new Instrumentation();
}
// ...
try {
// 这个方法将会执行我们的Application类的 onCreate()
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
// Instrumentation 类
public void callApplicationOnCreate(Application app) {
// 这里即为调用 Application 的 onCreate()
app.onCreate();
}
TAG2
接下来我们看下第二个标签位置的内容,这里系统调用了 ActivityStackSupervisor
对象的 attachApplicationLocked(app)
方法,同时传入了 ProcessRecord
对象,上面的注释中我们提到过,该对象缓存了我们的 ApplicationThread
对象;
// ActivityStackSupervisor 类
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
// ...
try {
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
}
// ...
return didSomething;
}
// ActivityStackSupervisor 类
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
// ...
try {
// ...
// 这里调用了 ApplicationThread 中的 scheduleLaunchActivity() 方法
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global and
// override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
// ...
} catch (RemoteException e) {
}
return true;
}
我们看到 ActivityStackSupervisor
对象最终还是调用了 ApplicationThread
对象的 scheduleLaunchActivity()
方法,上面的代码分析的是ActivityThread创建的时候系统初始化Application和到我们的第一个Activity创建前的流程,此时我们的Activity还没有创建,但是Application对象已经创建并执行了onCreate()
方法,如果我们在代码中调用 startActivity(Intent intent)
方法启动Activity则是走的另外一套流程但是最终都会执行到 realStartActivityLocked()
方法,这个方法后面即为Activity创建和执行其生命周期的方法的流程;
Activity的创建和生命周期方法的执行
根据上面代码的分析,realStartActivityLocked()
将会调用 ApplicationThread 的 scheduleLaunchActivity()
方法,先来看一下这个方法:
@Override
// 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 pendingResults, List pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
// ...
// 这里也是发送了一个队列消息用来告诉系统创建一个Activity实例
sendMessage(H.LAUNCH_ACTIVITY, r);
}
// ActivityThread 类
// 通过分析消息队列的 handleMessage() 方法,最终调用了该方法
@Override
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// ...
// TAG3
// 这里将是Activity实例创建的地方
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
// ...
// TAG4
// 这里执行Activity的onResume() 方法
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
// TAG5
// 这里判断Activity没有销毁同时失去焦点了将会执行onPause()方法
performPauseActivityIfNeeded(r, reason);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
// ...
}
}
同样我也在上述代码中找了三个相对重要的节点来分析:
TAG3
这里执行了performLaunchActivity(r, customIntent);
方法并最终返回了一个Activity对象,在这里我们就可以猜测一下Activity对象的实例就是在这个方法里面创建的,接下来我们将通过对该方法的源码分析来验证我们的猜想:
// ActivityThread 类
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// ...
// 该对象缓存了我们创建 Intent 对象时传入的目标Activity 的 Class 信息
ComponentName component = r.intent.getComponent();
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 获取类加载器
java.lang.ClassLoader cl = appContext.getClassLoader();
// 这里通过反射创建我们的目标Activity对象
// 验证了我们的之前的猜想
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
// ...
} catch (Exception e) {
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
// ...
// 这里调用 activity 的方法来初始化 Activity 的一些信息,
// 包括创建 Activity 中的 PhoneWindow 对象
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);
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
// 这个方法将会执行 Activity 的 onCreate() 方法
// activity.performCreate(icicle); --> onCreate(icicle);
// 此时Activity刚刚创建同时已经初始化了一些信息,例如Window等
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!r.activity.mFinished) {
// 这个方法将会执行 Acrivity 的 onStart() 方法
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
// 这里将会调用 Activity 的 onRestoreInstanceState(Bundle savedInstanceState);
// 我们可以发现 Activity 的 onRestoreInstanceState 获取到的Bundle对象和
// onCreate 方法中获取到的是一样的,只不过 onCreate 方法里面需要对 Bundle 数据判空
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
// ...
}
// 这里将创建好的Activity缓存到系统的集合中
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
} catch (Exception e) {
}
return activity;
}
分析完 performLaunchActivity()
方法,发现其内部还是信息量很大的这里我们将其做一下总结:
-
Activity
对象的创建是通过反射完成的,这也就可以解释为什么我们在启动Activity
时,在Intent
里面直接传入目标Activity
的Class
对象即可; -
Activity
在创建完对象后会马上调用activity.attach()
方法来初始化必要的信息,包括 Window ,Thread等对象; -
Activity
在初始化完必要的数据后会调用其onCreate(Bundle saveInstance)
方法; -
Activity
在调用完onCreate()
方法后如果没有销毁则会继续调用其onStart()
方法,这里可以做一个设想,如果在Activity
的onCreate()
方法里面调用finish()
方法,则Activity
将不会调用onStart()
方法; - 在调用完
onStart()
方法后,如果在Activity存在系统缓存在Bundle
中的数据,则会调用onRestoreInstanceState(Bundle savedInstanceState);
方法,此方法中的Bundle
数据和onCreate()
方法中的数据为同一个,只不过onCreate()
方法中的Bundle
需要自己判空;
TAG4
分析完上面一步,我们已经知道了 Activity
对象创建和其 onCreate()
和 onStart()
方法是在什么时候创建的,根据本文最开始的图片接下来调用的将会是 Activity
的 onResume()
方法,也就是我们接下来要分析的点:
// ActivityThread 类
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
// ...
// 这里将会执行 Activity 的 onResume() 方法
r = performResumeActivity(token, clearHide, reason);
if (r != null) {
final Activity a = r.activity;
// 这下面的代码是将在 onCreate() 方法中创建的DecorView 对象
// 和当前的Activity中的Window绑定,然后执行View的生命周期方法,
// 这也就是为什么在Activity的第一次 onResume() 方法中无法获取到
// 控件的宽高等信息的原因,关于View的绘制流程,我们将会在另外
// 一篇文章中分析,这里不做扩展;
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
// ...
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
// ...
a.onWindowAttributesChanged(l);
}
}
}
}
}
这里关于执行 onResume()
方法的逻辑还是比较简单的,不过handleResumeActivity()
方法中不仅仅是执行 onResume()
方法这么简单,他还负责将我们在 onCreate()
方法中创建的视图对象 DecorView
同我们Activity
的窗口绑定,同时执行 View
的绘制流程方法,这里不做展开,后期会专门对此模块分析;
根据上面的两段代码的分析,我们发现了 Activity
的 onCreate()
和onStart()
的调用和 Activity
创建是同一个方法中,而 onResume()
方法则是独立出来的一个方法,这样设计的好处在于 Activity
失去焦点和获得焦点的频率是比较高的,比如被其它 Activity
覆盖,而创建和销毁只有在内存被回收或者用户手动关闭才会调用,因此使用频率相对比较低,通过 Activity
的生命周期图也可以证明为什么是这么设计;
到这里 Activity
就可以展示到屏幕上了;