Activity啟動過程源碼分析

簡書 編程之樂
轉載請注明原創出處,謝謝!

根據上篇文章- Launcher源碼淺析,我們知道點擊Launcher某個圖標后,會調用Launcher的startActivitySafely方法。
如下:

public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
       
        boolean useLaunchAnimation = (v != null) &&
                !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
        Bundle optsBundle = useLaunchAnimation ? getActivityLaunchOptions(v) : null;

        // Prepare intent
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (v != null) {
            intent.setSourceBounds(getViewBounds(v));
        }
        try {
            // ==================  begin ======================
            startActivity(intent, optsBundle);
            return true;
        } catch (ActivityNotFoundException|SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
        }
        return false;
}

Launcher最終調用了父類 Activity 的startActivity(Intent intent, @Nullable Bundle options)方法,startActivity又調用了startActivityForResult。

在startActivityForResult方法內,會調用Instrumentation的execStartActivity方法。

注: 這里的mInstrumentation是Launcher里面的。

 public void startActivityForResult(
            String who, Intent intent, int requestCode, @Nullable Bundle options) {
        Uri referrer = onProvideReferrer();
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, who,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, who, requestCode,
                ar.getResultCode(), ar.getResultData());
        }
        cancelInputsAndStartExitTransition(options);
    }

startActivityForResult里面調用了mInstrumentation.execStartActivity方法

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, String target,
        Intent intent, int requestCode, Bundle options) { ...  }

其中有個參數是mMainThread.getApplicationThread(),mMainThread是Activity類的成員變量(ActivityThread類型),mMainThread.getApplicationThread()獲取的是ApplicationThread類型,ApplicationThread則是ActivityThread的內部類,可以看出ApplicationThread是一個Binder對象。

為了后面研究的方便,有必要提前說明下即將出現的這幾個類的關系,它們分別是

  1. IApplicationThread
  2. ApplicationThread
  3. ApplicationThreadNative
  4. ApplicationThreadProxy

如果你查看過AIDL生成的文件,那么這幾個類就比較容易理解了,IApplicationThread相當于AIDL接口

class ApplicationThread extends ApplicationThreadNative {
    // 因為ApplicationThreadNative繼承 Binder,且ApplicationThreadNative是抽象類,所以ApplicationThread才是真正的Binder實現。
}

public abstract class ApplicationThreadNative extends Binder implements IApplicationThread {
    // Activity中常用到的那個獲取接口的方法如:ServiceConnection中 IMedia iMedia = IMedia.Stub.asInterface(binder);

    static public IApplicationThread asInterface(IBinder obj) {
    // 內部代理類
    return new ApplicationThreadProxy(obj);
}

看下這個AIDL接口的部分定義,其中后面要用到。

public interface IApplicationThread extends IInterface {
    void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, boolean dontReport) throws RemoteException;
    void scheduleStopActivity(IBinder token, boolean showWindow,
            int configChanges) throws RemoteException;
    void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
    void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
    void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)
            throws RemoteException;
    void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
    void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
            IVoiceInteractor voiceInteractor, int procState, Bundle state,
            PersistableBundle persistentState, List<ResultInfo> pendingResults,
            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
            ProfilerInfo profilerInfo) throws RemoteException;
    void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
            List<Intent> pendingNewIntents, int configChanges,
            boolean notResumed, Configuration config) throws RemoteException;
    void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException;
    void scheduleDestroyActivity(IBinder token, boolean finished,
            int configChanges) throws RemoteException;
    void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo,
            int resultCode, String data, Bundle extras, boolean sync,
            int sendingUser, int processState) throws RemoteException;
    void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers,
            ComponentName testName, ProfilerInfo profilerInfo, Bundle testArguments,
            IInstrumentationWatcher testWatcher, IUiAutomationConnection uiAutomationConnection,
            int debugMode, boolean openGlTrace, boolean restrictedBackupMode, boolean persistent,
            Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
            Bundle coreSettings) throws RemoteException;

