Activity.java core\java\android\app
Android進(jìn)程啟動(dòng)的時(shí)候属拾,會(huì)調(diào)用attach 將自己的 ApplicationThread 對(duì)象傳到 AMS中钞护,AMS 通過(guò)這個(gè)ApplicationThread對(duì)象和 app 通信。如果有要啟動(dòng)的Activity,那么AMS就會(huì)基于ApplicationThread 創(chuàng)建一個(gè)clientTransaction的通信對(duì)象,(clientTransaction 繼承自 Parcel,保證了可以用于進(jìn)程間傳輸)
然后呢就在這個(gè)通信對(duì)象里面封裝好兩個(gè)事件惩坑,一個(gè)是類(lèi)型為 LaunchActivityItem 的事件,這個(gè)事件會(huì)根據(jù)里面的參數(shù)創(chuàng)造指定的Activity也拜,另一個(gè)是 ResumeActivityItem以舒,告知app創(chuàng)造完成后要執(zhí)行它的onStart 和 onResume 操作,然后發(fā)給 app執(zhí)行慢哈。
調(diào)用棧是
ActivityStackSupervisor.java ——> realStartActivityLocked
ClientLifecycleManager.java ——> void scheduleTransaction(ClientTransaction transaction)
ClientTransaction.java ——> public void schedule()
ActivityThread.java—> ApplicationThread scheduleTransaction(ClientTransaction transaction)
ClientTransactionHandler.java ——> void scheduleTransaction(ClientTransaction transaction)
ClientTransaction.java ——> public void preExecute(……)
ActivityThread.java—> MSG EXECUTE_TRANSACTION
TransactionExecutor.java ——> public void execute(ClientTransaction transaction)
TransactionExecutor.java ——> executeCallbacks (這里調(diào)用的就是LaunchActivityItem)
LaunchActivityItem.java ——>execute() postExecute()
直接看 LaunchActivityItem 吧
LaunchActivityItem.java core\java\android\app\servertransaction
這個(gè)類(lèi)里代碼量也不多蔓钟,我們只看關(guān)鍵代碼
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
意思是根據(jù)Activity在AMS中的代表 ActivityRecord 這個(gè) 對(duì)象中的 token 等信息,在app內(nèi)部創(chuàng)建了一個(gè) ActivityClientRecord 對(duì)象卵贱,那么一切就能對(duì)得上了滥沫。
我們打開(kāi)一個(gè)Activity時(shí), 最早是在AMS 中創(chuàng)建一個(gè)ActivityRecord艰赞,用它來(lái)描述Activity在AMS中的狀態(tài)佣谐。創(chuàng)建完成后將這個(gè) ActivityRecord 中的 一個(gè)Binder 對(duì)象發(fā)過(guò)來(lái)。(發(fā)過(guò)來(lái)的也只是一個(gè)Binder代理)方妖,app根據(jù)這個(gè) Binder對(duì)象構(gòu)建出與之對(duì)應(yīng)的ActivityClientRecord對(duì)象。然后根據(jù)這個(gè)ActivityClientRecord 對(duì)象new出真正的Activity罚攀。
這樣就能搞明白了党觅。
接著看client.handleLaunchActivity雌澄,client 就是繼承了 ClientTransactionHandler 的ActivityThread。
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}
if (r.mPendingFixedRotationAdjustments != null) {
// The rotation adjustments must be applied before handling configuration, so process
// level display metrics can be adjusted.
overrideApplicationDisplayAdjustments(r.token, adjustments ->
adjustments.setFixedRotationAdjustments(r.mPendingFixedRotationAdjustments));
}
// Make sure we are running with the most recent config.
handleConfigurationChanged(null, null);
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
// Initialize before creating the activity
if (!ThreadedRenderer.sRendererDisabled
&& (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
HardwareRenderer.preload();
}
WindowManagerGlobal.initialize();
// Hint the GraphicsEnvironment that an activity is launching on the process.
GraphicsEnvironment.hintActivityLaunch();
final Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
if (!r.activity.mFinished && pendingActions != null) {
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
pendingActions.setCallOnPostCreate(true);
}
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
try {
ActivityTaskManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
return a;
}
主要是做一些初始化的操作杯瞻, 關(guān)鍵點(diǎn)是通過(guò)
final Activity a = performLaunchActivity(r, customIntent);
通過(guò) performLaunchActivity 這個(gè)方法構(gòu)建了一個(gè)Activity
繼續(xù)往下镐牺,可以發(fā)現(xiàn)是通過(guò)Instrumentation 這個(gè)類(lèi)反射構(gòu)建了一個(gè)Activity,然后執(zhí)行它的attach 操作魁莉, 做一些初始化睬涧。
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
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);
}
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);//這里使用mInstrumentation 反射創(chuàng)建Activity
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);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
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 resources must be initialized with the same loaders as the
// application context.
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(activity);
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,//直接調(diào)用activity的attach方法,初始化window相關(guān)
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);//這里會(huì)調(diào)用Activity的OnCreate
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
mLastReportedWindowingMode.put(activity.getActivityToken(),
config.windowConfiguration.getWindowingMode());
}
r.setState(ON_CREATE);
// updatePendingActivityConfiguration() reads from mActivities to update
// ActivityClientRecord which runs in a different thread. Protect modifications to
// mActivities to avoid race.
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
接下來(lái)進(jìn)入正題了
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
attachBaseContext(context);//把context賦值給mBase旗唁,可以通過(guò)getBaseContext獲取到context
mFragments.attachHost(null /*parent*/);
mWindow = new PhoneWindow(this, window, activityConfigCallback);//創(chuàng)建一個(gè)類(lèi)型為PhoneWindow的 Window 對(duì)象畦浓,建立和WMS溝通的橋梁
mWindow.setWindowControllerCallback(mWindowControllerCallback);//這個(gè)回調(diào)和android 7.0多任務(wù)窗口有關(guān)
mWindow.setCallback(this);//設(shè)置callback,各類(lèi)鍵盤(pán)輸出事件的回調(diào)
mWindow.setOnWindowDismissedCallback(this);//設(shè)置窗口消失的回調(diào)
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);//與輸入法有關(guān)的設(shè)置
}
if (info.uiOptions != 0) {
mWindow.setUiOptions(info.uiOptions);
}
mUiThread = Thread.currentThread();//設(shè)置當(dāng)前線(xiàn)程為UI線(xiàn)程
mMainThread = aThread;//保存ActivityThread
mInstrumentation = instr;//保存mInstrumentation
mToken = token;//保存ActivityToken 服務(wù)端在 ActivityRecord中
mAssistToken = assistToken;
mIdent = ident;
mApplication = application;
mIntent = intent;
mReferrer = referrer;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;
if (voiceInteractor != null) {
if (lastNonConfigurationInstances != null) {
mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
} else {
mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
Looper.myLooper());
}
}
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);//setWindowManager
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());//為空
}
mWindowManager = mWindow.getWindowManager();//保存WM
mCurrentConfig = config;
mWindow.setColorMode(info.colorMode);
mWindow.setPreferMinimalPostProcessing(
(info.flags & ActivityInfo.FLAG_PREFER_MINIMAL_POST_PROCESSING) != 0);
setAutofillOptions(application.getAutofillOptions());
setContentCaptureOptions(application.getContentCaptureOptions());
}
回到ActivityThread检疫,當(dāng)activity.attach 調(diào)用完成后讶请,會(huì)執(zhí)行
mInstrumentation.callActivityOnCreate(activity, r.state);//這里會(huì)調(diào)用Activity的OnCreate
callActivityOnCreate 內(nèi)部就3個(gè)函數(shù)。最重要的是第二個(gè)屎媳。
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);//預(yù)處理
activity.performCreate(icicle);//判斷當(dāng)前Activity 的啟動(dòng)模式夺溢,分屏或者是畫(huà)中畫(huà), 調(diào)用Activity 的 onCreate,
postPerformCreate(activity);//
}
onCreate 之后Activity一般都會(huì)執(zhí)行 setContentView,setContentView 有兩個(gè)方法烛谊,名字相同但是參數(shù)不一樣风响,一個(gè)是傳入id,另一個(gè)是傳入View 對(duì)象丹禀,不過(guò)本質(zhì)上是一樣的状勤。
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
public void setContentView(View view) {
getWindow().setContentView(view);
initWindowDecorActionBar();
}
分析代碼發(fā)現(xiàn)都是調(diào)用的getWindow() 的 setContentView 方法。getWindow會(huì)返回一個(gè)類(lèi)型為 Window 的 mWindow對(duì)象湃崩,實(shí)際上它是 PhoneWindow荧降。然后調(diào)用它的方法setContentView將View 或者是資源ID設(shè)置進(jìn)去
PhoneWindow.java core\java\com\android\internal\policy
我們看第一種,會(huì)初始化 DecorView
DecorView是PhoneWindow中的起始節(jié)點(diǎn)View攒读,繼承于View類(lèi)朵诫,作為整個(gè)視圖容器來(lái)使用。用于設(shè)置窗口屬性薄扁。它本質(zhì)上是一個(gè)FrameLayout
會(huì)通過(guò) installDecor剪返, installDecor會(huì)調(diào)用generateDecor,最終生成一個(gè)新的Décor返回
@Override
public void setContentView(int layoutResID) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
if (mContentParent == null) {//要么是DecorView本身邓梅,或者是它的孩子脱盲,這里肯定是Null
installDecor();//初始化 DecorView
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
mLayoutInflater.inflate(layoutResID, mContentParent);// 解析我們?cè)O(shè)置的布局資源并且設(shè)置 mContentParent 為父布局
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
protected DecorView generateDecor(int featureId) {
// System process doesn't have application context and in that case we need to directly use
// the context we have. Otherwise we want the application context, so we don't cling to the
// activity.
Context context;
if (mUseDecorContext) {
Context applicationContext = getContext().getApplicationContext();
if (applicationContext == null) {
context = getContext();
} else {
context = new DecorContext(applicationContext, this);
if (mTheme != -1) {
context.setTheme(mTheme);
}
}
} else {
context = getContext();
}
return new DecorView(context, featureId, this, getAttributes());
}