基於8.0原始碼解析:Activity啟動流程

lantier發表於2018-01-26

歡迎關注我的公眾號:

歡迎關注我的公眾號
基於8.0原始碼解析:Activity啟動流程
--- 先貼下圖,有個心裡預期。
基於8.0原始碼解析:Activity啟動流程


基於8.0原始碼解析:Activity啟動流程

本文大概有以下方面:

  • 1、onPause()方法執行;
  • 2、onCreate()方法執行;
  • 3、onStart()方法執行;
  • 4、onResum()方法執行;
  • 5、onStop()方法執行;
  • 6、onSaveInstance()方法執行;
  • 7、總結;

1. onPause()方法的執行

呼叫startActivity,會執行Activity中的startActivity

@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 {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
複製程式碼

最後會呼叫startActivityForResult,然後會呼叫mInstrumentation的execStartActivity

mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
複製程式碼

mInstrumentation是android系統中啟動activity的一個實際操作類,也就是說activity在應用程式端的啟動實際上就是instrumentation執行的。實際上activity的啟動分為應用程式端的啟動和systemserver服務端的啟動。多個應用程式相互配合最終完成了activity在系統中的啟動,而在應用程式端的啟動實際的操作類就是intrumentation來執行的。於是發現了這個方法

int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target, requestCode, 0, null, options);
複製程式碼

ActivityManagerNative.getDefault() 是什麼?到ActivityManagerNative中看一眼

static public IActivityManager getDefault() {
return gDefault.get();
}
複製程式碼

gDefault.get()又是什麼?先看gDefault

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;
}
};
}
複製程式碼

可以發現啟動了IActivityManager am = asInterface(b);然後看asInterface(b)的實現:

static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}

return new ActivityManagerProxy(obj);
}
複製程式碼

最後直擊返回了ActivityManagerProxy。二ActivityManagerProxy繼承自IActivityManager,IActivityManager extends IInterface。應用程式與systemserver程式屬於兩個不同的程式,程式之間需要通訊,android系統採取了自身設計的binder機制,這裡的activityManagerProxy和ActivityManagerNative都是繼承IAcitivityManager,而Systemserver程式中的ActivityManagerServise物件則繼承於ActivityManagerNative Binder --> ActivityManagerNative/ActivityManagerProxy -->ActivityManagerService這樣ActivityManagerNative和ActivityManagerProxy相當於一個binder的客戶端,而ActivityManagerService相當於Binder的服務端。這樣當ActivityManagerNative呼叫介面方法的時候底層通過Binder driver就會將請求資料與請求傳遞給server端,並在server端進行具體的介面邏輯。binder機制是單向的,非同步的。繼續看

int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target, requestCode, 0, null, options);
複製程式碼

可以看到涉及到了binder資料傳輸機制,說明會呼叫systemserver程式

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}
複製程式碼

ActivityManagerService中檢視startActivity

@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());
}
複製程式碼

又呼叫了startActivityAsUser

然後呼叫到了ActivityStarter的startActivityMayWait方法

然後呼叫startActivityLocked然後呼叫 startActivity其中又呼叫了

result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
1003                    startFlags, doResume, options, inTask, outActivity);
複製程式碼

最後呼叫到

if (mDoResume) {
1159                mSupervisor.resumeFocusedStackTopActivityLocked();
1160            }
複製程式碼

檢視這個方法,最後發現其中呼叫了mFocusedStack.resumeTopActivityUncheckedLocked(null, null);

boolean resumeFocusedStackTopActivityLocked(
2060            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
2061        if (targetStack != null && isFocusedStack(targetStack)) {
2062            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
2063        }
2064        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
2065        if (r == null || r.state != RESUMED) {
2066            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
2067        } else if (r.state == RESUMED) {
2068            // Kick off any lingering app transitions form the MoveTaskToFront operation.
2069            mFocusedStack.executeAppTransition(targetOptions);
2070        }
2071        return false;
2072    }
複製程式碼

檢視其中的方法

