從Android 6.0原始碼的角度剖析Activity的啟動過程
在從Android 6.0原始碼的角度剖析Window內部機制原理文章中,我們詳細剖析了Android Window的內部工作機制,瞭解到每一個Activity都對應著一個Window,Activity的檢視(View)都是依附在Window來呈現的,Window實際是View的直接管理者。本文將在剖析Activity啟動過程的基礎上,詳細瞭解下Activity的Window建立過程。
1. Activity的啟動過程
眾所周知,在Android開發中如果我們需要啟動一個Activity,必須是先例項化一個Intent物件,然後呼叫Activity的startActivity()或startActivityForResult()
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity (Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Activity啟動過程分析入口
startActivityForResult(intent, -1);
}
}
Activity的startActivityForResult()
方法的程式碼比較簡單,它會根據Activity的例項mParent是否為空執行不同的邏輯,由於我們這裡研究的是Activity的啟動過程,所以只考慮mParent為空的情況。首先
Instrumentation的execStartActivity()
開始執行啟動Activity邏輯,該方法需要傳遞一個ApplicationThread例項,該ApplicationThread實質是一個Binder,其重要性我們後面會詳細道來;然後,通過ActivityThread的sendActivityResult()方法
,該方法會呼叫ApplicationThread的scheduleSendResult()方法通過訊息的形式,最終呼叫Activity的onActivityResult(requestCode, resultCode, data)方法將啟動Activity的執行結果回撥。
// ApplicationThread的繼承關係
private class ApplicationThread extends ApplicationThreadNative{...}
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread{...}
//---------------------------------------------------------------
// startActivityForResult原始碼
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
// 執行Instrumentation的execStartActivity
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
// 將Activity啟動結果最終通過onActivityResult回撥
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
...// 程式碼省略
}
}
Instrumentation的execStartActivity方法
並沒有真正實現Activity啟動的邏輯,而是呼叫了ActivityManagerService
的startActivity()方法,通過跟蹤程式碼發現,原來ActivityManagerService是一個Binder物件,歸屬於系統程序,也就是說,Activity的啟動過程實際上是一次IPC(Inter-Process Communication,跨程序通訊)
;然後再呼叫checkStartActivityResult()方法檢測最終啟動的結果,並根據返回的結果作相應的反映,比如我們比較熟悉的有當被啟動的Activitiy沒有在AndroidManifest.xml時,系統會報”Unable to find explicit activity class … ;have you declared this activity in your AndroidManifest.xml?“異常。execStartActivity()方法原始碼如下:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// 獲取IApplicationThread例項
IApplicationThread whoThread = (IApplicationThread) contextThread;
....
try {
// 執行ActivityManagerService的startActivity
// IPC跨程序呼叫
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
// 檢查啟動Activity的結果
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
既然上面提到Activity的啟動過程是一次IPC操作,那麼我覺得在深入分析ActivityManagerService的StartActivity()之前,有必要將這其中的原理講解下。在Instrumentation的execStartActivity方法中,主要通過ActivityManagerNative個靜態方法getDefault()獲得ActivityManagerService例項。通過檢視原始碼發現,ActivityManagerNative
實質是一個Binder,因為它繼承於Binder和介面IActivityManager;getDefault()方法通過Default.get()返回一個IActivityManager例項,gDefault是一個單例模式匿名類物件,在它的create()方法通過ServiceManager的getSystem()方法最終返回一個ActivityManagerService物件,它繼承於ActivityManagerNative,因此ActivityManagerService
就是一個Binder。由於ServiceManager位於系統程序中,用於管理系統各種服務,因此,ActivityManagerService就是一種系統服務,用於管理所有Activity。基於此,Activity的啟動過程,從應用程序Activity的startActivity()到系統程序的ActivityManagerService的startActivity(),就是一次IPC呼叫。
ActivityManagerService、ActivityManagerNative 的繼承關係如下:
// ActivityManagerService的繼承關係
public interface IActivityManager extends IInterface{...}
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
// 獲取系統服務,ActivityManagerService例項
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;
}
};
...
static public IActivityManager getDefault() {
// 返回ActivityManagerSevice例項
return gDefault.get();
}
}
public final class ActivityManagerService extends ActivityManagerNative
接著,我們繼續分析ActivityManagerService的startActivity()方法,該方法並沒有寫具體的邏輯,而是直接呼叫ActivityManagerService的startActivityAsUser()
方法,該方法繼續呼叫ActivityStackSupervisor的startActivityMayWait()
方法。從ActivityStackSupervisor的命名來看,它應該是與Activity棧有關的操作,與其相關聯的還有一個類ActivityStack,它們共同完成Activity的入棧操作。考慮到Activity入棧這部分呼叫稍微有點複雜,這裡通過流程圖的形式給出在ActivityStackSupervisor和ActivityStack之間的呼叫過程,如下圖所示,可以看到當執行到ActivityStackSupervisor的realStartActivityLocked()
方法時才是真正進入到Activity的啟動邏輯。
realStartActivityLocked()方法的程式碼較多,但我們只需關注app.thread.scheduleLaunchActivity(...)
這行程式碼。通過跟蹤原始碼發現,app.thread返回一個IApplication的例項,但是IApplicationThread
是一個介面,它繼承於介面IInterface,scheduleLaunchActivity的具體實現必然在其子類中。果然,在原始碼中我們找到了抽象類ApplicationThreadNative
,它不僅繼承於IApplicationThread還繼承於Binder,因此ApplicationThreadNative實質是一個Binder物件,對scheduleLaunchActivity()的呼叫也是一次IPC操作。但是遺憾的是,我們在ApplicationThreadNative類中並沒有找到與Activity啟動相關的功能程式碼,雖然在其內部類ApplicationThreadProxy(繼承於ApplicationThreadNative)找到scheduleLaunchActivity(),但是它只是完成標準的IPC資料讀寫操作。腫麼辦?還記得我們在文章的開頭分析Activity的startActivityForResult()方法時,傳遞給execStartActivity()方法的引數mMainThread.getApplicationThread()嗎?mMainThread是一個ActivityThread例項,這個類對於Activity的管理來說尤其重要,從命名來看,ActivityThread應該是對應APP的主執行緒(UI執行緒),用於管理應用程式程序中主執行緒的執行、Activity的排程和執行、廣播以及Activity管理器請求的其他操作
。getApplicationThread()是ActivityThread的一個方法,它返回的就是儲存在ActivityThread中的一個ApplicationThread
例項,而這個ApplicationThread就是ApplicationThreadNative的子類,當然也是一個Binder物件!
// ApplcationThread的繼承關係
public interface IApplicationThread extends IInterface {...}
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread {...}
public final class ActivityThread {
private class ApplicationThread extends ApplicationThreadNative {...}
}
//---------------------------------------------------------------
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
...
// 呼叫ActivityThread的scheduleLaunchActivity方法
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
...
}
在ApplicationThread的scheduleLaunchActivity()
方法中,該方法首先會將傳入的所有引數儲存到ActivityClientRecord物件中,然後呼叫sendMessage()使用Handler傳送一個訊息H.LAUNCH_ACTIVITY,其中H繼承於Handler
。接下來,我們在H(即Handler)的訊息處理方法handleMessage()中,順利找到了處理H.LAUNCH_ACTIVITY訊息的程式碼段,除此之外,還包括處理諸如RELAUNCH_ACTIVITY、PAUSE_ACTIVITY、RESUME_ACTIVITY等訊息。由此可見,有關Activity的生命週期等相關操作都是通過訊息傳遞的形式切換到主執行緒來處理的。最終,當Handler收到H.LAUNCH_ACTIVITY訊息後,會呼叫ActivityThread的handleLaunchActivity()
方法完成最後的啟動過程。
// scheduleLaunchActivity原始碼
@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);
// 使用Handler(H)傳送LAUNCH_ACTIVITY訊息
// 在handleMessage中會呼叫performLaunchActivity
sendMessage(H.LAUNCH_ACTIVITY, r);
}
//-----------------------------------------------------------
// H的訊息處理方法
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
// 處理啟動(launch) activity訊息
// 呼叫handleLaunchActivity
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);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
// 處理暫停activity訊息
case PAUSE_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
(msg.arg1&2) != 0);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
// 處理停止Activity訊息
case STOP_ACTIVITY_SHOW:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
handleStopActivity((IBinder)msg.obj, true, msg.arg2);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
為了完成Activity的啟動工作,handleLaunchActivity
主要做了以下幾件事情:
(1) 例項化一個WindowManagerService物件,為建立Window做準備
// 例項化WindowManagerService
WindowManagerGlobal.initialize();
(2) 呼叫performLaunchActivity,建立被啟動的Activity例項
Activity a = performLaunchActivity(r, customIntenyt);
關於Activity的建立過程,我們需要進入ActivityThread的performLaunchActivity()
方法進入進一步分析。首先,獲取Activity、Intent資訊
。獲取Activity的基本資訊,包括啟動模式、主題等等,同時獲取Intent的(ComponentName)元件資訊; 其次,建立Activity物件
。通過類載入器載入名為component.getClassName()的類,即被啟動的Activity類。然後例項化出該類的物件,這個過程主要通過Instrumentation的newActivity方法實現;第三,建立Application物件
。呼叫LoadedApk的makeApplication()方法建立Application例項,在makeApplication()方法中會先判斷是否已經存在一個Application,如果已經存在則直接返回該Application。由此可見,一個應用中(假設該應用只包含一個程序)只能存在一個Application例項。第四,建立Context和Window例項
,呼叫createBaseContextForActivity()方法建立Context上下文物件,同時呼叫Activity的attach()方法為Activity建立對應的Window和視窗管理器例項WindowManager。對於Activity的Window建立,我們將在下一小節詳細講解。最後,呼叫onCreate()方法
。在Instrumatation的callActivityOnCreate()方法中,它會呼叫Activity的performCreate()方法,最終完成對onCreate方法的回撥。至此,隨著Activity的onCreate方法被回撥,整個Activity的啟動過程分析完畢。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 獲取Activity Infomations
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
// 獲取intent的元件資訊
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
// 呼叫Instrumentation的newActivity方法實現
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
// 執行(Activity)cl.loadClass(className).newInstance();
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);
}
}
try {
// 使用makeApplication建立Application例項
// 如果mApplication已經存在,則直接返回該mApplication例項
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
// 為Activity建立上下文物件
Context appContext = createBaseContextForActivity(r, activity);
// 獲取APP name
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
// 建立Activity的Window物件
// 建立窗體管理器WindowManager
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);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
// 執行activity.performCreate方法,完成onCreate方法呼叫
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
// 執行activity.performRestoreInstanceState方法
// 完成onRestoreInstanceState方法呼叫
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) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
}
}
...
return activity;
}
(3) 當Activity例項a被建立後,說明Activity啟動過程已經執行完畢。接下來,系統會根據a建立的最後結果,作相應的處理。當a!=null時,Activity被建立成功,接下來就會呼叫handleResumeActivity()
方法,該方法會呼叫Activity的onResume()方法和將Activity的頂層檢視DecorView新增到Window中(注:DecorView、Window等會在Activity.attach()被呼叫時建立
);如果a==null,則Activity被建立失敗,會呼叫ActivityManagerService的finishActivity()方法讓Activity Manager結束該Activity,並清理相關的資源。
handleLaunchActivity()原始碼如下:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
// 建立Activity之前,先建立WindowManagerService
WindowManagerGlobal.initialize();
// 執行建立Activity操作,通過類載入器
// 執行建立或獲取Application例項操作,上下文
// 執行建立Window、WindowManager
// 執行呼叫onCreate操作
// 執行呼叫onRestoreSaved操作
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
// 將DecorView新增到Window中
// 進入View繪製
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
// 如果activity仍然存在且resumed狀態為false,執行onPause操作
if (!r.activity.mFinished && r.startsNotResumed) {
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to pause activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
r.paused = true;
}
} else {
// 如果a=null,執行finishActivity
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
// Ignore
}
}
}
2. Activity的Window建立過程
從上面Activity的啟動過程分析可知,Activity的Window建立是當執行到performLaunchActivity
方法中的activity.attach(appContext,...)
程式碼開始的。為了完成Activity的Window建立,Activity的attach方法主要做了以下幾件事情。首先,呼叫attachBaseContext()方法繫結Context(上下文)到Activity;其次,通過new PhoneWindow(this)的方式例項化一個Window物件,在從Android 6.0原始碼的角度剖析UI介面架構文章中我們曾分析過: Window是一個抽象類,它的具體實現類為PhoneWindow,該類將DecorView作為窗體的頂層檢視並封裝了相關操作窗體的方法。DecorView是PhoneWindow內部類,它繼承於FrameLayout,是整個窗體最頂層檢視,其包括TitleView和ContentView兩部分
; 接著,呼叫Window的setCallback()方法向Activity註冊Window狀態變化事件監聽器,在CallBack介面中常見的有onAttachedToWindow()、onDetachedFromWindow()等;最後,初始化與Activity相關變數,同時通過context的getSystemService(Context.WINDOW_SERVICE)方法獲取一個WindowManager例項,用於管理Window與WindowManagerService之間的互動.。
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) {
// 設定上下文
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
// 建立Activity的Window例項
mWindow = new PhoneWindow(this);
// 註冊Window狀態變化事件監聽器(Window.Callback)
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
if (info.uiOptions != 0) {
mWindow.setUiOptions(info.uiOptions);
}
mUiThread = Thread.currentThread();
// 初始化變數
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
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);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
// 獲取Window窗體管理器WindowManager
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
}
至此,隨著mWindow = new PhoneWindow(this)
這句程式碼的執行,關於Activity的Window建立就基本完成了。接下來,我們在分析下Activity的檢視是如何依附在Window上,以及Activity的檢視何時才能被使用者看見?
首先,為了將Activity的檢視依附到Window,我們先需要為Activity的檢視建立頂層檢視DecorView,並將檢視相應的佈局檔案新增到DecorView的mContentParent容器中。這個過程從Activity的onCreate方法開始,考慮到我們已經在從Android 6.0原始碼的角度剖析UI介面架構文中作了詳細地剖析,這裡就不再重複敘述了,給了流程圖 :
其次,雖然在上一步我們將Activity的檢視新增到了DecorView,但是這個時候DecorView還沒有被WindowManager新增到Window中。不知道大家是否記得在上一小節中,當我們分析handleLaunchActivity()方法時,在第(3)點:當Activity被建立成功時,即a!=null,會去呼叫ActivityThread的handleResumeActivity()方法
,該方法上述操作,具體如下:
(1) 執行ActivityThread的performResumeActivity()方法,完成對Activity的onResume()呼叫。需要注意的是,當mStopped為true時,會先呼叫activity.onRestart();
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide) {
ActivityClientRecord r = mActivities.get(token);
...
// 呼叫activity.onResume()
// 如果mStopped為ture,事先呼叫activity.onRestart()
r.activity.performResume();
...
return r;
}
(2) 使用WindowManager將DecorView新增到Window中,完成Activity的檢視到Window的繫結,其中,DecorView是Activity的頂層檢視。關於WindowManager是如何addView的,請參考文章從Android 6.0原始碼的角度剖析Window內部機制原理
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 (a.mVisibleFromClient) {
a.mWindowAdded = true;
// 通過WindowManager將其新增到Window(窗體)中
// 建立ViewRootImpl,發起View繪製流程,核心程式碼位於WindowManagerGlobal中
wm.addView(decor, l);
}
}
(3) 呼叫Activity的makeVisible()方法使Activity得檢視可見,即mDecor.setVisibility(View.VISIBLE)。至此,DecorView的新增和顯示過程執行完畢。
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
//------------------------------------------------------------
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
handResumeActivity原始碼如下:
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
// TODO Push resumeArgs into the activity for consideration
// 執行onResume方法
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
final Activity a = r.activity;
if (localLOGV) Slog.v(
TAG, "Resume " + r + " started activity: " +
a.mStartedActivity + ", hideForNow: " + r.hideForNow
+ ", finished: " + a.mFinished);
final int forwardBit = isForward ?
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
// If the window hasn't yet been added to the window manager,
// and this guy didn't finish itself or start another activity,
// then go ahead and add the window.
boolean willBeVisible = !a.mStartedActivity;
if (!willBeVisible) {
try {
willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
a.getActivityToken());
} catch (RemoteException e) {
}
}
// 獲取頂層檢視DecorView
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 (a.mVisibleFromClient) {
a.mWindowAdded = true;
// 通過WindowManager將其新增到Window(窗體)中
// 建立ViewRootImpl,發起View繪製流程,核心程式碼位於WindowManagerGlobal中
wm.addView(decor, l);
}
// If the window has already been added, but during resume
// we started another activity, then don't yet make the
// window visible.
} else if (!willBeVisible) {
if (localLOGV) Slog.v(
TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}
// Get rid of anything left hanging around.
cleanUpPendingRemoveWindows(r);
// The window is now visible if it has been added, we are not
// simply finishing, and we are not starting another activity.
if (!r.activity.mFinished && willBeVisible
&& r.activity.mDecor != null && !r.hideForNow) {
if (r.newConfig != null) {
r.tmpConfig.setTo(r.newConfig);
if (r.overrideConfig != null) {
r.tmpConfig.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
+ r.activityInfo.name + " with newConfig " + r.tmpConfig);
// 呼叫onConfigurationChanged方法
performConfigurationChanged(r.activity, r.tmpConfig);
freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
r.newConfig = null;
}
if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
+ isForward);
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
!= forwardBit) {
l.softInputMode = (l.softInputMode
& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
| forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
// 顯示DecorView,呼叫mDecor.setVisibity
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
}
if (!r.onlyLocalRequest) {
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(
TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
r.onlyLocalRequest = false;
// Tell the activity manager we have resumed.
if (reallyResume) {
try {
ActivityManagerNative.getDefault().activityResumed(token);
} catch (RemoteException ex) {
}
}
} else {
// If an exception was thrown when trying to resume, then
// just end this activity.
try {
ActivityManagerNative.getDefault()
.finishActivity(token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
}
}
}