注意
mMainThread在Launcher中,且mMainThread變量也是在Activity.attach()中綁定的。
目前我們使用到的某些變量如(mMainThread,mInstrumentation)都是Launcher中已經初始化好的,但我們現在分析的是Launcher啟動第三方Activity而不是Launcher本身,后面我們會再次遇到這些變量,這些變量的初始化和綁定過程會出現在新Activity的創建中,目前先不要對這些變量的由來疑惑!

Instrumentation 儀表盤
這個也是非常重要的一個類,大致對這個類有些了解,否則后面很難理解。

mInstrumentation是Activity的一個成員變量,且mInstrumentation是在Activity的 attach(xxx)方法里面賦值的,這個方法非常重要,里面還有mWindow = new PhoneWindow(this, window, activityConfigCallback);
等操作。后面會分析到此方法。

Instrumentation 儀表盤,命名就好像管理生命周期一樣,事實也差不多如此。
看下Instrumentation 的主要方法:

execStartActivity
callApplicationOnCreate
newActivity
callActivityOnCreate
callActivityOnDestroy
callActivityOnRestoreInstanceState
callActivityOnPostCreate
callActivityOnNewIntent
callActivityOnStart
callActivityOnRestart
callActivityOnResume
callActivityOnStop
callActivityOnSaveInstanceState
callActivityOnPause
callActivityOnUserLeaving