繼續跟mStackSupervisor.checkReadyForSleepLocked();發現其中呼叫了 startPausingLocked(false, true, null, false);然後去 startPausingLocked(false, true, null, false)中看:這個方法就是讓系統中的棧中的activity執行onPause方法。其中 prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,userLeaving,prev.configChangeFlags,pauseImmediately);這裡的thread是一個IApplicationThread型別的物件,而在ActivityThread中也有一個ApplicationThread類,其繼承了IApplicationTHread,並且都是Binder物件。那麼這裡的IApplication是一個Binder的client端,而ActivityThread中的APplictionThread中的ApplicationThread中是的Binder物件的server端。所以這裡的thrad。schedulePauseActivity實際上呼叫的就是ApplicationThread的SchedulePauseActivity方法。

回到AcitivityThread中:

public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
int seq = getLifecycleSeq();
if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
+ " operation received seq: " + seq);
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);
}
複製程式碼

其中sendMessage是繼承自Handler的H傳送了PAUSE_ACTIVITY_FINISHING的msg,於是去H中的handleMessage中找對應的方法:

case PAUSE_ACTIVITY_FINISHING: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
複製程式碼

其中呼叫了handlePauseActivity方法:看到其中呼叫了performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity")方法:

final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState, String reason) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
}
複製程式碼

這其中又呼叫了performPauseActivity的過載方法:方法中又呼叫了 performPauseActivityIfNeeded(r, reason)方法,我們到這個方法中看一眼:

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
if (r.paused) {
// You are already paused silly...
return;
}

try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName(), reason);
if (!r.activity.mCalled) {
throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
+ " 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 "
+ safeToComponentShortString(r.intent) + ": " + e.toString(), e);
}
}
r.paused = true;
}
複製程式碼

終於看到了mInstrumentation.callActivityOnPause(r.activity);然後我們去mInstrumentation中去找對應的方法:

public void callActivityOnPause(Activity activity) {
activity.performPause();
}
複製程式碼

我們看到是呼叫了 activity.performPause(),於是我們回到activity中看一眼:

final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
onPause();
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
mResumed = false;
}
複製程式碼

終於看到了onPause()方法,那麼就是在這裡呼叫了onPause()方法,讓棧頂的activity處於onpause。也就是說我們在啟動一個activty的時候最先被執行的是棧頂的activity的onpause方法;handlePauseActivity最後又掉用了ActivityManagerNative.getDefault().activityPaused(token),這是應用程式告訴服務程式,棧頂的activity已經彎沉onpause方法,通過binder機制,這個方法最終會呼叫到ActivityManagerServise的activityPaused方法執行。

@Override
7246    public final void activityPaused(IBinder token) {
7247        final long origId = Binder.clearCallingIdentity();
7248        synchronized(this) {
7249            ActivityStack stack = ActivityRecord.getStackLocked(token);
7250            if (stack != null) {
7251                stack.activityPausedLocked(token, false);
7252            }
7253        }
7254        Binder.restoreCallingIdentity(origId);
7255    }
7256
複製程式碼

該方法內部呼叫了activityPausedLocked方法,然後執行了 completePauseLocked(true /* resumeNext /, null / resumingActivity */);

2. onCreate()方法的執行

這裡面又呼叫了 mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);然後對應方法又呼叫targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);對應的方法又去呼叫 result = resumeTopActivityInnerLocked(prev, options);這個方法最後呼叫了 mStackSupervisor.startSpecificActivityLocked(next, true, false);(這幾個和前面類似,只是程式碼片段太多,估計貼出來你們都暈頭轉向了,所以省略吧)

void startSpecificActivityLocked(ActivityRecord r,
1553            boolean andResume, boolean checkConfig) {
1554        // Is this activity's application already running?
1555        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
1556                r.info.applicationInfo.uid, true);
1557
1558        r.getStack().setLaunchTime(r);
1559
1560        if (app != null && app.thread != null) {
1561            try {
1562                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
1563                        || !"android".equals(r.info.packageName)) {
1564                    // Don't add this if it is a platform component that is marked
1565                    // to run in multiple processes, because this is actually
1566                    // part of the framework so doesn't make sense to track as a
1567                    // separate apk in the process.
1568                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
1569                            mService.mProcessStats);
1570                }
1571                realStartActivityLocked(r, app, andResume, checkConfig);
1572                return;
1573            } catch (RemoteException e) {
1574                Slog.w(TAG, "Exception when starting activity "
1575                        + r.intent.getComponent().flattenToShortString(), e);
1576            }
1577
1578            // If a dead object exception was thrown -- fall through to
1579            // restart the application.
1580        }
1581
1582        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1583                "activity", r.intent.getComponent(), false, false, true);
1584    }
複製程式碼

