Android Activity是如何啟動的?Activity的生命週期是如何呼叫的?

浩宇碧海發表於2018-06-12

AndroidActivity 是如何啟動的?
Activity的生命週期是如何呼叫的?

在Android中有一個ActivityThread類,這個可以看成是app的主執行緒類,在Java中我們啟動程式的入口是 main()方法,在Android中,APP啟動時,會呼叫ctivityThread中的main()方法。

  public static void main(String[] args) {
        Trace.traceBegin(64L, "ActivityThreadMain");
        CloseGuard.setEnabled(false);
        Environment.initForCurrentUser();
        EventLogger.setReporter(new ActivityThread.EventLoggingReporter(null));
        File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
        Process.setArgV0("<pre-initialized>");
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        Trace.traceEnd(64L);
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
複製程式碼

這裡重點看兩點:

  1. Looper.prepareMainLooper();
    Looper.loop();
    開啟一個Looper,進行訊息輪詢。負責傳送訊息。
  2. 建立一個ActivityThread 並呼叫了attach()方法。
ActivityThread thread = new ActivityThread();
thread.attach(false);
複製程式碼

attach()

private void attach(boolean system) {
            ...
            final IActivityManager mgr = ActivityManager.getService();

            try {
                mgr.attachApplication(this.mAppThread);
            } catch (RemoteException var5) {
                throw var5.rethrowFromSystemServer();
            }

            ...
    
    }

複製程式碼

這裡我們只看關鍵程式碼,通過ActivityManager.getService(),生成一個IActivityManager的物件,我們接下來看

ActivityManager.getService()

 public static IActivityManager getService() {
        return (IActivityManager)IActivityManagerSingleton.get();
    }
    
    private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            IActivityManager am = Stub.asInterface(b);
            return am;
        }
    };

複製程式碼

這裡我們看到通過ServiceManager.getService()生成一個Binder,然後通過binder介面通訊。最後將生成的ActivityManager返回出去,ActivityManager是由系統服務所呼叫管理,並且通過在binder介面當中進行呼叫。
接著我們看attach()中的attachApplication(this.mAppThread); 這裡的mAppThread是: final ActivityThread.ApplicationThread mAppThread = new ActivityThread.ApplicationThread(null); 再看一下ApplicationThread 這是一個ActivityThread的內部類。


    private class ApplicationThread extends android.app.IApplicationThread.Stub {
        ...
        }


public interface IApplicationThread extends IInterface {
    void schedulePauseActivity(IBinder var1, boolean var2, boolean var3, int var4, boolean var5) throws RemoteException;

    void scheduleStopActivity(IBinder var1, boolean var2, int var3) throws RemoteException;

    void scheduleWindowVisibility(IBinder var1, boolean var2) throws RemoteException;

    void scheduleResumeActivity(IBinder var1, int var2, boolean var3, Bundle var4) throws RemoteException;

    void scheduleSendResult(IBinder var1, List<ResultInfo> var2) throws RemoteException;

    void scheduleLaunchActivity(Intent var1, IBinder var2, int var3, ActivityInfo var4, Configuration var5, Configuration var6, CompatibilityInfo var7, String var8, IVoiceInteractor var9, int var10, Bundle var11, PersistableBundle var12, List<ResultInfo> var13, List<ReferrerIntent> var14, boolean var15, boolean var16, ProfilerInfo var17) throws RemoteException;

    void scheduleNewIntent(List<ReferrerIntent> var1, IBinder var2, boolean var3) throws RemoteException;

    void scheduleDestroyActivity(IBinder var1, boolean var2, int var3) throws RemoteException;

    void scheduleReceiver(Intent var1, ActivityInfo var2, CompatibilityInfo var3, int var4, String var5, Bundle var6, boolean var7, int var8, int var9) throws RemoteException;

    void scheduleCreateService(IBinder var1, ServiceInfo var2, CompatibilityInfo var3, int var4) throws RemoteException;

    void scheduleStopService(IBinder var1) throws RemoteException;

    void bindApplication(String var1, ApplicationInfo var2, List<ProviderInfo> var3, ComponentName var4, ProfilerInfo var5, Bundle var6, IInstrumentationWatcher var7, IUiAutomationConnection var8, int var9, boolean var10, boolean var11, boolean var12, boolean var13, Configuration var14, CompatibilityInfo var15, Map var16, Bundle var17, String var18) throws RemoteException;

    void scheduleExit() throws RemoteException;

    void scheduleConfigurationChanged(Configuration var1) throws RemoteException;