mInstrumentation.execStartActivity內部調用了ActivityManagerNative.getDefault().startActivity()方法。
如下:

   public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        // ...
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        try {
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

ActivityManagerNative.getDefault()是個什么東西,這就是前面為什么要提一下ApplicationThread的原因了,形式幾乎一樣。
同樣看下面幾個類:

  1. IActivityManager
  2. ActivityManagerService(AMS)
  3. ActivityManagerNative
  4. ActivityManagerProxy
    和前面完全對應,AMS閃亮登場。
    很明顯,AMS是真正Binder的實現類。

為了體現AMS的重要性和更好理解Binder,這里的主要部分的代碼多貼一些,我們發現和ApplicationThread形式幾乎一模一樣,而且IActivityManager就是AIDL的接口,而ActivityManagerNative 繼承自Binder 且是抽象的,真正的實現是AMS,那么AMS類在哪里呢?

ActivityManagerNative 有一個靜態的getDefault方法,根據類加載機制 ,類在調用static方法時候才會初始化,此時返回gDefault.get(); Singleton是Android的一個單例封裝類工具類,第一次調用get方法時候會通過create方法初始化AMS對象。

這個單例寫法很有意思,又GET一個技能。

public abstract class Singleton<T> {
    private T mInstance;
    protected abstract T create();
    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

IBinder b = ServiceManager.getService("activity");
這個Binder對象就是ActivityManagerService。

在線 ActivityManagerService.java

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    /**
     * Cast a Binder object into an activity manager interface, generating
     * a proxy if needed.
     */
    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);
    }

    /**
     * Retrieve the system's default/global activity manager.
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }

    public IBinder asBinder() {
        return this;
    }

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

class ActivityManagerProxy implements IActivityManager {
    public ActivityManagerProxy(IBinder remote)
    {
        mRemote = remote;
    }

    public IBinder asBinder()
    {
        return mRemote;
    }

    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;
    }
    // ..............
    // ..............
    // 
}

簡單看下 IActivityManager 接口的部分聲明:

public interface IActivityManager extends IInterface {
    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
            ProfilerInfo profilerInfo, Bundle options) throws RemoteException;
    public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
            ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
    public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int flags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
            int userId) throws RemoteException;
    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
            int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options,
            int userId) throws RemoteException;
    public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
            int requestCode, int startFlags, Configuration newConfig,
            Bundle options, int userId) throws RemoteException;
    public int startActivityIntentSender(IApplicationThread caller,
            IntentSender intent, Intent fillInIntent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode,
            int flagsMask, int flagsValues, Bundle options) throws RemoteException;
    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
            Intent intent, String resolvedType, IVoiceInteractionSession session,
            IVoiceInteractor interactor, int flags, ProfilerInfo profilerInfo, Bundle options,
            int userId) throws RemoteException;
    public boolean startNextMatchingActivity(IBinder callingActivity,
            Intent intent, Bundle options) throws RemoteException;
    public int startActivityFromRecents(int taskId, Bundle options)
            throws RemoteException;
    public boolean finishActivity(IBinder token, int code, Intent data, int finishTask)
            throws RemoteException;
    public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
    public boolean finishActivityAffinity(IBinder token) throws RemoteException;
    public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException;
    public boolean releaseActivityInstance(IBinder token) throws RemoteException;
    public void releaseSomeActivities(IApplicationThread app) throws RemoteException;
    public boolean willActivityBeVisible(IBinder token) throws RemoteException;
    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
            IIntentReceiver receiver, IntentFilter filter,
            String requiredPermission, int userId) throws RemoteException;
    public void unregisterReceiver(IIntentReceiver receiver) throws RemoteException;
    public int broadcastIntent(IApplicationThread caller, Intent intent,
            String resolvedType, IIntentReceiver resultTo, int resultCode,
            String resultData, Bundle map, String[] requiredPermissions,
            int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException;
    public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException;
    public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
            boolean abortBroadcast, int flags) throws RemoteException;
    public void attachApplication(IApplicationThread app) throws RemoteException;
    public void activityResumed(IBinder token) throws RemoteException;

我們接著上一步ActivityManagerNative.getDefault().startActivity()即
AMS(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());
    }

AMS的startActivity方法調用了startActivityAsUser。

 @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null);
    }

下面是一系列的調用關系

1. AMS.startActivityAsUser-> ActivityStarter.startActivityMayWait
2. ActivityStarter.startActivityMayWait -> ActivityStarter.startActivityLocked
3. ActivityStarter.startActivityLocked -> ActivityStarter.doPendingActivityLaunchesLocked
4. ActivityStarter.doPendingActivityLaunchesLocked -> ActivityStarter.startActivityUnchecked
5. ActivityStarter.startActivityUnchecked -> mSupervisor(ActivityStackSupervisor).resumeFocusedStackTopActivityLocked();
6. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked->.targetStack(ActivityStack).resumeTopActivityUncheckedLocked
7. ActivityStack.resumeTopActivityUncheckedLocked -> ActivityStack.resumeTopActivityInnerLocked
8. ActivityStack.resumeTopActivityInnerLocked -> mStackSupervisor(ActivityStackSupervisor).startSpecificActivityLocked
9. ActivityStackSupervisor.startSpecificActivityLocked -> ActivityStackSupervisor.realStartActivityLocked

這段調用過程真是非常復雜,幾乎每個類或方法都是千百行,繞的我快暈了。
這些流程,會挑選著代碼講解,如果每個流程一下子把代碼貼出來,幾乎都會被搞瘋。

先看下最后一步:ActivityStackSupervisor.startSpecificActivityLocked

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

        r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }
            // mService是AMS
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

tips:
在 AMS中,每一個 Activity 組件都有一個用戶 ID 和一個進程名稱,其中,用戶 ID 是在安裝該 Activity 組件時由 PackageManagerService 分配的,而進程名稱則是由該 Activity 組件的 android:process屬性來決定的。
ActivityManagerService 在啟動一個 Activity 組件時,首先會以它的用戶 ID 和進程名稱來檢查系統中是否存在一個對應的應用程序進程。如果存在,就會直接通知這個應用程序進程將 Activity 組件啟動起來;否則,就會先以這個用戶 ID 和進程名稱來創建一個應用程序進程,然后在通知這個應用程序進程將該 Activity 組件啟動起來。

根據上面if語句的判斷:
(1). if (app != null && app.thread != null) { }
如果app已經啟動,則通過realStartActivityLocked()啟動Activity。
(2). 如果app還未啟動,則通過AMS創建應用進程。

上述代碼第一次啟動必定先運行(2)

查看ActivityManagerService類的 startProcessLocked()方法,注意startProcessLocked方法有多個重載
下面的方法調用app = newProcessRecordLocked,
最后又調用了另一個重載方法startProcessLocked。

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        long startTime = SystemClock.elapsedRealtime();
        ProcessRecord app;
        if (!isolated) { // 傳入的 isolated 參數為 false ,if 成立,并不是隔離的進程
            // 根據進程名稱和用戶 ID 得到應用程序進程,由于不存在,則為 null 。
            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
            checkTime(startTime, "startProcess: after getProcessRecord");
            // 省略部分代碼
        } else {
            // If this is an isolated process, it can't re-use an existing process.
            app = null;
        }
        // 當進程已經被分配的 PID 時,
        if (app != null && app.pid > 0) {
        }
        // 應用程序進程不存在,創建新的進程
        if (app == null) {
            checkTime(startTime, "startProcess: creating new process record");
            // 創建應用程序進程
            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
            if (app == null) {
            }
            app.crashHandler = crashHandler;
            checkTime(startTime, "startProcess: done creating new process record");
        } else {
            // If this is a new package in the process, add the package to the list
            app.addPackage(info.packageName, info.versionCode, mProcessStats);
            checkTime(startTime, "startProcess: added package to existing proc");
        }
        // 創建應用程序進程后,最終調用 startProcessLocked 方法
        startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);

}

上面的startProcessLocked方法最后調用了下面這個startProcessLocked。

 private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        
        // ................ 省略       
        checkTime(startTime, "startProcess: starting to update cpu stats");
        updateCpuStats();
        checkTime(startTime, "startProcess: done updating cpu stats");

        try {
      
            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
            boolean isActivityProcess = (entryPoint == null);
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            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);
            checkTime(startTime, "startProcess: returned from zygote!");
           
            checkTime(startTime, "startProcess: done updating pids map");
        } catch (RuntimeException e) {

        }
    }

可以看到上面調用了Process.start方法啟動一個進程。其中有這么一小段代碼,如下:

if (entryPoint == null) {
    entryPoint = "android.app.ActivityThread";
}
Process.ProcessStartResult startResult = Process.start(entryPoint,app.processName,....);

Process.start()方法的第一個參數是 entryPoint 指明入口類是ActivityThread(雖然名字是XXThread,但其實是個普通類),而Java的入口一般都是main方法,那么ActivityThread 的 main 方法將在這里啟動。

ActivityThread.main方法并不復雜,來看下它大致干些什么。

 public final class ActivityThread {
   final Looper mLooper = Looper.myLooper();
   final H mH = new H();
   final ApplicationThread mAppThread = new ApplicationThread();
   private static volatile ActivityThread sCurrentActivityThread;
   Instrumentation mInstrumentation;
   static volatile Handler sMainThreadHandler; 

  public static void main(String[] args) {
       // 初始化主線程的消息隊列
       Looper.prepareMainLooper();
       ActivityThread thread = new ActivityThread();
       thread.attach(false);
       if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
       }
       // 開啟消息循環
       Looper.loop();
   }
   private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) { // 是否為系統進程
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
           
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
        } else {
           // 省略系統進程代碼
        } 
        // 省略 ViewRootImpl 相關代碼
    }
}
   // AMS的 attachApplication方法
   public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
  1. Looper.prepareMainLooper();準備循環主線程。
  2. 創建一個 ActivityThread 對象并attach();
    最終sCurrentActivityThread = this; // 當前靜態sCurrentActivityThread
    AMS.attachApplication(mAppThread);// mAppThread是ApplicationThread
  3. 調用Looper.loop();使主線程中消息循環

AMS.attachApplication(mAppThread);中又調用了AMS的attachApplicationLocked,查看該方法:

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
        ProcessRecord app;
       
        // 移除超時消息,應用程序在規定時間內完成了啟動。
        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
        try{
        // 序號1. ************************** IPC 調用 ActivityThread,綁定并創建Application **************************
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
        }catch(Exception e){
            // 
        }
        boolean badApp = false;
        boolean didSomething = false;
         // See if the top visible activity is waiting to run in this process...
         // 序號2. ************************** 調度 Activity **************************  
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                badApp = true;
            }
        }
        // Find any services that should be running in this process...
        // 序號3 ************************** 調度 Service **************************
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                badApp = true;
            }
        }
        // Check if a next-broadcast receiver is in this process...
        // 序號4 ************************** 調度 Broadcast **************************
        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
            try {
                didSomething |= sendPendingBroadcastsLocked(app);
            } catch (Exception e) {
                // If the app died trying to launch the receiver we declare it 'bad'
                badApp = true;
            }
        }
}

這個地方代碼很多,需要特別注意:
下面把這幾個步驟分為幾個序號:

  1. thread.bindApplication啟動Application
  2. 啟動Activity
  3. 啟動Service
  4. 啟動Broadcast

每個序號里面都執行跳轉多次,一個序號一個序號來說,否則容易犯迷糊。
AMS.attachApplication(mAppThread) 序號一

先看 thread.bindApplication,這是一個IPC通信,thread是IApplicationThread 接口,最終調用的方法是服務端真正的Binder對象即 ApplicationThread.bindApplication()

 public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) {
         // delete the fucking code ...................
        sendMessage(H.BIND_APPLICATION, data);
}

可以看到該方法發送一條H.BIND_APPLICATION消息交給handler處理。
我們看下這個Handler,在ActivityThread的內部。

public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                } break;
                case BIND_APPLICATION:
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    break;
                case RELAUNCH_ACTIVITY: {
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                    handleRelaunchActivity(r);
                } break;
                case PAUSE_ACTIVITY: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, false,
                            (args.argi1 & USER_LEAVING) != 0, args.argi2,
                            (args.argi1 & DONT_REPORT) != 0, args.argi3);
                    maybeSnapshot();
                } break;
                case PAUSE_ACTIVITY_FINISHING: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
                            args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
                } break;
            // .................. delete 
}

根據消息case BIND_APPLICATION:
將執行ActivityThread.handleBindApplication(data);方法。

private void handleBindApplication(AppBindData data) {
    // 設置進程名
        Process.setArgV0(data.processName);
    // 創建 Android 運行環境 ContextImpl .
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    // 初始化 Intrumentation 對象
    if (data.instrumentationName != null) {
        try {
           java.lang.ClassLoader cl = instrContext.getClassLoader();
           mInstrumentation = (Instrumentation)
                        cl.loadClass(data.instrumentationName.getClassName()).newInstance();
           } catch (Exception e) {
           }
           mInstrumentation.init(this, instrContext, appContext,
                   new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
                   data.instrumentationUiAutomationConnection);
     } else {
            mInstrumentation = new Instrumentation();
     }
        try {
            // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
            // 創建 Application 對象
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;
            // don't bring up providers in restricted mode; they may depend on the
            // app's custom Application class
            if (!data.restrictedBackupMode) {
                List<ProviderInfo> providers = data.providers;
                if (providers != null) {
                    installContentProviders(app, providers);
                    // For process that contains content providers, we want to
                    // ensure that the JIT is enabled "at some point".
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                }
            }
            // Do this after providers, since instrumentation tests generally start their
            // test thread at this point, and we don't want that racing.
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {         
            }
            try {
                // 執行 Application 的 onCreate 方法
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
            }
        } finally {
            
        }
}

AMS.attachApplication(mAppThread) 序號二
序號二調用了mStackSupervisor(ActivityStackSupervisor).attachApplicationLocked(app)方法:

 boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFocusedStack(stack)) {
                    continue;
                }
                ActivityRecord hr = stack.topRunningActivityLocked();
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                  + hr.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
        return didSomething;
    }

該方法遍歷 ActivityStack 和 TaskRecord,找到位于 Activity 堆棧頂端的一個 ActivityRecord 對象 hr,接著檢查這個 Activity 組件的用戶 ID 和 進程名是否與 ProcessRecord 對象 app 所描述的應用程序的用戶 ID 和進程名一致,如果一致,則調用 StackSupervisor.realStartActivityLocked方法來請求該應用程序進程啟動一個 Activity 組件。

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
            
            // .... 刪 刪 刪 刪 刪 刪 刪 刪 fuck
           app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
     }

StackSupervisor.realStartActivityLocked方法內部調用了app.thread.scheduleLaunchActivity()方法,其中thread是ApplicationThread類型,binder對象。

ApplicationThread.scheduleLaunchActivity方法如下:

@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
        ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
        CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
        int procState, Bundle state, PersistableBundle persistentState,
        List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
        boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

    updateProcessState(procState, false);

    ActivityClientRecord r = new ActivityClientRecord();
    // .......... delete code 
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

scheduleLaunchActivity里面同樣是發送了一條handler消息。
根據上面handleMessage處理的消息類型,將執行
ActivityThread.handleLaunchActivity()方法。

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
     // Initialize before creating the activity
    WindowManagerGlobal.initialize();
    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);
    } else {
        // If there was an error, for any reason, tell the activity
        // manager to stop us.
        try {
            ActivityManagerNative.getDefault()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
        } catch (RemoteException ex) {
            // Ignore
        }
    }
}

分別調用:

  1. performLaunchActivity將 Activity 組件啟動起來
  2. handleResumeActivity方法將 Activity 組件的狀態設置為 Resumed。

下面只講Activity a = performLaunchActivity(r, customIntent);就可以了,handleResumeActivity設置Resumed就沒有什么必要說了。

ActivityThread.performLaunchActivity是個重重重要的方法 ,我們最前面提到某些 重要角色對象 的設置都是在這個方法里面初始化的。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // 獲取ActivityInfo信息
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }

    // 獲取要啟動的Activity的組件信息
    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 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 {
        // 這個地方我稍有疑惑,因為根據前面的邏輯 BIND_APPLICATION消息[app == null情況下]->handleApplication()中
        // 已經使用LoadedApk.makeApplication()生成一個Application對象了,這里在case LAUNCHER_ACTIVITY又調用一遍。
        // 不過LoadedApk.makeApplication有判斷null處理,所以只會返回一個Application對象啦!
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        if (activity != null) {
             // 創建 Activity的 ContextImpl ,作為 Activity 的運行上下文環境
            Context appContext = createBaseContextForActivity(r, activity);
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            // 構造Configuration對象
            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 window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }
            // ******** 重要 : activity.attach(),我最前面提到的這個方法,把上面這些重要對象都設置為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, 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()) {
                // 根據是否需要持久化調用此方法通知Activity已被創建和啟動
                // 回調 Activity 的 onCreate 函數
                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 的 onStart 函數
                activity.performStart();
                r.stopped = false;
            }
            if (!r.activity.mFinished) {
                if (r.isPersistable()) {
                    // Activity 的 onRestoreInstanceState 函數
                    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);
        }
    }
    // 返回創建并初始化過的activity對象
    return activity;
}

終于講完了序號1和序號2,這里的序號1和序號2指的是下圖這幾個步驟的前2個:

AMS.attachApplication中方法的前2個

講了這么多,AMS.attachApplication這個方法還沒執行完,我了個去,累死了!寫的最累的一篇博客了。
時序圖實在懶得畫了,畫這個圖估計也夠嗆,這篇文章篇幅雖然和其他分析AMS的文章比起來算是短些了,因為很多文章幾乎把源碼全部都貼上了,我看著都暈,單單
AMS.startActivityAsUser->ActivityStackSupervisor.realStartActivityLocked 那9步就夠你貼上十幾頁了,那一部分確實跳來跳去搞得人眼花繚亂,而且每段代碼都是千百行,但是最重要的確是最后那兩步,所以我把該省略的跳轉代碼都省掉了,如果具體研究某個步驟就比較容易了,有興趣的可以查找9步中的某一段代碼進行具體分析。花了整整3天時間,如果你喜歡,請點一個贊!nnd......Fuck the code!!!

小結
從上面的執行流程:我們發現Application會創建一個appContext,一個Activity會創建一個Context,(一個Service也會創建一個Context),那么一個應用中 Context的總數 = Activity對象數 + Service對象數 + 1個Application對象。四大組件中的BroadcastReciver和ContentProvider的Context都是直接或間接來自于 Application,Activity,Service。

最后找來自己參考過的一種博主畫的圖,和我的流程差不多,盜圖一張!


image.png

相關補充說明
ActivityStack :Android 中的 Activity 組件堆棧信息,也就是 Task。
ActivityStackSupervisor:管理ActivityStack的類。

參考
Android開發藝術探索
Android源碼設計模式
Android 7.0 源碼
Activity啟動過程分析(從Launcher啟動)
Android 6.0 Launcher 啟動 Activity 過程源碼分析(二)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容