android app啟動流程解析

Linux系統(tǒng)啟動流程

Linux啟動概述

android系統(tǒng)內(nèi)核實質(zhì)是使用了Linux的內(nèi)核,所以在談到android app啟動流程就必須先了解Linux啟動流程;當(dāng)們啟動Linux系統(tǒng)時,bootloader會加載linux內(nèi)核到內(nèi)存運(yùn)行,完成后會啟動系統(tǒng)的第一個進(jìn)程(init進(jìn)程),其完成后會主動創(chuàng)建許多(Daemon)守護(hù)進(jìn)程,保證一些服務(wù)能正常開啟,如usb daemon進(jìn)程,保證usb驅(qū)動服務(wù)正常運(yùn)行。

android相關(guān)概述

init進(jìn)程會創(chuàng)建android底層的一個Zygote進(jìn)程,Zygote進(jìn)程會初始化第一個VM虛擬器,并且加載android相關(guān)的framework和app所需要的資源,然后Zygote會開啟一個socket來監(jiān)聽外部請求,如果收到請求,會根據(jù)已有的VM孵化出一個新的VM和進(jìn)程;
  隨后,Zygote會創(chuàng)建一個System Server進(jìn)程,此進(jìn)程會啟動android相關(guān)的所有核心服務(wù),如AMS(Activity Manager Service)和其他服務(wù)進(jìn)程等,至此,系統(tǒng)會啟動第一個App--Home進(jìn)程,Home進(jìn)程就是手機(jī)的桌面進(jìn)程。

啟動桌面上的app

app_launch

  
  1. 點擊桌面app icon -> home的onclick()方法 -> startActivity(Intent)
  
  2. 通過Binder通信進(jìn)制,將此次啟動信息通知給ActivityManagerService,在service內(nèi)部會做如下操作:
     a. 收集此次啟動的對象信息,并封裝在intent對象里面去 --- PackageManager的resolveIntent()方法
     b. 驗證用戶是否有足夠的權(quán)限來啟動這個activity --- grantUriPermissionLocked()
     c. 如果有權(quán)限,AMS就會啟動這個activity,如果這個activity的進(jìn)程ProcessRecord為null的話,就會為其創(chuàng)建一個新進(jìn)程;反之,則回去打開已經(jīng)存在的activity
     接下來,就開始分析AMS如何具體的啟動activity
     
  3. AMS創(chuàng)建進(jìn)程啟動app
    AMS調(diào)用startProcessLocked()方法創(chuàng)建新進(jìn)程,并且通過socket通道傳遞請求給Zygote進(jìn)程,Zygote進(jìn)程會根據(jù)收到的請求孵化出一個自身,并調(diào)用ZygoteInit.main來實例化一個ActivityThead,ActivityThread的main方法就是作為app的起始入口。

    
進(jìn)程創(chuàng)建

  4. ActivityThread的main入口是app的起始入口,它是app進(jìn)程的主線程,管理Activity和Application的啟動和生命周期的調(diào)用等等

ActivityThread啟動細(xì)節(jié)

這里寫圖片描述

兩個重要內(nèi)部類

ApplicationThread 和 H

1. main入口

public static void main(String[] args) {
    //創(chuàng)建Looper對象, 創(chuàng)建MessageQueue對象
        Looper.prepareMainLooper();

    //創(chuàng)建自己的ActivityThread對象
        ActivityThread thread = new ActivityThread();
        thread.attach(false);                 // --- 這個很重要

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        AsyncTask.init();

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

    //進(jìn)入消息循環(huán)
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
}
//applicationThread實質(zhì)是一個binder實例,將binder實例綁定到AMS
private void attach(boolean system) {
    ...
    //獲得AMS(ActivityManagerService)實例, AMS的log tag: "ActivityManager"
    IActivityManager mgr = ActivityManagerNative.getDefault();
    //把ApplicationThread對象傳給AMS
    mgr.attachApplication(mAppThread);
    ...
}

2. attachApplication綁定ApplicationThread,收集進(jìn)程的信息,并通過ApplicationThread的bindApplication接口跨進(jìn)程回傳此次新進(jìn)程信息給ActivityThread

