Activity組件啓動過程(三)

承接上面文章《Activity組件啓動過程(二)》中的分析,繼續進去看startSpecificActivityLocked:

11、ActivityStackSupervisor#startSpecificActivityLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java*/
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // 判斷待啓動Activity所在進程是否已經存在並運行
    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);
            }
            // 如同字面上的意義,真正開啓Activity的方法函數
            realStartActivityLocked(r, app, andResume, checkConfig);
            
            return;
        } catch (RemoteException 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);
}
    可以看到一個重要的函數realStartActivityLocked,正如方法名字面上的意義,該方法是真正開啓Activity的地方。


12、ActivityStackSupervisor#realStartActivityLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java*/
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig)
        throws RemoteException {
    .....
    final ActivityStack stack = r.task.stack;
    try {
        if (app.thread == null) {
            throw new RemoteException();
        }
        ......

        ProfilerInfo profilerInfo = profileFile != null
                ? new ProfilerInfo(profileFile, profileFd, mService.mSamplingInterval,
                mService.mAutoStopProfiler) : null;
        app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);

        // 調用此函數來執行Activity的相關啓動工作,開啓Activity的生命週期
        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);

       .......

    } catch (RemoteException e) {

    }
    .......
    return true;
}
    執行Activity的Launch工作是通過調用app.thread.scheduleLaunchActivity實現的。

    app.thread是定義在ProcessRecord中的IApplicationThread類;而IApplicationThread是個接口,其具體實現類爲ApplicationThreadNative.類似於AIDL中的用法,thread的類型爲ApplicationThreadProxy的Binder代理對象。

13、IApplicationThread定義:

/** @path: frameworks\base\core\java\android\app\IApplicationThread.java*/
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,
                                String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
                                PersistableBundle persistentState, List<ResultInfo> pendingResults,
                                List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
                                ProfilerInfo profilerInfo) throws RemoteException;
    void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
                                  List<ReferrerIntent> pendingNewIntents, int configChanges,
                                  boolean notResumed, Configuration config) throws RemoteException;
    void scheduleNewIntent(List<ReferrerIntent> 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 scheduleCreateBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo,
                                   int backupMode) throws RemoteException;
    void scheduleDestroyBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo)
            throws RemoteException;
    void scheduleCreateService(IBinder token, ServiceInfo info,
                               CompatibilityInfo compatInfo, int processState) throws RemoteException;
    void scheduleBindService(IBinder token,
                             Intent intent, boolean rebind, int processState) throws RemoteException;
    void scheduleUnbindService(IBinder token,
                               Intent intent) throws RemoteException;
    void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
                             int flags, Intent args) throws RemoteException;
    void scheduleStopService(IBinder token) 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;
    void scheduleExit() throws RemoteException;
    void scheduleSuicide() throws RemoteException;
    void scheduleConfigurationChanged(Configuration config) throws RemoteException;
    void updateTimeZone() throws RemoteException;
    void clearDnsCache() throws RemoteException;
    void setHttpProxy(String proxy, String port, String exclList,
                      Uri pacFileUrl) throws RemoteException;
    void processInBackground() throws RemoteException;
    void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args)
            throws RemoteException;
    void dumpProvider(FileDescriptor fd, IBinder servicetoken, String[] args)
            throws RemoteException;
    void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
                                    int resultCode, String data, Bundle extras, boolean ordered,
                                    boolean sticky, int sendingUser, int processState) throws RemoteException;
    void scheduleLowMemory() throws RemoteException;
    void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
    void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType)
            throws RemoteException;
    void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd)
            throws RemoteException;
    void setSchedulingGroup(int group) throws RemoteException;
    void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException;
    void scheduleCrash(String msg) throws RemoteException;
    void dumpActivity(FileDescriptor fd, IBinder servicetoken, String prefix, String[] args)
            throws RemoteException;
    void setCoreSettings(Bundle coreSettings) throws RemoteException;
    void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException;
    void scheduleTrimMemory(int level) throws RemoteException;
    void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, boolean dumpInfo,
                     boolean dumpDalvik, String[] args) throws RemoteException;
    void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
    void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
    void unstableProviderDied(IBinder provider) throws RemoteException;
    void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, int requestType)
            throws RemoteException;
    void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
            throws RemoteException;
    void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options)
            throws RemoteException;
    void setProcessState(int state) throws RemoteException;
    void scheduleInstallProvider(ProviderInfo provider) throws RemoteException;
    void updateTimePrefs(boolean is24Hour) throws RemoteException;
    void scheduleCancelVisibleBehind(IBinder token) throws RemoteException;
    void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) throws RemoteException;
    void scheduleEnterAnimationComplete(IBinder token) throws RemoteException;

    String descriptor = "android.app.IApplicationThread";

    ......
}


    可以看到IApplicationThread中聲明瞭大量與Activity以及Service的啓動和停止相關的功能方法,其具體的實現類爲ApplicationThreadNative。ApplicationThread是ActivityThread中的內部類,其繼承實現了ApplicationThreadNative;

/** @path: frameworks\base\core\java\android\app\ActivityThread.java*/
private class ApplicationThread extends hust.testlearn.View.ApplicationThreadNative
/** @path: frameworks\base\core\java\android\app\ApplicationThreadNative.java*/
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
   ApplicationThreadProxy是ApplicationThreadNative的內部類。


14、ApplicationThreadProxy#ApplicationThreadNative:

