Android源碼解析四大組件系列(四)---Activity啟動詳細流程

轉載請注明文章出處LooperJing

在上一篇博客http://m.itdecent.cn/p/98fa08ee1bfb,我們起碼知道了Zygote是怎么啟動SystemServer進程的,AMS是怎么注冊的,啟動的,啟動之后通過Socket怎樣與Zygote進程通信的,而Zygote進程收到AMS的請求之后,是怎么fork進程,將ActivityThread的main方法是執(zhí)行起來的。這些內容在我的前兩篇博客都梳理過,建議閱讀一下,在看本文。

一、Activity請求啟動

啟動Activity的方式

我們以startActivity這種來分析

Intent intent=new Intent(MainActivity.this,TargetActivity.class);
startActivity(intent);

經(jīng)過startActivity-->startActivityForResult-->execStartActivity,最終會調用Instrumentation的execStartActivity方法。

public ActivityResult execStartActivity(
           Context who, IBinder contextThread, IBinder token, Activity target,
           Intent intent, int requestCode, Bundle options) {
       IApplicationThread whoThread = (IApplicationThread) contextThread;
       Uri referrer = target != null ? target.onProvideReferrer() : null;
       if (referrer != null) {
           intent.putExtra(Intent.EXTRA_REFERRER, referrer);
       }
      .....
       
       try {
           intent.migrateExtraStreamToClipData();
           intent.prepareToLeaveProcess(who);
           //獲取AMS的代理,啟動Activity
           int result = ActivityManagerNative.getDefault()
               .startActivity(whoThread, who.getBasePackageName(), intent,
                       intent.resolveTypeIfNeeded(who.getContentResolver()),
                       token, target != null ? target.mEmbeddedID : null,
                       requestCode, 0, null, options);
       
           //檢查Activity是否啟動成功,若失敗給出是什么原因
           checkStartActivityResult(result, intent);
       } catch (RemoteException e) {
           throw new RuntimeException("Failure from system", e);
       }
       return null;
     
   }

這些參數(shù)的意思是

  • this,為啟動Activity的對象;
  • contextThread,為Binder對象,是主進程的context對象;
  • token,也是一個Binder對象,指向了服務端一個ActivityRecord對象;
  • target,為啟動的Activity;
  • intent,啟動的Intent對象;
  • requestCode,請求碼;
  • options,參數(shù);

