最近我開始學習framework,不想一上來就研究到c/c++層進程啓動原理什麼的,首先得從四大組件的啓動流程入手學習,因此我決定寫幾篇博文,來記錄整個過程的學習心得。java
關於Activity的啓動流程,我準備分紅兩個部分來寫:app進程篇和system進程篇,做爲一個應用層開發者,其實掌握前者已經夠用了,第二篇做爲提升,畢竟多瞭解一點也沒有壞處,就這樣吧。android
本文主要基於
android8.1.0_r15
代碼分支調試分析;c++
須要掌握的知識:bash
咱們都知道,打開一個新的Activity須要調用startActivity方法,該方法定義在Context中的,而且在Activity中作了重寫,若是是在Service中開啓一個Activity呢,Service的實現來自Context,先分析在Context中的實現。app
ContextImpl#startActivityasync
@Override
public void startActivity(Intent intent) {
warnIfCallingFromSystemProcess();
startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
&& options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
//真正的調用在這裏
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}
複製代碼
順手看一眼Activity中是怎樣實現的(fk,你到底眼看的仍是手看的);ide
Activity#startActivityoop
@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 {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
//真正的調用在這裏
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) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
複製代碼
比較Activity和ContextImpl的區別:post
最終都是調用Instrumentation.execStartActivity(Context, IBinder, IBinder, Activity, Intent, int, Bundle)
方法,而後就是ContextImpl下有幾個參數傳null。學習
此外,Context還定義startActivityAsUser
方法,該方法對應用層是隱藏的,最終也調用Instrumentation.execStartActivity
另外一個重載方法,暫不追蹤另外一個方法。那咱們繼續跟進Instrumentation代碼。
注意:Instrumentation下,execStartActivity
有幾個重載方法,咱們這裏只分析有七個參數,且第四個參數爲Activity類型的execStartActivity方法。
Instrumentation#execStartActivity
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);
ActivityResult result = null;
if (am.ignoreMatchingSpecificIntents()) {
result = am.onStartActivity(intent);
}
if (result != null) {
am.mHits++;
return result;
} else 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 = ActivityManager.getService()
.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;
}
複製代碼
咱們先捋清每一個參數的意義
參數名 | 參數類型 | 意義 |
---|---|---|
who | Context | 上下文對象 |
contextThread | IBinder | ApplicationThread對象 |
token | IBinder | 當前Activity的Token,可能爲空 |
target | Activity | 當前Activity,可能爲空 |
intent | Intent | intent |
requestCode | int | startActivityforResult傳的requestCode |
options | Bundle | 傳遞的數據 |
這七個參數最不熟悉的就是token和contextThread,這兩個是IBinder類型,這個問題先放一放,帶着疑問,咱們繼續往下看ActivityManager.getService()
是什麼鬼。
ActivityManager#getService
//獲取的是一個單例對象
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
//正在的IActivityManager在這裏
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
複製代碼
getService()
返回是從IActivityManagerSingleton
單例對象中獲得,真正的操做是IActivityManager.Stub
,就這兩行代碼
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
複製代碼
Stub這貨是AIDL生成的,關於AIDL原理自行學習,咱們從AIDL生成的代碼裏拿到了IActivityManager
代理對象,而後再回到Instrumentation.execStartActivity
繼續看
真正調用的是IActivityManager.startActivity()
方法,AIDL應該該有的東西。咱們仍是分析一下IActivityManager.aidl
文件怎樣定義該方法的。
frameworks/base/core/java/android/app/IActivityManager.aild
int startActivity(in IApplicationThread caller, in String callingPackage, in Intent intent,
in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode,
int flags, in ProfilerInfo profilerInfo, in Bundle options);
複製代碼
這個方法一共十個參數,可是沒有註釋,咱們看看調用端Instrumentation
怎麼傳參的吧。
參數名 | 傳參值 | 意義 |
---|---|---|
caller | whoThread | ApplicationThread對象 |
callingPackage | who.getBasePackageName() | 應用包名 |
intent | intent | |
resolvedType | intent.resolveTypeIfNeeded(who.getContentResolver()) | Return the MIME data type of this intent |
resultTo | token | 調用者,也就是結果將要返給誰 |
resultWho | target != null ? target.mEmbeddedID : null | 調用者的另外一種標識吧 |
requestCode | requestCode | |
flags | 0 | |
ProfilerInfo | null | |
Bundle | options |
寫的馬馬虎虎湊合看一下吧,其實很好理解。
那麼IActivityManager
真正的Stub
是誰呢,按照AIDL的慣例,確定是繼承它的IActivityManager.Stub
,一番搜索,咱們找到了ActivityManagerService
這個類。
frameworks/base/service/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
複製代碼
WMS咱們暫時再也不往下追蹤,由於已經超出這篇文章的提綱了,先記住這個類方法入口,咱們下篇將要從這裏分析,到這我畫一張圖,總結一下上面說的這些。
圖畫的很簡單,值得注意的是綠色表明運行在system_process進程,system_process就是AMS所在的進程。
上文咱們一直提到一個類型IApplicationThread
,在Activity和ContextImpl中傳值是mMainThread.getApplicationThread()
,mMainThread
是ActivityThread
類型,getApplicationThread
獲得了ApplicationThread
,那咱們重點分析ApplicationThread
和ActivityThread
這兩個對象。
首先,ActivityThread
並無繼承Thread
,那它就不是線程的子類,那它表明了什麼,從官方的註釋的來看,他是一個應用進程主線程執行的管理者,負責調度和執行四大組件,着手分析他,咱們從main方法入口。
ActivityThread#main
public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
}
複製代碼
精簡完代碼能夠看出,main方法中調用Looper.prepareMainLooperf
方法,該方法建立主線程的Looper
對象,緊接着建立ActivityThread
對象並調用attach
方法,attach方法參數system用來區分是不是系統進程,咱們先不考慮系統進程
ActivityThread#attach
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//獲取IActivityManager代理對象
final IActivityManager mgr =ActivityManager.getService();
try {
//調用attachApplication方法
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
複製代碼
上面關於system的和ViewRootImpl相關的代碼已經精簡掉,能夠清楚的看到調用IActivityManager
的attachApplication
方法,上文已經提到過startActivity
方法也是相似,可是巧合的是兩個方法都傳遞了IApplicationThread
對象做爲第一個參數,上面傳遞的是mAppThread
,那麼這個mAppThread和IApplicationManager何種關係?
ApplicationThread
繼承自IApplicationThread.Stub
,說到這裏你們可能就尬笑了,又是AIDL,先看一下它定義哪些參數,放眼望去大部分是schedule開頭的方法 ApplicationThread#scheduleLaunchActivity
@Override
public final void scheduleLaunchActivity(Intenintent, IBinder token, int ident,
ActivityInfo info, Configuration curConfigConfiguration overrideConfig,
CompatibilityInfo compatInfo, Strinreferrer, IVoiceInteractor voiceInteractor,
int procState, Bundle statePersistableBundle persistentState,
List<ResultInfo> pendingResultsList<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForwardProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = neActivityClientRecord();
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);
}
複製代碼
方法太多不粘貼了,可是有個類有必要留意一下,那就是ActivityClientRecord
ActivityClientRecord
名字爲啥帶個client,我認爲是爲了區別AMS的,ActivityThread相對於AMS就是client;
再顧名思義,這個類是客戶端記錄Activity信息的,有個關鍵屬性token
,token在前文出現過,可是這裏出現意義不同,爲啥,由於這個從WMS傳遞過來的,這是來源,其實在system_process中並不會生成正在的Activity對象,那如何在app端和system_process中共同標識惟一的Activity呢,就是這個token。
再回歸到scheduleLaunchActivity
方法,最後調用了 sendMessage()方法;追蹤該方法,最終調用mH的sendMessage方法 ApplicationThread#sendMessage
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);
}
複製代碼
那麼mH又是誰,是H,繼承自Handler,一個H單字母好風騷,H是幹啥的呢,主要進行線程間通訊,主要看它的handleMessage
方法
ActivityThread.H
public static final int LAUNCH_ACTIVITY = 100;
public static final int PAUSE_ACTIVITY = 101;
public static final int PAUSE_ACTIVITY_FINISHING= 102;
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
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;
}
複製代碼
代碼太長少粘貼爲妙,反正是定義一堆常量,而後handleMessage一路的switch case,頗有規律的最終調用ActivityThread下名字handleXXX()的方法;
隨便進入一個好比handleLaunchActivity方法,下面貌似是建立Activity的代碼,對建立Activity的代碼就是這裏。 既然找到了Activity的建立入口,咱們是否是趁着興奮一路進入handleLaunchActivity看個究竟;說得對,可是我想回過頭來捋一下這幾個類的關係ActivityThread,H,ApplicationThread,IApplicationThread,IActivityManager;
先說ApplicationThread
和ActivityManagerService
進程間雙向通訊:
分析這兩個以前,必須得了解AIDL的Proxy/Stub模式,Proxy做爲客戶端的代理對象,Stub做爲服務端的存根(真正實現),IActivityManager和IApplicationThread二者實現binder雙向通訊。
當app進程向system_process進程請求startActivity事,app進程從ActivityManager獲得IActivityManager的Proxy對象,system_process進程正真的Stub是ActivityManagerService;
當system_process向app進程答覆這個請求時,此時app進程做爲服務端,system_process調用IApplicationThread的proxy對象,app進程正真的Stub是ApplicationThread,從而實現了二者的雙向通訊。
再說ActivityThread
和ApplicationThread
線程間通訊:
爲何說這兩個哥們是須要線程通訊,上文得知ActivityThread是代碼主線程,ApplicationThread表明app進程的IApplicationThread.Stub;
這二者跟線程有什麼關係,這就涉及到binder的另外一個知識binder線程池,具體不在這裏描述,記住一點ApplicationThrea裏面的方法都是在binder線程中執行的,因此H這個類應運而生,接管這二者之間的線程通訊。呵呵我有圖。
接前文所講,咱們繼續從handleLaunchActivity
方法分析,探究Activity的建立和啓動。
ActivityThread#handleLaunchActivity
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// 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();
}
// 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) {
GraphicsEnvironment.earlyInitEGL();
}
WindowManagerGlobal.initialize();
//調用performLaunchActivity方法返回Activity對象
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
//調用resume方法
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
try {
ActivityManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
複製代碼
流程解析:
performLaunchActivity
方法中handleResumeActivity
執行resume,若是須要,調用performPauseActivityIfNeeded
ActivityThread#performLaunchActivity
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
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
//類加載器
java.lang.ClassLoader cl = appContext.getClassLoader();
//建立Activity
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 {
//獲得Application
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;
}
//ContextImpl和Activity綁定
appContext.setOuterContext(activity);
//調用Activity的attath方法
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 (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;
//調用Instrumentation.callActivityOnCreate()
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) {
//調用performStart
activity.performStart();
r.stopped = false;
}
//條件調用Instrumentation.callActivityOnRestoreInstanceState()
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);
}
}
//條件調用Instrumentation.callActivityOnPostCreate()
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
r.paused = true;
//講Activity放到集合中
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;
}
複製代碼
在performLaunchActivity方法中作的工做挺多,咱們整理一下關鍵的流程
ActivityThread#createBaseContextForActivity
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
final int displayId;
try {
displayId = ActivityManager.getService().getActivityDisplayId(r.token);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
//建立ContextImpl
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
String pkgName = SystemProperties.get("debug.second-display.pkg");
if (pkgName != null && !pkgName.isEmpty()
&& r.packageInfo.mPackageName.contains(pkgName)) {
for (int id : dm.getDisplayIds()) {
if (id != Display.DEFAULT_DISPLAY) {
Display display =
dm.getCompatibleDisplay(id, appContext.getResources());
appContext = (ContextImpl) appContext.createDisplayContext(display);
break;
}
}
}
return appContext;
}
複製代碼
ContextImpl的真正建立是調用ContextImpl.createActivityContext,接下來又要分析Instrumentation這個傢伙了
Instrumentation#newActivity
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
//反射調用
return (Activity)cl.loadClass(className).newInstance();
}
複製代碼
Instrumentation#callActivityOnCreate
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
複製代碼
Instrumentation#callActivityOnRestoreInstanceState
public void callActivityOnRestoreInstanceState(Activity activity, Bundle savedInstanceState) {
activity.performRestoreInstanceState(savedInstanceState);
}
複製代碼
Instrumentation#callActivityOnPostCreate
public void callActivityOnPostCreate(Activity activity, Bundle icicle) {
activity.onPostCreate(icicle);
}
複製代碼
Instrumentation大部分起到一箇中轉做用,真正仍是調用了Activity的相關方法,因此最終代碼歸結到Activity身上。
再回到handleLaunchActivity的第二步調用handleResumeActivity,handleResumeActivity方法會繼續調用performResumeActivity
ActivityThread#performResumeActivity
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (localLOGV) Slog.v(TAG, "Performing resume of " + r
+ " finished=" + r.activity.mFinished);
if (r != null && !r.activity.mFinished) {
if (clearHide) {
r.hideForNow = false;
r.activity.mStartedActivity = false;
}
try {
r.activity.onStateNotSaved();
r.activity.mFragments.noteStateNotSaved();
checkAndBlockForNetworkAccess();
if (r.pendingIntents != null) {
deliverNewIntents(r, r.pendingIntents);
r.pendingIntents = null;
}
if (r.pendingResults != null) {
deliverResults(r, r.pendingResults);
r.pendingResults = null;
}
//調用在這裏
r.activity.performResume();
synchronized (mResourcesManager) {
for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) {
final ActivityClientRecord relaunching = mRelaunchingActivities.get(i);
if (relaunching.token == r.token
&& relaunching.onlyLocalRequest && relaunching.startsNotResumed) {
relaunching.startsNotResumed = false;
}
}
}
EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName(), reason);
r.paused = false;
r.stopped = false;
r.state = null;
r.persistentState = null;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to resume activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}
return r;
}
複製代碼
這裏關鍵點是調用Activity.performResume方法; 繼續解析handleResumeActivity()方法
ActivityTread#handleResumeActivity
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
return;
}
// 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
//最終會調用activity的performResume()
r = performResumeActivity(token, clearHide, reason);
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 = ActivityManager.getService().willActivityBeVisible(
a.getActivityToken());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
if (r.window == null && !a.mFinished && willBeVisible) {
//獲取到window
r.window = r.activity.getWindow();
//docor設置成INVISIBLE狀態
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;
//把decorView假如wm
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}
} else if (!willBeVisible) {
if (localLOGV) Slog.v(
TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}
// Get rid of anything left hanging around.
cleanUpPendingRemoveWindows(r, false /* force */);
// 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) {
performConfigurationChangedForActivity(r, r.newConfig);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
+ r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
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) {
//decorView更新wm
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
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 {
//通知AMS這個activity更新了狀態
ActivityManager.getService().activityResumed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
} else {
//異常狀況,幹掉AMS的記錄
try {
ActivityManager.getService()
.finishActivity(token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
複製代碼
activity真正的顯示是邏輯是windowManager.add(View,WindowManager.LayoutParams),WindowManager從Activity獲取,Activity從Window獲得,分析Window代碼獲得WindowManagerImpl是真正的實現,肯定麼?
在看WindowManagerImpl代碼,我曹真正的實現是WindowManagerGlobal,順藤摸瓜到WindowManagerGlobal.addView方法,發現WindowManagerGlobal也只是記錄記錄view的信息,真正處理View的ViewRootImpl對象。
WindowManager.addView追蹤: Activity->Window->WindowManagerImpl->WindowManagerGlobal->ViewRootImpl.setView(),END;
回到主題,總結一下Activity相關方法被調用的順序 0. 反射構造
Activity顯示關鍵代碼順序:
如今咱們能夠很輕鬆的獲得從AMS到Activity的啓動時序圖:
洋洋灑灑寫了一篇,總體沒有多大的深度,是以Activity的啓動爲主線,記錄了在app進程中Activity啓動的調用過程,可是沒有講到Activity其餘生命週期的相關調用,沒有講到Activity自身調用的流程,算是遺憾吧。
另外:近期想寫兩篇VirtualApk
的源碼解析(包括gradle_plugin),到時應該會涉及到更詳細更具體的知識點了,加油吧!