這裡判斷activity所需的程式是否已經啟動,若啟動的話呼叫realStartActivityLocked(r, app, andResume, checkConfig);看一下這個方法,否則呼叫 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false, false, true):在這其中呼叫了app.thread.scheduleLaunchActivity

而當activity所需要的程式未啟動則會呼叫 startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);然後這個方法又呼叫了

startResult = Process.start(entryPoint,
3926                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3927                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3928                        app.info.dataDir, invokeWith, entryPointArgs);
複製程式碼

然後就到了ZygoteProcess中的start方法:

public final Process.ProcessStartResult start(final String processClass,
196                                                  final String niceName,
197                                                  int uid, int gid, int[] gids,
198                                                  int debugFlags, int mountExternal,
199                                                  int targetSdkVersion,
200                                                  String seInfo,
201                                                  String abi,
202                                                  String instructionSet,
203                                                  String appDataDir,
204                                                  String invokeWith,
205                                                  String[] zygoteArgs) {
206        try {
207            return startViaZygote(processClass, niceName, uid, gid, gids,
208                    debugFlags, mountExternal, targetSdkVersion, seInfo,
209                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
210        } catch (ZygoteStartFailedEx ex) {
211            Log.e(LOG_TAG,
212                    "Starting VM process through Zygote failed");
213            throw new RuntimeException(
214                    "Starting VM process through Zygote failed", ex);
215        }
216    }
複製程式碼

對應方法太長於是就擷取最關鍵的程式碼

synchronized(mLock) {
431            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
432        }
複製程式碼

這最終呼叫了zygote並通過socket通訊的方式讓那個zygote程式fork出一個新的程式,並根據我們剛剛傳遞的“android.app.ActivityTHread"字串,發射出該物件並執行activitythread的main方法。應用程式被產建立之後,首先執行的是ActivityThead的main方法。main方法中

ActivityThread thread = new ActivityThread();
thread.attach(false);
複製程式碼

attach方法又呼叫了

final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
複製程式碼

於是又回到了ActivityManagerService中

@Override
7021    public final void attachApplication(IApplicationThread thread) {
7022        synchronized (this) {
7023            int callingPid = Binder.getCallingPid();
7024            final long origId = Binder.clearCallingIdentity();
7025            attachApplicationLocked(thread, callingPid);
7026            Binder.restoreCallingIdentity(origId);
7027        }
7028    }
7029
複製程式碼

最終呼叫到

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
1468                    System.identityHashCode(r), r.info,
1469                    // TODO: Have this take the merged configuration instead of separate global and
1470                    // override configs.
1471                    mergedConfiguration.getGlobalConfiguration(),
1472                    mergedConfiguration.getOverrideConfiguration(), r.compat,
1473                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
1474                    r.persistentState, results, newIntents, !andResume,
1475                    mService.isNextTransitionForward(), profilerInfo);
複製程式碼

與onPause類似,這裡也是通過IApplicationThread的方法實現的,這裡呼叫的scheduleLaunchActivity方法最終呼叫的是ActivityThread中的 scheduleLaunchActivity方法同樣的到了H中的handleMessage:

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;
複製程式碼

然後我們去看handleLaunchActivity,其中又呼叫了Activity a = performLaunchActivity(r, customIntent);

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

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);
}

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);
}
}

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) {
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);

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;
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;
}
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);
}
}
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;

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;
}
複製程式碼

mInstrumentation.newActivity通過反射方法建立了Activity,最後呼叫了mInstrumentation.callActivityOnCreate方法然後我們去Instrumentation中看:

