1. 程式人生 > >基於N原始碼的Activity的啟動過程分析

基於N原始碼的Activity的啟動過程分析

對於該主題的文章,網上氾濫,為了加深印象,最好還是自己跟一遍原始碼,這樣對框架的認識以及對應用的控制都是很有幫助的。

推薦老羅的一些列文章:

老羅的部落格寫的非常好,但分析的原始碼有點老,不過大體思路是不會變的。我這裡就基於android 7.0的原始碼來跟下這個流程,希望能幫到大家。

分析之前,大家一定要對AIDL的使用有個認識,這樣看原始碼才不會迷糊,不懂的可以看下之前發表的文章:AIDL的簡單使用

重要的是腦海裡有這幅圖:

記住這幾點:

1、服務端有個中間者Stub(這個名稱可以自定定義,比如下面要將的ActivityManagerNative),記住它繼承Binder,實現介面。

2、服務端會有一個真正的實現者,它繼承Stub,還記得我們在用AIDL的時候也會這樣用。比如這裡的ActivityManagerServices。

3、客戶端有個中間者Proxy,在跨程序的時候都會這樣獲取它,proxy=stub.asInterface(binder),proxy裡面會有一個binder物件,呼叫代理的方法裡面會呼叫binder物件的transact方法,它會跨程序進入stub裡的onTransact方法裡,從上圖也能看出。

理解這三點後,我們可以來分析Activity的啟動過程了。

首先在應用裡面啟動Activity:

	public void startActivityTest(){
		Intent intent = new Intent(this, MainActivity.class);
		startActivity(intent);
	}

接著會進入Activity.java裡面:

    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

這裡傳入的options為null,接著會走下面方法:

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);

這裡會看到幾個重要的類,一個Instrumentation類,它是Activity啟動的幫助類,一個是ActivityThread類,它主要管理主執行緒應用程式的執行流程。它有個內部類ApplicationThread:

private class ApplicationThread extends ApplicationThreadNative {

這是啥?他繼承ApplicationThreadNative:

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {

看到沒有,他繼承Binder,實現介面。這不就是服務端的Stub嗎?ApplicationThread是服務端的實現者,要理解這裡的服務端是在客戶端這邊。

這個地方可以先記住,後面會用到,繼續我們的流程,在startActivityForResult中會轉到Instrumentation中執行,並且傳遞了一個binder的實現者ApplicationThread。

進入Instrumentation.java

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

這裡又出現一個重要的類,ActivityManagerNative:

public abstract class ActivityManagerNative extends Binder implements IActivityManager
<pre class="java" name="code">    static public IActivityManager getDefault() {
        return gDefault.get();
    }

可以明顯看到它也是服務端的中間者stub,接著看下gDefault:

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

它是個單例類,呼叫get方法,如果沒有初始化就會走進create方法。這裡會從服務總管ServiceManager裡面拿到binder物件,然後看到IActivityManager am = asInterface(b);是不是很熟悉?應該是獲取本地代理吧:

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

        return new ActivityManagerProxy(obj);
    }

果然如此,這裡返回ActivityManagerProxy型別本地代理,上面startActivity就會走進代理裡面:

    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 {
		.
		.
		.
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
		.
		.
        return result;
    }

這裡mRemote就是遠端binder物件,呼叫transact就會進入stub(ActivityManagerNative)中的onTransact方法:

    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case START_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            IBinder resultTo = data.readStrongBinder();
            String resultWho = data.readString();
            int requestCode = data.readInt();
            int startFlags = data.readInt();
            ProfilerInfo profilerInfo = data.readInt() != 0
                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
            Bundle options = data.readInt() != 0
                    ? Bundle.CREATOR.createFromParcel(data) : null;
            int result = startActivity(app, callingPackage, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }

上面startActivity會走進Stub的實現者,誰是stub的實現者,也就是說誰繼承ActivityManagerNative?毋庸置疑,當然是赫赫有名的ActivityManagerService:

public final class ActivityManagerService extends ActivityManagerNative

接著跟蹤,進入startActivity:

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

可以看到進入了ActivityStarter.java中的startActivityMayWait函式,接著又進入startActivityLocked方法:

    final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
			         int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask);
			}

又進入了startActivityLocked方法:

    final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
				doPendingActivityLaunchesLocked(false);
			}
    final void doPendingActivityLaunchesLocked(boolean doResume) {
        while (!mPendingActivityLaunches.isEmpty()) {
            final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
            final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
            try {
                final int result = startActivityUnchecked(
                        pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);
                postStartActivityUncheckedProcessing(
                        pal.r, result, mSupervisor.mFocusedStack.mStackId, mSourceRecord,
                        mTargetStack);
            } catch (Exception e) {
                Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
                pal.sendErrorResult(e.getMessage());
            }
        }
    }

在startActivityUnchecked函式中:

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
				mSupervisor.resumeFocusedStackTopActivityLocked();
			}

轉到了ActivityStackSupervisor.java中的resumeFocusedStackTopActivityLocked函式:

    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }

接著又進入ActivityStack.java中的resumeTopActivityUncheckedLocked函式,好複雜。。。又進入resumeTopActivityInnerLocked函式:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
	startPausingLocked(userLeaving, false, true, dontWaitForPause);
	mStackSupervisor.startSpecificActivityLocked(next, true, true);
}

startPausingLocked應該是暫停啟動Activity的那個Activity,然後又回到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.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

這裡因為啟動的Activity不是應用的第一個Activity所以上面app的資訊不為null,進入realStartActivityLocked中:

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
			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);
	}

這裡的app.thread是遠端binder代理,它是在ActivityManagerNative中的onTransact中初始化:

    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case START_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
    static public IApplicationThread asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IApplicationThread in =
            (IApplicationThread)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ApplicationThreadProxy(obj);
    }

可以看到這個代理是ApplicationThreadProxy型別,呼叫scheduleLaunchActivity會進入stub實現類(ApplicationThread)裡面:

        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) {
			.
			.
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        mH.sendMessage(msg);
    }

這裡的mH是handler型別,發訊息讓它切換到主執行緒處理:

    private class H extends Handler {
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;


進入handleLaunchActivity:

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
		Activity a = performLaunchActivity(r, customIntent);
		
		handleResumeActivity(r.token, false, r.isForward,
        !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
	}

進入handleResumeActivity:

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
	        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);
            }
        }
		Application app = r.packageInfo.makeApplication(false, mInstrumentation);
		Context appContext = createBaseContextForActivity(r, activity);
		Configuration config = new Configuration(mCompatConfiguration);
		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);
	}

終於可以看到這裡用Instrumentation建立Activity,接著建立Application、ContextImpl、Configuration等,接著呼叫Activity的attach函式,將建立的物件關聯到Activity。


Activity的啟動過程就跟蹤到這裡,中間有些函式描述的不是很清楚,下面給出一張圖來總結下: