天天看點

activity啟動流程_App 啟動流程分析

activity啟動流程_App 啟動流程分析

App 啟動流程分析

Android中每一個App都在一個獨立的空間,運作在一個單獨的程序中,擁有一個vm,系統會配置設定一個唯一的user ID 如

u0_a30

,用來實作沙盒目錄。

init程序會啟動一個"Zygote"程序. 這個程序初始化了第一個VM, 并且預加載了framework和衆多App所需要的通用資源. 然後它開啟一個Socket接口來監聽請求, 根據請求孵化出新的VM來管理新的App程序. 一旦收到新的請求, Zygote會基于自身預先加載的VM來孵化出一個新的VM建立一個新的程序. Zygote還會孵化出一個超級管理程序---System Server. SystemServer會啟動所有系統核心服務: 引導服務(7個):ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService、PackageManagerService、UserManagerService、SensorService; 核心服務(3個):BatteryService、UsageStatsService、WebViewUpdateService; 其他服務(70個+):AlarmManagerService、VibratorService等。

啟動App流程

啟動一個App的方式
Intent intent = packageManager.getLaunchIntentForPackage(packname);
startActivity(intent);
或者
ComponentName cn = new ComponentName("com.example", "com.example.MainActivity");
startActivity(intent);
           

啟動一個應用時:都會調用startActivity(Intent)

Activity.startActivity

```
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
}

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
            // 忽略...
            // 這裡mMainThread也是Activity類的成員變量,它的類型是ActivityThread,
            // token是表示Activity
            Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
            // 忽略...
        }
```
           

這裡mMainThread也是Activity類的成員變量,它的類型是ActivityThread,mMainThread.getApplicationThread獲得它裡面的ApplicationThread成員變量,這個ApplicationThread實際上是一個Binder對象,是App所在的程序與AMS所在程序system_server通信的橋梁。 1. AMS會對Activity生命周期的管理以及任務棧的管理,通過Binder通信,這時AMS是Server端,App程序持有AMS的client端IActivityManagerSingleton進行通信 2. AMS在完成任務棧和生命周期管理後,回調App方法,這時AMS是client持有App的ApplicationThread進行通信

mToken是Activity中一個成員變量,AMS和Activity互動中并沒有把Activity執行個體傳入,而是使用mToken,可以唯一标示Activity。

Instrumentation.execStartActivity

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

        // Binder對象,把這個句柄傳給AMS,用來回調App程序方法
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        // 忽略..
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .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;
    }
           

這裡把App中Binder的Server端的ApplicationThread的句柄傳給AMS,用于生命周期的回調等,如onPause。 通過Binder驅動,就進入過AMS的startActivity方法

ActivityManagerService 通知目前程序進入pause狀态

AMS在system_server程序中,由于AMS中代碼太多了,我們這裡就不全部展開講了,大概的說一下。有興趣的可以去看一下老羅的文章。 在AMS會新建立一個棧Task,并通過ApplicationThread的句柄通知目前Activity進入paused狀态

回到ActivityThread中

public final class ActivityThread {
    // ......
    private class ApplicationThread extends IApplicationThread.Stub {
        // ......
        public final void schedulePauseActivity(IBinder token, boolean finished,
                    boolean userLeaving, int configChanges, boolean dontReport) {
                int seq = getLifecycleSeq();
                if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
                        + " operation received seq: " + seq);
                // 這裡的finished為false
                // token 代表要pause的Activity
                sendMessage(
                        finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                        token,
                        (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
                        configChanges,
                        seq);
            }
        // 忽略..
    }
    private class H extends Handler {
        public void handleMessage(Message msg) {
            // ......
            case PAUSE_ACTIVITY: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                        SomeArgs args = (SomeArgs) msg.obj;
                        handlePauseActivity((IBinder) args.arg1, false,
                                (args.argi1 & USER_LEAVING) != 0, args.argi2,
                                (args.argi1 & DONT_REPORT) != 0, args.argi3);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break;
            // ......
        }
    }

    private void handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport, int seq) {
        // ......
        // 擷取ActivityClientRecord
        ActivityClientRecord r = mActivities.get(token);
        // 調用Activity的onPause
        performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity"); 
        // ......

        // 通知AMS已經暫停, 可以繼續AMS還沒完成的事,啟動新的Activity
        if (!dontReport) {
            try {
                ActivityManager.getService().activityPaused(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }
    // ......
}
           

通知AMS已經暫停,啟動新的App

暫停目前Activity後,通知AMS已經暫停, 可以繼續AMS還沒完成的事,啟動新的App,主要是調用了Process.start函數,通過LocalSocket和ZygoteServer通信,fork一個新的程序。注意這裡使用的是Socket通信,并不是Binder。因為zygote程序内加載了preload()方法中的所有資源,當需要fork新程序時,采用copy on write技術,是以fork出的新程序可以直接使用預加載的資源,并調用ZygoteInit.nativeZygoteInit()執行Binder驅動程式初始化的相關工作了,才使得程序中的Binder對象能夠順利地進行Binder程序間通信,最後執行新程序中的android.app.ActivityThread類中的Main函數,在main函數調用了attach,接着有調用AMS的attachApplication,用于生命周期的回調。

public final class ActivityThread {
    // ......
    public static void main(String[] args) {
        // ......
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        Looper.loop();
        // ......
    }

    private void attach(boolean system) {
        // ......
        final IActivityManager mgr = ActivityManager.getService();
        try {
            // 把mAppThread傳給AMS,用來程序通信,進入AMS的attachApplication函數中
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        // ......
    }
}
           

建立Application

通過Binder驅動程式,執行流程又回到AMS中,調用ActivityManagerService的attachApplication函數中,主要做了2件事 1. 通過Binder驅動程式調用ApplicationThread的bindApplication。 2. 通過Binder驅動調用ApplicationThread的scheduleLaunchActivity。

public class ActivityManagerService ... {

    // ......
    @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) {
        thread.bindApplication(processName, appInfo, providers,
                        app.instr.mClass,
                        profilerInfo, app.instr.mArguments,
                        app.instr.mWatcher,
                        app.instr.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);

        // ......
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }  
        // ......
    }
}
           

通過Binder驅動程式調用ApplicationThread的bindApplication。然後利用mH.sendMessage最終會執行到ActivityThread中handleBindApplication函數,在這個函數主要是建立了Application,并調用了attach和onCreate方法。

public final class ActivityThread {
    // ......
    private void handleBindApplication(AppBindData data) {
        Application app;
            // ......
        try {
            // ......
            data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);

            // 建立Application并調用了attach方法
            app = data.info.makeApplication(data.restrictedBackupMode, null);
            // 把app賦給全局變量
            mInitialApplication = app;
            // ......
            // 調用了onCreate方法
            mInstrumentation.callApplicationOnCreate(app);
    }
    // ......
}

public final class LoadedApk {
    public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {
        Application app = null;

        String appClass = mApplicationInfo.className;
        // forceDefaultAppClass為false,如果沒有沒有指定就會加載預設的
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            // ...... 建立一個Context對象
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            // 調用Instrumentation的newApplication
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            // ......
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;
    }
}

public class Instrumentation {
    static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }
}
           