public final class ActivityManagerService extends ActivityManagerNative {
    ...
    public final void attachApplication(IApplicationThread thread) {
        ...
        attachApplicationLocked(thread, callingPid);
        ...
    }
    ...
    private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
        ....
        //通過binder,跨進(jìn)程調(diào)用ApplicationThread的bindApplication()方法, 下面代碼邏輯重回ActivityThread.java
            thread.bindApplication(processName, appInfo, providers,
                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
                    app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
                    mCoreSettingsObserver.getCoreSettingsLocked());
        ....

    }
}

這個時候還在Binder進(jìn)程中,利用Handler把消息傳回給ActivityThread

//ActivityThread.java

private class ApplicationThread extends Binder implements IApplicationThread{

    ...
        public final void bindApplication(String processName,
                ApplicationInfo appInfo, List<ProviderInfo> providers,
                ComponentName instrumentationName, String profileFile,
                ParcelFileDescriptor profileFd, boolean autoStopProfiler,
                Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
                Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
                Bundle 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.initProfileFile = profileFile;
            data.initProfileFd = profileFd;
            data.initAutoStopProfiler = false;
         //發(fā)消息
            sendMessage(H.BIND_APPLICATION, data);
        }

    ...
        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把BIND_APPLICATION消息發(fā)給H處理
        mH.sendMessage(msg);
        }
    ...

}

3. ActivityThread的H接收消息并開啟逐步執(zhí)行Application的oncreate

收到BIND_APPLICATION消息后,創(chuàng)建Application對象以及上下文

//ActivityThread.java
public final class ActivityThread {
    ...
    private void handleBindApplication(AppBindData data) {
        ...
        //創(chuàng)建Instrumentation 對象
                java.lang.ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();

        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
        //創(chuàng)建app運(yùn)行時的上下文對象,并對其進(jìn)行初始化.
        final ContextImpl appContext = new ContextImpl();
        appContext.init(data.info, null, this);
        //這里的data.info是LoadedApk類的對象
        //在這里創(chuàng)建了上層開發(fā)者的代碼中所涉及的Applicaiton類的對象
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        ...

        //如果有ContentProvider的話, 先加載ContentProvider,后調(diào)用Application的onCreate()方法
        List<ProviderInfo> providers = data.providers;
        if (providers != null) {
            installContentProviders(app, providers);
        }
        //調(diào)Application的生命周期函數(shù) onCreate()
        mInstrumentation.callApplicationOnCreate(app);

    }
    ...

    private class H extends Handler {
        ...
        public static final int BIND_APPLICATION  = 110;
        ...
        public void handleMessage(Message msg) {
            switch (msg.what) {
                ...
                    case BIND_APPLICATION:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                        AppBindData data = (AppBindData)msg.obj;
                        handleBindApplication(data);//調(diào)用ActivityThread的handleBindApplication()方法處理
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                ...
            }
        }
    }
}

執(zhí)行application的oncreate方法

// LoadedApk.java
public final class LoadedApk {
    ...
    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        Application app = null;
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
        return app;
    }
    ...

}

// Instrumentation.java
public class Instrumentation {
    ...
    public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }
    ...
}

至此,Application啟動流程完了;同理,啟動activity的流程大致相同;
activty啟動開始點在AMS的attachApplicationLocked方法內(nèi)部,即bindApplication發(fā)送Application后,就會開始準(zhǔn)備啟動Activity,依次調(diào)用mStackSupervisor.attachApplicationLocked(app), 在里面再調(diào)用realStartActivityLocked(), 里面再調(diào)用app.thread.scheduleLaunchActivity(), 也就是mAppThread的scheduleLaunchActivity(), 在ApplicationThread的scheduleLaunchActivity()內(nèi),發(fā)送一個"LAUNCH_ACTIVITY"消息, mH處理"LAUNCH_ACTIVITY"時調(diào)用handleLaunchActivity(), handleLaunchActivity()分兩步, 第一步調(diào)performLaunchActivity(),
創(chuàng)建Activity的對象, 依次調(diào)用它的onCreate(), onStart(). 第二步調(diào)handleResumeActivity(), 調(diào)用Activity對象的onResume().

至此, 應(yīng)用啟動的完整流程就分析完整了

手動總結(jié):

Android啟動總流程.jpg

參考文章:
http://www.itdecent.cn/p/a1f40b39b3de
http://www.itdecent.cn/p/a5532ecc8377

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容