    void scheduleServiceArgs(IBinder var1, ParceledListSlice var2) throws RemoteException;

    void updateTimeZone() throws RemoteException;

    void processInBackground() throws RemoteException;

    void scheduleBindService(IBinder var1, Intent var2, boolean var3, int var4) throws RemoteException;

    void scheduleUnbindService(IBinder var1, Intent var2) throws RemoteException;

    void dumpService(ParcelFileDescriptor var1, IBinder var2, String[] var3) throws RemoteException;

    void scheduleRegisteredReceiver(IIntentReceiver var1, Intent var2, int var3, String var4, Bundle var5, boolean var6, boolean var7, int var8, int var9) throws RemoteException;

    void scheduleLowMemory() throws RemoteException;

    void scheduleActivityConfigurationChanged(IBinder var1, Configuration var2) throws RemoteException;

    void scheduleActivityMovedToDisplay(IBinder var1, int var2, Configuration var3) throws RemoteException;

    void scheduleRelaunchActivity(IBinder var1, List<ResultInfo> var2, List<ReferrerIntent> var3, int var4, boolean var5, Configuration var6, Configuration var7, boolean var8) throws RemoteException;

    void scheduleSleeping(IBinder var1, boolean var2) throws RemoteException;

    void profilerControl(boolean var1, ProfilerInfo var2, int var3) throws RemoteException;

    void setSchedulingGroup(int var1) throws RemoteException;

    void scheduleCreateBackupAgent(ApplicationInfo var1, CompatibilityInfo var2, int var3) throws RemoteException;

    void scheduleDestroyBackupAgent(ApplicationInfo var1, CompatibilityInfo var2) throws RemoteException;

    void scheduleOnNewActivityOptions(IBinder var1, Bundle var2) throws RemoteException;

    void scheduleSuicide() throws RemoteException;

    void dispatchPackageBroadcast(int var1, String[] var2) throws RemoteException;

    void scheduleCrash(String var1) throws RemoteException;

    void dumpHeap(boolean var1, boolean var2, boolean var3, String var4, ParcelFileDescriptor var5) throws RemoteException;

    void dumpActivity(ParcelFileDescriptor var1, IBinder var2, String var3, String[] var4) throws RemoteException;

    void clearDnsCache() throws RemoteException;

    void setHttpProxy(String var1, String var2, String var3, Uri var4) throws RemoteException;

    void setCoreSettings(Bundle var1) throws RemoteException;

    void updatePackageCompatibilityInfo(String var1, CompatibilityInfo var2) throws RemoteException;

    void scheduleTrimMemory(int var1) throws RemoteException;

    void dumpMemInfo(ParcelFileDescriptor var1, MemoryInfo var2, boolean var3, boolean var4, boolean var5, boolean var6, boolean var7, String[] var8) throws RemoteException;

    void dumpGfxInfo(ParcelFileDescriptor var1, String[] var2) throws RemoteException;

    void dumpProvider(ParcelFileDescriptor var1, IBinder var2, String[] var3) throws RemoteException;

    void dumpDbInfo(ParcelFileDescriptor var1, String[] var2) throws RemoteException;

    void unstableProviderDied(IBinder var1) throws RemoteException;

    void requestAssistContextExtras(IBinder var1, IBinder var2, int var3, int var4, int var5) throws RemoteException;

    void scheduleTranslucentConversionComplete(IBinder var1, boolean var2) throws RemoteException;

    void setProcessState(int var1) throws RemoteException;

    void scheduleInstallProvider(ProviderInfo var1) throws RemoteException;

    void updateTimePrefs(int var1) throws RemoteException;

    void scheduleEnterAnimationComplete(IBinder var1) throws RemoteException;

    void notifyCleartextNetwork(byte[] var1) throws RemoteException;

    void startBinderTracking() throws RemoteException;

    void stopBinderTrackingAndDump(ParcelFileDescriptor var1) throws RemoteException;

    void scheduleMultiWindowModeChanged(IBinder var1, boolean var2, Configuration var3) throws RemoteException;

    void schedulePictureInPictureModeChanged(IBinder var1, boolean var2, Configuration var3) throws RemoteException;

    void scheduleLocalVoiceInteractionStarted(IBinder var1, IVoiceInteractor var2) throws RemoteException;

    void handleTrustStorageUpdate() throws RemoteException;

    void attachAgent(String var1) throws RemoteException;

    void scheduleApplicationInfoChanged(ApplicationInfo var1) throws RemoteException;

