1、前述
在前一篇文章中我們簡要的介紹Activity的啟動流程Activity啟動流程源碼分析之入門(一),當時隻是簡單的分析了一下流程,而且在上一篇部落格中我們也說了Activity的兩種啟動方式,現在我們就來分析其中的第一種方式——Launcher啟動,這種啟動方式的特點是會建立一個新的程序來加載相應的Activity(基于Android5.1源碼)。
2、Activity啟動流程時序圖
好啦,接下來我們先看一下Launcher啟動Activity的時序圖:
好啦,接下來我們将上述時序圖用代碼來分析一下。
3、Activity啟動流程步驟說明
(1)Launcher.startActivitySafely()
Android中桌面的應用程式都是由Launcher啟動的,其中Launcher本身也是一個應用,當應用程式安裝完成後都會在桌面建立相應的應用程式圖示,點選這個圖示,Launcher就會将其啟動起來。
源碼:packages/apps/Launcher2
public final class Launcher extends Activity
implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,View.OnTouchListener {
/**
* Launches the intent referred by the clicked shortcut.
*
* @param v The view representing the clicked shortcut.
*/
public void onClick(View v) {
//......
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
// Open shortcut
final Intent intent = ((ShortcutInfo) tag).intent;
int[] pos = new int[];
v.getLocationOnScreen(pos);
intent.setSourceBounds(new Rect(pos[], pos[],
pos[] + v.getWidth(), pos[] + v.getHeight()));
//這裡調用startActivitySafely方法
boolean success = startActivitySafely(v, intent, tag);
if (success && v instanceof BubbleTextView) {
mWaitingForResume = (BubbleTextView) v;
mWaitingForResume.setStayPressed(true);
}
} else if (tag instanceof FolderInfo) {
if (v instanceof FolderIcon) {
FolderIcon fi = (FolderIcon) v;
handleFolderClick(fi);
}
} else if (v == mAllAppsButton) {
if (isAllAppsVisible()) {
showWorkspace(true);
} else {
onClickAllAppsButton(v);
}
}
}
boolean startActivitySafely(View v, Intent intent, Object tag) {
boolean success = false;
try {
//這裡調用startActivity方法
success = startActivity(v, intent, tag);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
}
return success;
}
}
(2)Activity.startActivity()
由于Launcher是繼承于Activity,是以在startActivitySafely中調用的startActivity方法其實就是Activity中的方法。
源碼:frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks {
//......
@Override
public void startActivity(Intent intent) {
startActivityForResult(intent, -);
}
//......
}
這個函數很簡單,通過調用startActivityForResult方法來進一步操作。
(3)Activity.startActivityForResult()
源碼:frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks {
//......
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);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
//......
}
//......
}
這裡的mInstrumentation和mMainThread都是Activity的成員變量,mMainThread的類型是ActivityThread,表示應用程式的主線程。其通過mMainThread.getApplicationThread()獲得ApplicationThread成員變量,ApplicationThread是一個Binder對象,ActivityManagerService就是通過它和ActivityThread進行通信,這裡的mMainThread代表的是Launcher應用程式的程序。
(4)Instrumentation.execStartActivity()
源碼:frameworks/base/core/java/android/app/Instrumentation.java
public class Instrumentation {
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
//......
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
//這裡調用ActivityManagerProxy對象的startActivity方法
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, , null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
}
這裡通過ActivityManagerNative.getDefault()方法獲得ActivityManagerService的遠端代理ActivityManagerProxy對象。
(5)ActivityManagerProxy.startActivity()
源碼:frameworks/base/core/java/android/app/ActivityManagerNative.java
class ActivityManagerProxy implements IActivityManager
{
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;
}
}
在代碼的注釋位置通過Binder調用ActivityManagerNative類中的onTransact方法,其識别碼為START_ACTIVITY_TRANSACTION,并調用ActivityManagerNative類的startActivity方法,由于ActivityManagerService繼承于ActivityManagerNative類,是以最終調用了ActivityManagerService中的startActivity方法。
(6)ActivityManagerService.startActivity()
源碼:frameworks/base/services/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 options) {
//這裡調用startActivityAsUser方法
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, options,
UserHandle.getCallingUserId());
}
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
//這裡調用startActivityMayWait方法
return mStackSupervisor.startActivityMayWait(caller, -, callingPackage, intent,resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,profilerInfo, null, null, options, userId, null, null);
}
進入到ActivityManagerService.startActivity方法後,調用本類的startActivityAsUser方法,這裡隻是簡單的将操作轉發給ActivityStackSupervisor.startActivityMayWait方法。
(7)ActivityStackSupervisor.startActivityMayWait()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
public final class ActivityStackSupervisor implements DisplayListener {
final int startActivityMayWait(IApplicationThread caller, int callingUid,String callingPackage, Intent intent, ...) {
//......
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, ...);
}
//......
}
緊接着調用本類的startActivityLocked方法。
(8)ActivityStackSupervisor.startActivityLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType, ActivityInfo aInfo,...) {
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, true, options, inTask);
}
緊接着調用本類的startActivityUncheckedLocked方法。
(9)ActivityStackSupervisor.startActivityUncheckedLocked()方法
源碼:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,boolean doResume, Bundle options, TaskRecord inTask) {
//......
ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
targetStack.mLastPausedActivity = null;
//此處調用ActivityStack.startActivityLocked方法
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
if (!launchTaskBehind) {
// Don't set focus on an activity that's going to the back.
mService.setFocusedActivityLocked(r, "startedActivity");
}
return ActivityManager.START_SUCCESS;
}
這段代碼相當的長,并在最終調用ActivityStack.startActivityLocked方法。
(10)ActivityStack.startActivityLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStack.java
final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
TaskRecord rTask = r.task;
final int taskId = rTask.taskId;
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
}
由于這裡的參數doResume在之前的方法中傳入的是true,于是有調用了mStackSupervisor對象的resumeTopActivitiesLocked方法。
(11)ActivityStackSupervisor.resumeTopActivitiesLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,Bundle targetOptions) {
if (targetStack == null) {
targetStack = getFocusedStack();
}
// Do targetStack first.
boolean result = false;
if (isFrontStack(targetStack)) {
//此處又調用了ActivityStack.resumeTopActivityLocked方法
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
}
進入到resumeTopActivityLocked方法。
(12)ActivityStack.resumeTopActivityLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStack.java
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
mService.updateSleepIfNeededLocked();
}
//這裡調用resumeTopActivityInnerLocked方法
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
(13)ActivityStack.resumeTopActivityInnerLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStack.java
final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
if ((parent != null && parent.state != ActivityState.RESUMED) ||
!mActivityContainer.isAttachedLocked()) {
return false;
}
// Find the first activity that is not finishing.
final ActivityRecord next = topRunningActivityLocked(null);
// If the top activity is the resumed one, nothing to do.
if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
mStackSupervisor.allResumedActivitiesComplete()) {
//......
}
// If we are sleeping, and there is no resumed activity, and the top
// activity is paused, well that is the state we want.
if (mService.isSleepingOrShuttingDown()
&& mLastPausedActivity == next
&& mStackSupervisor.allPausedActivitiesComplete()) {
//......
}
if (mResumedActivity != null) {
//這裡調用startPausingLocked方法
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
}
這段代碼做的事情還是比較多的,函數首先通過調用topRunningActivityLocked方法獲得堆棧頂端的Activity,儲存到next中。
然後看要啟動的Activity是否就是目前處理Resumed狀态的Activity,如果是就不做任何處理,如果不滿足就需要将Resumed狀态的Activity推入Paused狀态,然後才能啟動新的Activity。但再這之前首先要檢查一下是否有Activity正處于Paused狀态,如果有的話這個Resumed狀态的Activity就要稍後才能進入Paused狀态了,這樣才能保證所有需要進入Paused狀态的Activity串行處理,這裡就需要調用startPausingLocked方法把Launcher推入Paused狀态。
我們進入startPausingLocked方法。
(14)ActivityStack.startPausingLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStack.java
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,boolean dontWait) {
//調用IApplicationThread對象的schedulePauseActivity方法
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,userLeaving, prev.configChangeFlags, dontWait);
}
這裡的prev.app.thread是一個遠端IApplicationThread對象,通過調用這個遠端對象的schedulePauseActivity來通知Launcher進入Paused狀态,而ApplicationThreadProxy是IApplicationThread對象的代理類,另外就是此刻由于Launcher還沒Pause,是以prev.finishing屬性為false。
(15)ApplicationThreadProxy.schedulePauseActivity()
源碼:frameworks/base/core/java/android/app/ApplicationThreadNative.java
class ApplicationThreadProxy implements IApplicationThread {
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(finished ? : );
data.writeInt(userLeaving ? :);
data.writeInt(configChanges);
data.writeInt(dontReport ? : );
//這裡通過SCHEDULE_PAUSE_ACTIVITY_TRANSACTION識别碼調用onTransact方法
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
}
在代碼的注釋位置通過Binder調用ApplicationThreadNative類中的onTransact方法,其識别碼為SCHEDULE_PAUSE_ACTIVITY_TRANSACTION,并調用ApplicationThreadNative類的schedulePauseActivity方法,由于ApplicationThread繼承于ApplicationThreadNative類,是以最終調用了ApplicationThread中的schedulePauseActivity方法。
(16)ApplicationThread.schedulePauseActivity()
源碼:frameworks/base/core/java/android/app/ActivityThread.java
這是ActivityThread的内部類
public final class ActivityThread {
private class ApplicationThread extends ApplicationThreadNative {
public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) {
//通過發送Message來處理消息
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? : ) | (dontReport ? : ),
configChanges);
}
}
}
在(14)步時已經說了,這裡的finished變量是false,是以我們進入到識别碼為PAUSE_ACTIVITY的Handler中。
(17)ActivityThread .H
源碼:frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread {
private final class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case PAUSE_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
//此處調用handlePauseActivity
handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&) != , msg.arg2,(msg.arg1&) != );
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
}
}
可以看出此處調用了ActivityThread.handlePauseActivity方法進行處理,另外說一句此處的msg.obj是一個ActivityRecord對象的引用,它代表的是Launcher這個Activity。
(18)ActivityThread.handlePauseActivity()
源碼:frameworks/base/core/java/android/app/ActivityThread.java
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
//當userLeaving為true,将執行performUserLeavingActivity()方法
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
//執行performPauseActivity
performPauseActivity(token, finished, r.isPreHoneycomb());
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
// Tell the activity manager we have paused.
if (!dontReport) {
try {
//執行ActivityManagerService.activityPaused方法
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
}
}
mSomeActivitiesChanged = true;
}
}
這個方法做了三件事:
(1)當userLeaving為true時,通過調用performUserLeavingActivity方法來調用Activity.performUserLeaving方法通知目前Activity即将要退出了。
(2)調用performPauseActivity方法來調用Activity.onPause方法。
(3)調用ActivityManagerNative.getDefault()對象的activityPaused方法來通知ActivityManagerService處理剩下的事情。
(19)ActivityManagerProxy.activityPaused()
源碼:frameworks/base/core/java/android/app/ActivityManagerNative.java
public void activityPaused(IBinder token) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
在(18)步驟中通過ActivityManagerNative.getDefault()獲得ActivityManagerNative的代理對象ActivityManagerProxy,并調用他的activityPaused方法。
通過Binder機制調用ActivityManagerNative的onTransact方法,其識别碼為ACTIVITY_PAUSED_TRANSACTION,并最終調用ActivityManagerService的activityPaused方法。
(20)ActivityManagerService.activityPaused()
源碼:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
}
再次進入到ActivityStack的activityPausedLocked方法中。
(21)ActivityStack.activityPausedLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStack.java
final class ActivityStack {
final void activityPausedLocked(IBinder token, boolean timeout) {
//......
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)"));
completePauseLocked(true);
}
//......
}
}
}
在上面的(17)步驟中我們說了此處的參數token即是ActivityRecord,同時也是Launcher這個Activity。此處的r就是我們目前需要Pause的對象,是以條件成立進入completePauseLocked方法。
(22)ActivityStack.completePauseLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStack.java
private void completePauseLocked(boolean resumeNext) {
ActivityRecord prev = mPausingActivity;
//......
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDown()) {
mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
} else {
mStackSupervisor.checkReadyForSleepLocked();
ActivityRecord top = topStack.topRunningActivityLocked(null);
if (top == null || (prev != null && top != prev)) {
// If there are no more activities available to run,
// do resume anyway to start something. Also if the top
// activity on the stack is not the just paused activity,
// we need to go ahead and resume it to ensure we complete
// an in-flight app switch.
mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
}
}
}
}
此處再次調用了mStackSupervisor對象的resumeTopActivitiesLocked方法。
(23)ActivityStackSupervisor.resumeTopActivitiesLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
if (targetStack == null) {
targetStack = getFocusedStack();
}
// Do targetStack first.
boolean result = false;
if (isFrontStack(targetStack)) {
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
}
(24)ActivityStack.resumeTopActivityLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStack.java
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
mService.updateSleepIfNeededLocked();
}
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
(25)ActivityStack.resumeTopActivityInnerLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStack.java
final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
//......
mStackSupervisor.startSpecificActivityLocked(next, true, false);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
我們進入到startSpecificActivityLocked方法中。
(26)ActivityStackSupervisor.startSpecificActivityLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
//......
if (app != null && app.thread != null) {
realStartActivityLocked(r, app, andResume, checkConfig);
return;
}
//......
//我們主要來分析這裡
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, ,
"activity", r.intent.getComponent(), false, false, true);
}
我們接下來分析一下這段代碼:
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
這裡由于是第一次啟動應用程式的Activity,是以取回來的app為null。在Activity應用程式中的AndroidManifest.xml配置檔案中,我們沒有指定Application标簽的process屬性,系統就會預設使用應用程式包名作為程序名。每一個應用程式都有自己的uid,是以,這裡uid + processName的組合就可以為每一個應用程式建立一個ProcessRecord。當然,我們也可以在不同的應用程式中的AndroidManifest.xml檔案的application标簽或者activity标簽中顯式指定相同的process屬性值,那樣不同的應用程式也可以在同一個程序中啟動。
最後執行ActivityManagerService.startProcessLocked方法。
(27)ActivityManagerService.startProcessLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,...) {
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
}
}
這裡通過調用Process.start方法來建立新的程序,新的程序會導入android.app.ActivityThread類,并且執行它的main函數,這就是為什麼每個應用程式都有一個ActivityThread對象對應着,同時每個應用程式都是從ActivityThread的main函數開始的。
(28)ActivityThread.main()
源碼:frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
//......
Process.setArgV0("<pre-initialized>");
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"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
private void attach(boolean system) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
}
main函數建立ActivityThread對象,然後調用它的attach方法,緊接着最後進入消息循環,直至程序退出。
而attach方法通過ActivityManagerNative.getDefault()獲得ActivityManagerProxy代理對象,然後調用其attachApplication方法,這個方法最終在ActivityManagerService中實作,傳入的參數是ApplicationThread類型的Binder對象,用于程序間通信。
(29)ActivityManagerService.attachApplication()
源碼:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
緊接着直接調用attachApplicationLocked方法。
(30)ActivityManagerService.attachApplicationLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
//這裡調用mStackSupervisor對象的attachApplicationLocked方法
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
}
(31)ActivityStackSupervisor.attachApplicationLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
//......
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid&& processName.equals(hr.processName)) {
try {
//這裡調用真正啟動Activity的方法
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
//......
}
}
}
}
}
//......
return didSomething;
}
這裡通過topRunningActivityLocked方法從棧頂端取出要啟動的Activity,然後通過realStartActivityLocked方法來啟動它。
(32)ActivityStackSupervisor.realStartActivityLocked()
源碼:frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
//這裡調用IApplicationThread對象的scheduleLaunchActivity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,
r.icicle, r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
}
這裡可以看出app.thread對象就是IApplicationThread對象,而該對象的代理對象是ApplicationThreadProxy,是以這裡調用ApplicationThreadProxy.scheduleLaunchActivity方法。
(33)ApplicationThreadProxy.scheduleLaunchActivity()
源碼:frameworks/base/core/java/android/app/ApplicationThreadNative.java
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,...) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
intent.writeToParcel(data, 0);
data.writeStrongBinder(token);
//......
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
這裡通過Binder對象調用ApplicationThreadNative的onTransact方法,其識别碼是SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION,而ApplicationThreadNative的實作類是ApplicationThread類,是以這裡間接的調用了ApplicationThread的scheduleLaunchActivity方法。
(34)ApplicationThread.scheduleLaunchActivity()
源碼:frameworks/base/core/java/android/app/ActivityThread.java
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info,...) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
//......
r.profilerInfo = profilerInfo;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
這裡通過H這個Handler來發送和處理消息。
(35)ActivityThread.H
源碼:frameworks/base/core/java/android/app/ActivityThread.java
public void handleMessage(Message msg) {
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);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
}
}
這裡調用本類的handleLaunchActivity方法。
(36)ActivityThread.handleLaunchActivity()
源碼:frameworks/base/core/java/android/app/ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
//......
}
//......
}
這裡先調用performLaunchActivity方法來加載Activity,這個方法内部會調用OnCreate方法,并傳回目前Activity,當Activity!=null時将執行handleResumeActivity方法,使這個Activity在調用OnResume方法,這裡按照Activity的生命周期執行。
我們直接進入performLaunchActivity方法。
(37)ActivityThread.performLaunchActivity()
源碼:frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
//()這裡主要用于收集Activity的相關資訊(package和component)
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 {
//()這裡通過類加載器ClassLoader加載目前需要啟動的Activity
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對象,主要是根據Manifest檔案配置進行建立
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//......
if (activity != null) {
//()建立上下文資訊,并通過attach方法将上下文資訊設定到Activity中
Context appContext = createBaseContextForActivity(r, 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);
//......
activity.mCalled = false;
if (r.isPersistable()) {
//()通過調用mInstrumentation對象的callActivityOnCreate方法并最終調用Activity的OnCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
}
上面的源碼的我們對重要的點都做了分析,此處就不一一分析了,我們緊接着進入mInstrumentation對象的callActivityOnCreate方法。
(38)Instrumentation.callActivityOnCreate()
源碼:frameworks/base/core/java/android/app/Instrumentation.java
/**
* Perform calling of an activity's {@link Activity#onCreate}
* method. The default implementation simply calls through to that method.
*
* @param activity The activity being created.
* @param icicle The previously frozen state (or null) to pass through to onCreate().
*/
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
在調用Activity的performCreate方法前後,會分别調用一個prePerformCreate和postPerformCreate方法做處理。
(39)Activity.performCreate()
源碼:frameworks/base/core/java/android/app/Activity.java
final void performCreate(Bundle icicle) {
bringUpThreadPriority();
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
終于看到Activity的OnCreate方法調用了吧,哈哈到此整個Activity的啟動流程我們就看完啦,也就是說現在MainActivity也就啟動起來了。
4、總結
從上面的啟動流程來看,平時我們啟動一個Activity時,在應用的架構層還是做了很多的事情,由于上面的步驟較多,我們準備将它們分分類。
- (1)-(13)Launcher通過Binder通信通知ActivityManagerService要啟動一個Activity。
- (14)-(22)ActivityManagerService通過Binder通信使Launcher進入Paused狀态,并且準備建立新的程序。
- (23)-(27)ActivityManagerService通過startProcessLocked方法建立新的程序ActivityThread,準備啟動新的Activity。
- (28)-(39)新的程序啟動後ActivityThread開始通過Binder通信使ActivityManagerService啟動新的Activity。
好啦,這邊部落格到此就全部結束啦,整個篇幅還是蠻長的,下篇我們将闡述Activity内部啟動新的Activity的啟動流程,即新的Activity和啟動它的Activity在同一程序中Activity啟動流程源碼分析之startActivity啟動(三)。