/** @path: frameworks\base\core\java\android\app\ApplicationThreadNative.java*/
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                                         ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                                         String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
                                         PersistableBundle persistentState, List<ResultInfo> pendingResults,
                                         List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
                                         ProfilerInfo profilerInfo) throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(IApplicationThread.descriptor);
    intent.writeToParcel(data, 0);
    data.writeStrongBinder(token);
    data.writeInt(ident);
    info.writeToParcel(data, 0);
    curConfig.writeToParcel(data, 0);
    compatInfo.writeToParcel(data, 0);
    data.writeString(referrer);
    data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null);
    data.writeInt(procState);
    data.writeBundle(state);
    data.writePersistableBundle(persistentState);
    data.writeTypedList(pendingResults);
    data.writeTypedList(pendingNewIntents);
    data.writeInt(notResumed ? 1 : 0);
    data.writeInt(isForward ? 1 : 0);
    if (profilerInfo != null) {
        data.writeInt(1);
        profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
    } else {
        data.writeInt(0);
    }
    // 封裝相應的信息,通過AMS代理髮送類型爲SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION的IPC請求
    mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
            IBinder.FLAG_ONEWAY);
    data.recycle();
}
    Binder機制的用法,獲取AMS的代理,發送類型爲SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION的IPC請求。在本地,ApplicationThreadNative則通過以下的方法處理SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION類型的請求。


15、ApplicationThreadNative#onTransact:

/** @path: frameworks\base\core\java\android\app\ApplicationThreadNative.java*/
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
        .....
        case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            Intent intent = Intent.CREATOR.createFromParcel(data);
            IBinder b = data.readStrongBinder();
            int ident = data.readInt();
            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
            Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
            String referrer = data.readString();
            IVoiceInteractor voiceInteractor = IVoiceInteractor.Stub.asInterface(
                    data.readStrongBinder());
            int procState = data.readInt();
            Bundle state = data.readBundle();
            PersistableBundle persistentState = data.readPersistableBundle();
            List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
            List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR);
            boolean notResumed = data.readInt() != 0;
            boolean isForward = data.readInt() != 0;
            ProfilerInfo profilerInfo = data.readInt() != 0
                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
            
            // 具體處理啓動Activity功能的函數
            scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, referrer,
                    voiceInteractor, procState, state, persistentState, ri, pi,
                    notResumed, isForward, profilerInfo);
            return true;
        }
        .....
    }
}
具體的處理邏輯也就是恢復信息,最終調用scheduleLaunchActivity來完成啓動Activity的工作; scheduleLaunchActivity中具體的處理邏輯在ApplicationThread中實現。


16、ApplicationThread#scheduleLaunchActivity:

/** @path: frameworks\base\core\java\android\app\ActivityThread.java*/
private class ApplicationThread extends hust.testlearn.View.ApplicationThreadNative {

    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                                             ActivityInfo info, Configuration curConfig, 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對象
        ActivityClientRecord r = new ActivityClientRecord();

        r.token = token;
        r.ident = ident;
        r.intent = intent;
        r.referrer = referrer;
        r.voiceInteractor = voiceInteractor;
        r.activityInfo = info;
        r.compatInfo = compatInfo;
        r.state = state;
        r.persistentState = persistentState;

        r.pendingResults = pendingResults;
        r.pendingIntents = pendingNewIntents;

        r.startsNotResumed = notResumed;
        r.isForward = isForward;

        r.profilerInfo = profilerInfo;

        updatePendingConfiguration(curConfig);
        
        // 發送LAUNCH_ACTIVITY消息,交由H(Hanlder)進行處理
        sendMessage(H.LAUNCH_ACTIVITY, r);
    }

}
    上面的處理邏輯較爲簡單,通過解析獲得的數據封裝成一個ActivityRecord對象,然後交由Handler進行處理;


17、ActivityThread#sendMessage:

/** @path: frameworks\base\core\java\android\app\ActivityThread.java*/
final H mH = new H();
private void sendMessage(int what, Object obj) {
    sendMessage(what, obj, 0, 0, false);
}

private void sendMessage(int what, Object obj, int arg1) {
    sendMessage(what, obj, arg1, 0, false);
}

private void sendMessage(int what, Object obj, int arg1, int arg2) {
    sendMessage(what, obj, arg1, arg2, false);
}

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}
    sendMessage邏輯較爲簡單,簡單的Hanlder消息發送機制,mH的類型是H,H是ActivityThread的內部類,繼承了Handler,下面深入到H類中去具體來看其處理邏輯;這裏發送的what類型是LAUNCH_ACTIVITY。


18、H:

/** @path: frameworks\base\core\java\android\app\ActivityThread.java*/
private class H extends Handler {
    public static final int LAUNCH_ACTIVITY = 100;
    public static final int PAUSE_ACTIVITY          = 101;
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
                final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                r.packageInfo = getPackageInfoNoCheck(
                        r.activityInfo.applicationInfo, r.compatInfo);
                handleLaunchActivity(r, null);
            }
            break;
            case PAUSE_ACTIVITY:
                handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
                        (msg.arg1&2) != 0);
                maybeSnapshot();
                break;
            ......
        }
    }
}
     可以看到處理LAUNCH_ACTIVITY事件的方法爲handleLaunchActivity方法;碰到了熟悉的函數,Activity的啓動過程則從此進行,下面的啓動過程:Android View機制深入學習(一)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章