先看checkStartActivityResult方法的實現(xiàn)

 public static void checkStartActivityResult(int res, Object intent) {
        if (res >= ActivityManager.START_SUCCESS) {
            return;
        }

        switch (res) {
            case ActivityManager.START_INTENT_NOT_RESOLVED:
            case ActivityManager.START_CLASS_NOT_FOUND:
                if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + ((Intent)intent).getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case ActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            case ActivityManager.START_NOT_ACTIVITY:
                throw new IllegalArgumentException(
                        "PendingIntent is not an activity");
            case ActivityManager.START_NOT_VOICE_COMPATIBLE:
                throw new SecurityException(
                        "Starting under voice control not allowed for: " + intent);
            case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
                throw new IllegalStateException(
                        "Session calling startVoiceActivity does not match active session");
            case ActivityManager.START_VOICE_HIDDEN_SESSION:
                throw new IllegalStateException(
                        "Cannot start voice activity on a hidden session");
            case ActivityManager.START_CANCELED:
                throw new AndroidRuntimeException("Activity could not be started for "
                        + intent);
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
    }
     ```
常見的ActivityNotFoundException,SecurityException等錯日志就在這里報出來的。


OK,現(xiàn)在回到execStartActivity,內部調用了ActivityManagerNative.getDefault().startActivity,關于ActivityManagerNative已經(jīng)說了很多了,相當于AMS服務端存根或者代理,其客戶端是ActivityManagerNative的內部類ActivityManagerProxy,這里getDefault獲取的就是ActivityManagerProxy對象,通過ActivityManagerProxy對象來使用AMS內部的一些服務,包括單不限于啟動Activity。所以通過ActivityManagerProxy對象調用startActivity方法的實質是調用BinderProxy.transact向Binder驅動發(fā)送START_ACTIVITY_TRACSACTION命令,binder驅動將處理邏輯從Launcher所在的進程切換到AMS所在的SystemServer進程。OK,我們直接看ActivityManagerService的startActivity方法,不明白,建議看一下Binder的通信原理。



####二、AMS處理Activity的啟動請求


#####2.1、AMS處理Activity的啟動請求
@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());
}
保持篇幅,以下步驟省略。
ActvityiManagerService.startActivityAsUser() 
ActivityStackSupervisor.startActivityMayWait() 
ActivityStackSupervisor.startActivityLocked() 
ActivityStackSupervisor.startActivityUncheckedLocked() 
ActivityStackSupervisor.startActivityLocked() 
ActivityStackSupervisor.resumeTopActivitiesLocked() 
ActivityStackSupervisor.resumeTopActivityInnerLocked() 


在resumeTopActivityInnerLocked的內部有如下代碼。

if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}

這表明在啟動一個Activity的時候,前面一個Activity要執(zhí)行onPause方法,onPause方法是怎么調用的呢?

#####2.2、AMS調用棧頂Activity的onPause

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
boolean dontWait) {
......
if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
prev.updateThumbnailLocked(screenshotActivities(prev), null);
}
stopFullyDrawnTraceIfNeeded();

    mService.updateCpuStats();

    if (prev.app != null && prev.app.thread != null) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
        try {
           //調用ApplicationThread的schedulePauseActivity
            prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                    userLeaving, prev.configChangeFlags, dontWait);
        } catch (Exception e) {
         ......
        }
    }

   ......
}
這里先留一個問題, 我知道prev.app.thread是ApplicationThreadProxy對象,實際是調用了ApplicationThread的schedulePauseActivity方法,但是**AMS是怎么獲取到prev.app.thread的呢?**


public final void schedulePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport) {
        sendMessage(
                finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                token,
                (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
                configChanges);
    }
關鍵就是最后調用了sendMessage(H.BIND_APPLICATION, data),發(fā)送了消息。關于H這個類,其實是個Hander,我覺得它的作用就像是一個交通樞紐。對這個H想更詳細了解的,詳細[戳我](http://m.itdecent.cn/p/325d3cd79fd5)。H接收到這個Message之后,調用

handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2, (msg.arg1&2) != 0);


private void handlePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport) {
    ActivityClientRecord r = mActivities.get(token);
        .......
        r.activity.mConfigChangeFlags |= configChanges;
        performPauseActivity(token, finished, r.isPreHoneycomb());
        .......

        // Tell the activity manager we have paused.
        if (!dontReport) {
            try {
                ActivityManagerNative.getDefault().activityPaused(token);
            } catch (RemoteException ex) {
            }
        }
        mSomeActivitiesChanged = true;
    }
}

final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
        boolean saveState) {
    if (r.paused) {
     .......
    try {
      .......
        //調用Instrumentation的callActivityOnPause方法
        mInstrumentation.callActivityOnPause(r.activity);
        EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
                r.activity.getComponentName().getClassName());
        if (!r.activity.mCalled) {
            throw new SuperNotCalledException(
                "Activity " + r.intent.getComponent().toShortString() +
                " did not call through to super.onPause()");
        }

    } catch (SuperNotCalledException e) {
        throw e;

    } catch (Exception e) {
        .......
        }
    }
    r.paused = true;

     .......
    return !r.activity.mFinished && saveState ? r.state : null;
}

public void callActivityOnPause(Activity activity) {
activity.performPause();
}


final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
//onPause執(zhí)行
onPause();
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
mResumed = false;
}



分析到這里  onPause()終于執(zhí)行了?;氐? handlePauseActivity方法中,在這個方法最后調用了ActivityManagerNative.getDefault().activityPaused(token)

#####2.3、ActivityManagerService的activityPaused方法執(zhí)行。

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

經(jīng)過一些方法,最終會調用startSpecificActivityLocked
ActivityStack.activityPausedLocked()
ActivityStack.completePauseLocked()
ActivityStackSupervisor.resumeTopActivitiesLocked()
ActivityStack.resumeTopActivityLocked()
ActivityStack.resumeTopActivityInnerLocked ()
ActivityStack.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所需要的應用進程是否已經(jīng)啟動,如果沒有則執(zhí)行realStartActivityLocked去啟動Activity,否則去啟動啟動應用進程,相當于一個預啟動的過程。


#####2.4、應用進程創(chuàng)建
關于startProcessLocked怎么執(zhí)行的,上篇博客分析過,SystemServer進程中Ams通過Socket與Zygote進程進行通信的,Zygote接收到AMS發(fā)起的創(chuàng)建進程的請求,會fork出一個子進程,并且反射調用這個進程中ActivityThread的main方法。詳情步驟[戳我](http://m.itdecent.cn/p/98fa08ee1bfb),在應用進程啟動之后,ActivityThread的main方法就開始執(zhí)行了。



####三、ActivityThread的main方法執(zhí)行


在ActivityThread的main方法里調用thread.attach(false);

public static void main(String[] args) {
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    SamplingProfilerIntegration.start();
    ......

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

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}


對于上面main方法,相信很多人都看多很多遍了,接下來重點分析  thread.attach(false)這行代碼。

private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
.......

    //獲取ActivityManagerService在客戶端的代理
        IActivityManager mgr = ActivityManagerNative.getDefault();
        try {

    //實質是調用ActivityManagerService的attachApplication方法,目的是讓ActivityManagerService通過ApplicationThread代理對象控制應用進程
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
        }
    }
.......
}

在調用  mgr.attachApplication()的時候,將mAppThread對象傳進去了。

final ApplicationThread mAppThread = new ApplicationThread();


ApplicationThread繼承了ApplicationThreadNative, 看一下ApplicationThreadNative里面的方法。

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1836169-9c2353efc74864e6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


內部調用了ActivityManagerNative.getDefault() .attachApplication,關于ActivityManagerNative已經(jīng)說了很多了,相當于AMS服務端存根或者代理,其客戶端是ActivityManagerNative的內部類ActivityManagerProxy,這里getDefault獲取的就是ActivityManagerProxy對象,通過ActivityManagerProxy對象來使用AMS內部的一些服務,包括單不限于啟動Activity。所以通過ActivityManagerProxy對象調用attachApplication方法的實質是調用BinderProxy.transact向Binder驅動發(fā)送ATTACH_APPLICATION_TRANSACTION命令,binder驅動將處理邏輯從APP應用進程所在的進程切換到AMS所在的SystemServer進程。OK,我們直接看ActivityManagerService的attachApplication方法:
@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
//通過進程ID,獲取進程的記錄信息
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}

    if (app == null) {
        Slog.w(TAG, "No pending application record for pid " + pid
                + " (IApplicationThread " + thread + "); dropping process");
        EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
        if (pid > 0 && pid != MY_PID) {
            //如果沒有獲取到,需要殺死該進程,MY_PID是系統(tǒng)進程
            Process.killProcessQuiet(pid);
         
        } else {
             ......
        return false;
    }

    ......
//獲取進程名稱
    final String processName = app.processName;
    try {
        AppDeathRecipient adr = new AppDeathRecipient(
                app, pid, thread);
        thread.asBinder().linkToDeath(adr, 0);
        app.deathRecipient = adr;
    } catch (RemoteException e) {
        app.resetPackageList(mProcessStats);
        startProcessLocked(app, "link fail", processName);
        return false;
    }

    EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);

//設置進程的OOM,adj等值

    //還記得上面留下的那個問題嗎,AMS是怎么獲取到prev.app.thread的呢?就在這,prev.app是ProcessRecord對象,makeActive內部將thread對象賦值給prev.app.thread??梢宰约翰殚啠@樣AMS是可以查詢進程記錄的,進程記錄中就有一個app.thread,若AMS要跟Activity通信直接獲取prev.app.thread就可以了。
    app.makeActive(thread, mProcessStats);
    app.curAdj = app.setAdj = -100;
    app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
    app.forcingToForeground = null;
    updateProcessForegroundLocked(app, false, false);
    app.hasShownUi = false;
    app.debugging = false;
    app.cached = false;
    app.killedByAm = false;

    //將attach之前的超時Meessage移除掉
    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);

    boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
    List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;

      ......
    try {
      ......
        thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                isRestrictedBackupMode || !normalMode, app.persistent,
                new Configuration(mConfiguration), app.compat,
                getCommonServicesLocked(app.isolated),
                mCoreSettingsObserver.getCoreSettingsLocked());
        updateLruProcessLocked(app, false, null);
        app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    } catch (Exception e) {
        // todo: Yikes!  What should we do?  For now we will try to
        // start another process, but that could easily get us in
        // an infinite loop of restarting processes...
        Slog.wtf(TAG, "Exception thrown during bind of " + app, e);

        app.resetPackageList(mProcessStats);
        app.unlinkDeathRecipient();
        startProcessLocked(app, "bind fail", processName);
        return false;
    }

   ......

// See if the top visible activity is waiting to run in this process...
    if (normalMode) {
        try {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }

    // 執(zhí)行等待進程而暫時掛起的Service
    if (!badApp) {
        try {
            didSomething |= mServices.attachApplicationLocked(app, processName);
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
            badApp = true;
        }
    }

    // 執(zhí)行等待進程而暫時掛起的廣播
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        try {
            didSomething |= sendPendingBroadcastsLocked(app);
        } catch (Exception e) {
            // If the app died trying to launch the receiver we declare it 'bad'
            Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
            badApp = true;
        }
    }



    ......

    if (!didSomething) {
    //調整進程優(yōu)先級adj的值
        updateOomAdjLocked();
    }

    return true;
}
發(fā)現(xiàn)AMS用IApplicationThread對象thread調用了bindApplication,thread實際上就是ApplicationThreadProxy對象。AMS通過ApplicationThreadProxy對象與ActivityThread通信。所以去ApplicationThread中看bindApplication的真正實現(xiàn)。

public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {

        if (services != null) {
            // Setup the service cache in the ServiceManager
            ServiceManager.initServiceCache(services);
        }

        setCoreSettings(coreSettings);
        ......
        AppBindData data = new AppBindData();
        data.processName = processName;
        data.appInfo = appInfo;
        data.providers = providers;
        data.instrumentationName = instrumentationName;
        data.instrumentationArgs = instrumentationArgs;
        data.instrumentationWatcher = instrumentationWatcher;
        data.instrumentationUiAutomationConnection = instrumentationUiConnection;
        data.debugMode = debugMode;
        data.enableOpenGlTrace = enableOpenGlTrace;
        data.restrictedBackupMode = isRestrictedBackupMode;
        data.persistent = persistent;
        data.config = config;
        data.compatInfo = compatInfo;
        data.initProfilerInfo = profilerInfo;
        sendMessage(H.BIND_APPLICATION, data);
    }
這里又是用H發(fā)送了一個消息,是不是很像一個交通樞紐,做轉發(fā)用的。詳細[戳我](http://m.itdecent.cn/p/325d3cd79fd5)。
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");

AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

handleBindApplication內部就不分析了,Applcation對象的onCreate方法調用就是在這里面,它內部創(chuàng)建了Applcation對象。



####四、Activity周期如何執(zhí)行

#####、4.1、Activity的onCreate是怎么回調的
回到第二小節(jié)的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)) {
      
                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);
}
在預啟動之后,一般我們的應用進程就被孵化來了,直接執(zhí)行realStartActivityLocked去啟動Activity。


在realStartActivityLocked內部調用了如下代碼,現(xiàn)在你應該知道   app.thread是什么了。

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);


直接到scheduleLaunchActivity真正實現(xiàn),它的真正實現(xiàn)是在Applciation中的。

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

        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;

        r.overrideConfig = overrideConfig;
        updatePendingConfiguration(curConfig);

        sendMessage(H.LAUNCH_ACTIVITY, r);
    }

經(jīng)過一堆的變量賦值之后,又通過H發(fā)送了一個消息LAUNCH_ACTIVITY,H在收到這個消息之后,執(zhí)行下面。

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




private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;

    if (r.profilerInfo != null) {
        mProfiler.setProfiler(r.profilerInfo);
        mProfiler.startProfiling();
    }

    // Make sure we are running with the most recent config.
    handleConfigurationChanged(null, null);

    if (localLOGV) Slog.v(
        TAG, "Handling launch of " + r);

    // Initialize before creating the activity
    WindowManagerGlobal.initialize();

     //一個 perform開頭的方法,啟動Activity
    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        Bundle oldState = r.state;
        //Launch
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed);

        if (!r.activity.mFinished && r.startsNotResumed) {
       
            try {
                r.activity.mCalled = false;
                
                mInstrumentation.callActivityOnPause(r.activity);
      
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
                if (!r.activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onPause()");
                }

            } catch (SuperNotCalledException e) {
                throw e;

            } catch (Exception e) {
                 .....
            }
            r.paused = true;
        }
     .....
    }
}

這個方法會將Activity創(chuàng)建出來。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

    ActivityInfo aInfo = r.activityInfo;
     r.activityInfo.targetActivity);
 
    ......
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
      .......
    } catch (Exception e) {
         .......
    }
    
   Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
    if (activity != null) {     
    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的create方法執(zhí)行
      if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }

.......

    r.activity = activity;
            r.stopped = true;
            if (!r.activity.mFinished) {
            //Activity的start方法執(zhí)行
                activity.performStart();
                r.stopped = false;
            }
    mActivities.put(r.token, r);

    return activity;
}

反射創(chuàng)建Activity,為啥要用反射呢,此處搞不清楚。
public Activity newActivity(ClassLoader cl, String className,
        Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    return (Activity)cl.loadClass(className).newInstance();
}

解析來mInstrumentation調用callActivityOnCreate方法。

public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}


final void performCreate(Bundle icicle) {
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}


onCreate方法在此處被調用了。

#####4.2、Activity的onStart是怎么回調的

在performLaunchActivity中調用了callActivityOnCreate之后,又會調用   activity.performStart()

final void performStart() {
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
mFragments.noteStateNotSaved();
mCalled = false;
mFragments.execPendingActions();
mInstrumentation.callActivityOnStart(this);
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStart()");
}
mFragments.dispatchStart();
mFragments.reportLoaderStart();
mActivityTransitionState.enterReady(this);
}


public void callActivityOnStart(Activity activity) {
activity.onStart();
}

到此處start方法又被調用了。

#####4.3、Activity的onResume是怎么回調的

handleLaunchActivity方法中,在調用performLaunchActivity之后,調用了handleResumeActivity方法。

ActivityThread.handleResumeActivity()
ActivityThread.handleResumeActivity()
Activity.performResume()
Instrumentation.callActivityOnResume();


public void callActivityOnResume(Activity activity) {
    activity.mResumed = true;
    activity.onResume();
    
    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                am.match(activity, activity, activity.getIntent());
            }
        }
    }
}
到此Activity的onResume方法被調用,onPause方法已經(jīng)講解過,關于onStop,onDestory一樣的套路分析。


#####五、總結
關于Activity的啟動過程分析,三篇文章都分析完了,現(xiàn)在以一張圖總結一下。



![](http://upload-images.jianshu.io/upload_images/1836169-08a3c6f594f9ae9d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

- 啟動一個Activity的方式有多種,都是通過向Ams發(fā)送startActivity請求

- Ams在啟動Activity的時候,會判斷目標進程有沒有被創(chuàng)建,沒有創(chuàng)建的話,向zygote進程發(fā)送創(chuàng)建進程的請求;

- Zygote進程fork出新的子進程,即App進程;

- App進程,通過Binder IPC向sytem_server進程發(fā)起attachApplication請求;

- AMS所在的SystemServer進程在收到請求后,進行一系列準備工作后,再通過binder IPC向App進程發(fā)送scheduleLaunchActivity請求;

- App進程的binder線程(ApplicationThread)在收到請求后,通過handler向主線程發(fā)送LAUNCH_ACTIVITY消息;

- 主線程在收到Message后,通過發(fā)射機制創(chuàng)建目標Activity,并回調Activity.onCreate()等方法。

上圖大致說明了一個Activity的啟動流程,  重點在于把握Binder的通信原理,接著弄清楚APP進程,SystemServer進程,Zygote進程是怎么互相通信的。seeyou!


參考博客:
http://gityuan.com/2016/03/12/start-activity/
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容