建立Activity

通過Binder驅動程式調用ApplicationThread的scheduleLaunchActivity。然後利用mH.sendMessage最終會執行到ActivityThread中handleLaunchActivity函數,在這個函數主要是建立了Activity,并調用了attach和onCreate等生命周期方法。

public final class ActivityThread {
    private class ApplicationThread extends IApplicationThread.Stub {
        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);

            // 發送msg,在H.handleMessage響應
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
    }

    private class H extends Handler {
        public void handleMessage(Message msg) {
            // ......
            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;
            // ......
        }
    }

        private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
            // ..... 建立Activity, 并調用onCreate, onStart, onPostCreate以及onRestoreInstanceState(分情況調用),
            Activity a = performLaunchActivity(r, customIntent);
            if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;

            // ...... 調用onResume, onPostResume
            handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
            // ......
        }
}
           

調用performLaunchActivity,建立Activity, 并調用onCreate, onStart, onPostCreate以及onRestoreInstanceState(分情況調用), 接下來我們繼續看:

public final class ActivityThread {

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // ...... 建立Context
        ContextImpl appContext = createBaseContextForActivity(r);
            Activity activity = null;
            try {
                java.lang.ClassLoader cl = appContext.getClassLoader();
                // 執行個體化一個Activity對象
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                // ......
                r.intent.setExtrasClassLoader(cl);
                r.intent.prepareToEnterProcess();
                if (r.state != null) {
                    r.state.setClassLoader(cl);
                }
            } catch (Exception e) {
                // ......
            }

         // ......
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

         // ......初始化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, r.configCallback);
        // ...... 調用Activity的onCreate函數        
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        // ...... 調用Activity的onStart函數
        if (!r.activity.mFinished) {
            activity.performStart();
            r.stopped = false;
        }
        // ...... 調用Activity的onRestoreInstanceState函數
        if (!r.activity.mFinished) {
            if (r.isPersistable()) {
                if (r.state != null || r.persistentState != null) {
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                            r.persistentState);
                }
            } else if (r.state != null) {
                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
            }
        }
         // ...... 調用Activity的onPostCreate函數
        if (!r.activity.mFinished) {
            activity.mCalled = false;
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnPostCreate(activity, r.state,
                        r.persistentState);
            } else {
                mInstrumentation.callActivityOnPostCreate(activity, r.state);
            }
            // ......
        }
        r.activity = activity;
        // ...... 添加到集合中,token是key
        mActivities.put(r.token, r);
    }
}
           

調用handleResumeActivity,調用onResume, onPostResume生命周期方法,然後調用makeVisible, 添加View到WindowManager,WindowManager的實作類是WindowManagerImpl,WindowManagerImpl的addView又調用了WindowManagerGloble.addView, 建立ViewRootImpl對象,并調用了setView函數。(有點扯遠了,有興趣的小夥伴可以去看看),

當線程空閑的時候,調用AMS的activityIdle,最終會調回ApplicationThread.scheduleStopActivity.

最後Activity進入Resumed,并通知AMS

public final class ActivityThread {
    public final ActivityClientRecord performResumeActivity(IBinder token,
        boolean clearHide, String reason) {
        // 根據token取出ActivityClientRecord
        ActivityClientRecord r = mActivities.get(token);   
        // 調用onResume, onPostResume
        r = performResumeActivity(token, clearHide, reason);
        // .......
        // 添加View到WindowManager
        if (r.activity.mVisibleFromClient) {
            r.activity.makeVisible();
        }


        if (!r.onlyLocalRequest) {
            r.nextIdle = mNewActivities;
            mNewActivities = r;
            // ...... 當線程空閑時,調用AMS的activityIdle
            Looper.myQueue().addIdleHandler(new Idler());
        }
        r.onlyLocalRequest = false;

        通知AMS, Activity已經進入了resumed狀态
        if (reallyResume) {
            try {
                ActivityManager.getService().activityResumed(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }
           

到這裡一個新的App,就完成啟動了,整個App啟動過程執行了很多步驟,最後畫個圖,幫助大家了解。

activity啟動流程_App 啟動流程分析

參考連結:

https://blog.csdn.net/luoshengyang/article/details/6689748​blog.csdn.net

播客位址

木易楊的部落格 | YGS Blog​shineygs.github.io

activity啟動流程_App 啟動流程分析

繼續閱讀