public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
複製程式碼

我們去看Activity中的activity.performCreate(icicle);

final void performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
複製程式碼

3. onstart()方法的執行

好吧,總算看到了Activity的onCreate方法,再去ActivityThread的performLaunchActivty中在呼叫了callActivityOnCreate方法後又呼叫了activity.performStart();方法

if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
複製程式碼

去Activity類中看一眼對應的方法:

final void performStart() {
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
mFragments.noteStateNotSaved();
mCalled = false;
mFragments.execPendingActions();
mInstrumentation.callActivityOnStart(this);
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStart()");
}
mFragments.dispatchStart();
mFragments.reportLoaderStart();

// This property is set for all builds except final release
boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1;
boolean isAppDebuggable =
(mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;

if (isAppDebuggable || isDlwarningEnabled) {
String dlwarning = getDlWarning();
if (dlwarning != null) {
String appName = getApplicationInfo().loadLabel(getPackageManager())
.toString();
String warning = "Detected problems with app native libraries\n" +
"(please consult log for detail):\n" + dlwarning;
if (isAppDebuggable) {
new AlertDialog.Builder(this).
setTitle(appName).
setMessage(warning).
setPositiveButton(android.R.string.ok, null).
setCancelable(false).
show();
} else {
Toast.makeText(this, appName + "\n" + warning, Toast.LENGTH_LONG).show();
}
}
}

mActivityTransitionState.enterReady(this);
}
複製程式碼

看到了mInstrumentation.callActivityOnStart(this);看一眼這個方法做了什麼:

public void callActivityOnStart(Activity activity) {
activity.onStart();
}
複製程式碼

尼瑪,這麼久終於等到onstart方法了。然後我們再回到ActivityThread中的handleLaunchActivty中看到PerformLaynchActivty方法之後呼叫了

handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
複製程式碼

4. onResume()方法的執行

然後就是呼叫r = performResumeActivity(token, clearHide, reason);然後再呼叫 r.activity.performResume();這個方法在Activity中,於是又跑到activty類中:

final void performResume() {
performRestart();

mFragments.execPendingActions();

mLastNonConfigurationInstances = null;

mCalled = false;
// mResumed is set by the instrumentation
mInstrumentation.callActivityOnResume(this);
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onResume()");
}

// invisible activities must be finished before onResume() completes
if (!mVisibleFromClient && !mFinished) {
Log.w(TAG, "An activity without a UI must call finish() before onResume() completes");
if (getApplicationInfo().targetSdkVersion
> android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
throw new IllegalStateException(
"Activity " + mComponent.toShortString() +
" did not call finish() prior to onResume() completing");
}
}

// Now really resume, and install the current status bar and menu.
mCalled = false;

mFragments.dispatchResume();
mFragments.execPendingActions();

onPostResume();
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPostResume()");
}
}
複製程式碼

又看到了mInstrumentation.callActivityOnResume(this);去Instrumentation中看對應的方法:

public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
activity.onResume();

if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
am.match(activity, activity, activity.getIntent());
}
}
}
}
複製程式碼

看到了activity.onResume();

###至此,一個activty的啟動過程完成。

5. onStop()方法的執行

###下面就是另一個activty的onstop過程:在ActivityThread中的handleresumeActivty中:有這樣一段程式碼:

