通常情況下女蜈,我們?cè)陲@式調(diào)用Activity的情況下涂屁,只需要通過如下代碼就能啟動(dòng)一個(gè)Activity:
Intent intent = new Intent(this, TestActivity.class);
startActivity(intent);
通過上面的代碼就能啟動(dòng)一個(gè)Activity牲览,之后新的Activity就能被系統(tǒng)展示給用戶寥枝。
那么系統(tǒng)是如何啟動(dòng)一個(gè)Activity盖奈?
新的Activity對(duì)象是在什么情況下被創(chuàng)建的混坞?
onCreate是在什么時(shí)機(jī)被系統(tǒng)回調(diào)的?
帶著這些問題钢坦,我們來一起分析下Activity的啟動(dòng)過程究孕。
我們通過startActivity開始分析:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
通過上面的代碼可以發(fā)現(xiàn)調(diào)用了mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options)
這個(gè)方法:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
通過上面的代碼可以發(fā)現(xiàn),啟動(dòng)Activity的真正實(shí)現(xiàn)是ActivityManangerNative.getDefault()
的startActivity
方法來完成的爹凹。
public abstract class ActivityManagerNative extends Binder implements IActivityManager{
}
通過觀察ActivityManangerNative可以發(fā)現(xiàn)繼承了Binder
并實(shí)現(xiàn)了IActivityManager
厨诸,所以ActivityManangerNative
是一個(gè)Binder對(duì)象:
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
通過ActivityManangerNative.getDefault()
方法可以看到這是一個(gè)單例的封裝:
IBinder b = ServiceManager.getService("activity");
通過ServiceManger來獲取到真正的Binder對(duì)象并返回,而這個(gè)對(duì)象就是ActivityManagerService
禾酱,那么怎么確定就是它呢微酬?可以參考PackageManagerService的創(chuàng)建過程。
到此為止颤陶,Activity的啟動(dòng)過程就轉(zhuǎn)到了ActivityManagerService中(不同版本的源碼略有區(qū)別):
ActivityManagerService.startActivity
-> ActivityManagerService.startActivityAsUser
-> ActivityStarter.startActivityMayWait
-> ActivityStarter.startActivityLocked
-> ActivityStarter.startActivityUnchecked
-> ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
-> ActivityStack.resumeTopActivityUncheckedLocked
-> ActivityStack.resumeTopActivityInnerLocked
-> ActivityStackSupervisor.startSpecificActivityLocked
-> ActivityStackSupervisor.realStartActivityLocked
通過不斷的跳轉(zhuǎn)最終跳轉(zhuǎn)到了ActivityStackSupervisor.realStartActivityLocked
方法中:
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
app.thread
是IApplicationThread
的類型:
public interface IApplicationThread extends IInterface {}
而IApplicationThread
是IInterface
類型颗管,所以它也是一個(gè)Binder類型的接口,從IApplicationThread
的聲明可以看出指郁,其中包含了大量的啟動(dòng)忙上、停止Activity的接口,還包含啟動(dòng)和停止Service的接口闲坎。通過聲明可以猜測這個(gè)Binder接口完成了大量的Activity和Service啟動(dòng)和停止相關(guān)的功能疫粥。
那么IApplicationThread
的實(shí)現(xiàn)又是什么呢?
我們通過追溯thread可以知道是ApplicationThread
:
@Override
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) {
updateProcessState(procState, false);
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);
}
這個(gè)方法很簡單腰懂,就是構(gòu)造了ActivityClientRecord
并賦值梗逮,之后發(fā)送一個(gè)消息給Handler,這個(gè)Handler就是主線程的H:
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
Activity a = performLaunchActivity(r, customIntent);
}
最終performLaunchActivity
完成了Activity對(duì)象的創(chuàng)建和啟動(dòng)過程绣溜。
這個(gè)方法主要完成了這幾個(gè)操作:
-
通過
ActivityClientRecord
獲取到需要啟動(dòng)的Activity的組件信息ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); } 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); }
-
通過類加載器創(chuàng)建Activity
Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null) { r.state.setClassLoader(cl); } } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to instantiate activity " + component + ": " + e.toString(), e); } } public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return (Activity)cl.loadClass(className).newInstance(); }
-
通過makeApplication嘗試創(chuàng)建Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
從makeApplication中也可以看到如果Application已經(jīng)存在了慷彤,那么就不會(huì)在創(chuàng)建Application,保證一個(gè)應(yīng)用只有一個(gè)Application對(duì)象。Application也是通過類加載器來創(chuàng)建的底哗。
instrumentation.callApplicationOnCreate(app);
當(dāng)Application第一次創(chuàng)建之后就會(huì)調(diào)用Application的onCreate方法岁诉,這就是為什么當(dāng)啟動(dòng)一個(gè)App的時(shí)候,Application會(huì)被首先調(diào)用的原因跋选。
-
創(chuàng)建ContextImpl對(duì)象并通過Activity的attach方法來完成一系列操作
Context appContext = createBaseContextForActivity(r, activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); if (r.overrideConfig != null) { config.updateFrom(r.overrideConfig); } if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config); Window window = null; if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { window = r.mPendingRemoveWindow; r.mPendingRemoveWindow = null; r.mPendingRemoveWindowManager = null; } 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);
attach方法會(huì)關(guān)聯(lián)ContextImpl對(duì)象涕癣,還會(huì)關(guān)聯(lián)Window對(duì)象,并建立自己和Window對(duì)象的關(guān)聯(lián)前标。
-
調(diào)用Activity的onCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state); -> activity.performCreate(icicle); final void performCreate(Bundle icicle) { restoreHasCurrentPermissionRequest(icicle); onCreate(icicle); mActivityTransitionState.readState(icicle); performCreateCommon(); }
最終調(diào)用了我們熟悉的onCreate的生命周期中坠韩,此時(shí)Activity就完成了整個(gè)的啟動(dòng)過程。