    void setNetworkBlockSeq(long var1) throws RemoteException;


public abstract static class Stub extends Binder implements IApplicationThread {
複製程式碼

可以看到ApplicationThread繼承自IApplicationThread.Stub,來實現管理activity生命週期的類。 attachApplication在這裡的作用其實實際上是ActivityThread通過attach獲取到,然後將applciationThread將其關聯,把activity相關資訊儲存在applciationThread裡面,apllicationThread的類為activity的各種狀態做了相對應的準備工作。


當我們開啟ApplicationThread中我們會看到一堆的schedle方法,這些方法的名稱其實就可以給我們表明,代表的是在執行Activity的某種狀態時呼叫的計劃執行方法

這時我們會看到一個scheduleLaunchActivity方法,表示計劃載入時呼叫的

     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) {
            this.updateProcessState(procState, false);
            ActivityThread.ActivityClientRecord r = new ActivityThread.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;
            this.updatePendingConfiguration(curConfig);
            ActivityThread.this.sendMessage(H.LAUNCH_ACTIVITY, r);
        }
        
        
    private class H extends Handler {
        public static final int LAUNCH_ACTIVITY = 100;

複製程式碼

最後我們看見ActivityThread.this.sendMessage(100, r);通過handler傳送了一個訊息 LAUNCH_ACTIVITY 這裡就是啟動activity了 我們看handleMessage()的 handleLaunchActivity()方法

 public void handleMessage(Message msg) {
            ActivityThread.ActivityClientRecord r;
            SomeArgs args;
            switch(msg.what) {
            case 100:
                Trace.traceBegin(64L, "activityStart");
                r = (ActivityThread.ActivityClientRecord)msg.obj;
                r.packageInfo = ActivityThread.this.getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
                ActivityThread.this.handleLaunchActivity(r, (Intent)null, "LAUNCH_ACTIVITY");
                Trace.traceEnd(64L);
                break;
                ...
              }
              }
   
    private void handleLaunchActivity(ActivityThread.ActivityClientRecord r, Intent customIntent, String reason) {
        this.unscheduleGcIdler();
        this.mSomeActivitiesChanged = true;
        if (r.profilerInfo != null) {
            this.mProfiler.setProfiler(r.profilerInfo);
            this.mProfiler.startProfiling();
        }

        this.handleConfigurationChanged((Configuration)null, (CompatibilityInfo)null);
        if (!ThreadedRenderer.sRendererDisabled) {
            GraphicsEnvironment.earlyInitEGL();
        }

        WindowManagerGlobal.initialize();
        Activity a = this.performLaunchActivity(r, customIntent);
        if (a != null) {
            r.createdConfig = new Configuration(this.mConfiguration);
            this.reportSizeConfigurations(r);
            Bundle oldState = r.state;
            this.handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
            if (!r.activity.mFinished && r.startsNotResumed) {
                this.performPauseActivityIfNeeded(r, reason);
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        } else {
            try {
                ActivityManager.getService().finishActivity(r.token, 0, (Intent)null, 0);
            } catch (RemoteException var6) {
                throw var6.rethrowFromSystemServer();
            }
        }

    }
複製程式碼

上面我們看到Activity a = this.performLaunchActivity(r, customIntent);


    private Activity performLaunchActivity(ActivityThread.ActivityClientRecord r, Intent customIntent) {
        ...
        Activity activity = null;

        try {
            ClassLoader cl = appContext.getClassLoader();
            activity = this.mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
        ...
        }

        try {
          ...
                activity.mCalled = false;
                if (r.isPersistable()) {
                    this.mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    this.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.performStart();
                    r.stopped = false;
                }

                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            this.mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, r.persistentState);
                        }
                    } else if (r.state != null) {
                        this.mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }

                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        this.mInstrumentation.callActivityOnPostCreate(activity, r.state, r.persistentState);
                    } else {
                        this.mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }

                    if (!activity.mCalled) {
                        throw new SuperNotCalledException("Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPostCreate()");
                    }
                }
            }
            ...
        }

        return activity;
    }

複製程式碼

到此我們看到,根據不同情況來呼叫activity不同的生命週期的方法。

總結:

Application執行的過程當中,對於Activity的操作,狀態轉變,其實實際上是通過Handler訊息機制來完成的,

Application當中只管去發, 由訊息機制負責呼叫,因為在main方法當中我門的Looper輪訓器是一直在進行輪訓的

而當我們在載入Activity的時候,當中呼叫了一個performLaunchActivity()方法,在這個中間我發現了我們onCreate的呼叫痕跡。

參考:原文傳送門,感謝BarryKerwin 老師。留做筆記使用。

相關文章