if (!r.onlyLocalRequest) {
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(
TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
複製程式碼

先把這段程式碼貼出來:

private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
boolean stopProfiling = false;
if (mBoundApplication != null && mProfiler.profileFd != null
&& mProfiler.autoStopProfiler) {
stopProfiling = true;
}
if (a != null) {
mNewActivities = null;
IActivityManager am = ActivityManagerNative.getDefault();
ActivityClientRecord prev;
do {
if (localLOGV) Slog.v(
TAG, "Reporting idle of " + a +
" finished=" +
(a.activity != null && a.activity.mFinished));
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
if (stopProfiling) {
mProfiler.stopProfiling();
}
ensureJitEnabled();
return false;
}
}
複製程式碼

看到其中呼叫了am.activityIdle(a.token, a.createdConfig, stopProfiling);按照Binder機制,這段程式碼執行在ActivityManagerService中,

@Override
7031    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7032        final long origId = Binder.clearCallingIdentity();
7033        synchronized (this) {
7034            ActivityStack stack = ActivityRecord.getStackLocked(token);
7035            if (stack != null) {
7036                ActivityRecord r =
7037                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7038                                false /* processPausingActivities */, config);
7039                if (stopProfiling) {
7040                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
7041                        try {
7042                            mProfileFd.close();
7043                        } catch (IOException e) {
7044                        }
7045                        clearProfilerLocked();
7046                    }
7047                }
7048            }
7049        }
7050        Binder.restoreCallingIdentity(origId);
7051    }
複製程式碼
這其中有一段程式碼:mStackSupervisor.activityIdleInternalLocked先貼下這個方法的程式碼:在這其中,又呼叫了 stack.stopActivityLocked(r);r.app.thread.scheduleStopActivity這個熟悉吧,這個肯定又是去ActivityThread中,還是Binder機制,於是又回到ActivityThread中:
public final void scheduleStopActivity(IBinder token, boolean showWindow,
int configChanges) {
int seq = getLifecycleSeq();
if (DEBUG_ORDER) Slog.d(TAG, "stopActivity " + ActivityThread.this
+ " operation received seq: " + seq);
sendMessage(
showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
token, 0, configChanges, seq);
}
複製程式碼

還是去H中看對應的case:

case STOP_ACTIVITY_SHOW: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
SomeArgs args = (SomeArgs) msg.obj;
handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
複製程式碼

再追蹤,發現handleStopActivty中又呼叫了performStopActivityInner(r, info, show, true, "handleStopActivity");然後對應的有看到r.activity.performStop(false /preserveWindow/);回到Activty中:又呼叫了mInstrumentation.callActivityOnStop(this);貼程式碼:

public void callActivityOnStop(Activity activity) {
activity.onStop();
}
複製程式碼

激動不,終於呼叫到了onstop方法。

6. OnSaveInstanceStat()方法的執行

值得注意的是在 r.activity.performStop();之前呼叫了callCallActivityOnSaveInstanceState(r);

private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
r.state = new Bundle();
r.state.setAllowFds(false);
if (r.isPersistable()) {
r.persistentState = new PersistableBundle();
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
}
}
複製程式碼

然後又呼叫到了mInstrumentation.callActivityOnSaveInstanceState

public void callActivityOnSaveInstanceState(Activity activity, Bundle outState,
PersistableBundle outPersistentState) {
activity.performSaveInstanceState(outState, outPersistentState);
}
複製程式碼

回到Activity中:

final void performSaveInstanceState(Bundle outState) {
onSaveInstanceState(outState);
saveManagedDialogs(outState);
mActivityTransitionState.saveState(outState);
storeHasCurrentPermissionRequest(outState);
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
}
複製程式碼

onSaveInstanceState(outState);就是在這裡被調起來的,所以通常問onSaveInstanceState在什麼時機被調起,就是onstop之前。至此,所有的activity啟動流程我們都分析完成了。

7. 總結

下面總結一下:

    1. Activity啟動涉及到多個程式之間的通訊,這裡主要是ActivityThead和ActivityManagerService之間的通訊
    1. ActivityThread向ActivityManagerService程式間訊息通過ActivityManagerNative,ActivityManagerService向ActivityThread程式間傳遞訊息通過IApplicationThread
    1. ActivityManagerService儲存完資訊之後會將系統棧頂的activity執行onPause操作,並且IApplication程式間通訊告訴應用程式執行當前棧頂Activity的onPause方法。
    1. ActivityThead接收到SystemServer的訊息後會統一交給自身定義的Handler物件處理;
    1. ActivityManagerService將執行建立Activity的通知告知ActivityTHread,通過反射機制建立出Activity物件,並執行Activity的oncreate方法,onstart方法,onresume方法。
    1. ActivityThread執行完成onresume方法後告知ActivityManagerServise onresume方法完成,執行棧頂的onstop方法。

相關文章