天天看點

Activity啟動流程源碼分析之Launcher啟動(二)

1、前述

在前一篇文章中我們簡要的介紹Activity的啟動流程Activity啟動流程源碼分析之入門(一),當時隻是簡單的分析了一下流程,而且在上一篇部落格中我們也說了Activity的兩種啟動方式,現在我們就來分析其中的第一種方式——Launcher啟動,這種啟動方式的特點是會建立一個新的程序來加載相應的Activity(基于Android5.1源碼)。

2、Activity啟動流程時序圖

好啦,接下來我們先看一下Launcher啟動Activity的時序圖:

Activity啟動流程源碼分析之Launcher啟動(二)

好啦,接下來我們将上述時序圖用代碼來分析一下。

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. (1)-(13)Launcher通過Binder通信通知ActivityManagerService要啟動一個Activity。
  2. (14)-(22)ActivityManagerService通過Binder通信使Launcher進入Paused狀态,并且準備建立新的程序。
  3. (23)-(27)ActivityManagerService通過startProcessLocked方法建立新的程序ActivityThread,準備啟動新的Activity。
  4. (28)-(39)新的程序啟動後ActivityThread開始通過Binder通信使ActivityManagerService啟動新的Activity。

好啦,這邊部落格到此就全部結束啦,整個篇幅還是蠻長的,下篇我們将闡述Activity内部啟動新的Activity的啟動流程,即新的Activity和啟動它的Activity在同一程序中Activity啟動流程源碼分析之startActivity啟動(三)。