App啟動流程:App進程內(nèi)部操作-1

目錄

  • 概述
  • 總結(jié)
  • 詳細(xì)過程
  • 重要類說明

概述

在冷啟動過程中,“當(dāng)為App創(chuàng)建完進程”之后,就需要“激活處于焦點棧棧頂?shù)拇龁覣ctivity”。關(guān)于冷啟動過程的前兩步操作,《為目標(biāo)App啟動做準(zhǔn)備》、《啟動App進程》 的流程請點擊查看。

由于“App進程內(nèi)部操作”部分內(nèi)容比較多一些,所以這部分的內(nèi)容被分成了2個小章節(jié)來分析。
第一節(jié):也就是本節(jié)是從“App進程啟動完畢之后,從ActivityThread.main()開始” 至 “App進程接收到AMS通過scheduleLaunchActivity()發(fā)起的 LAUNCH_ACTIVITY 消息”為止。
第二節(jié):《App啟動流程:App進程內(nèi)部操作-2》,則從“App接收到LAUNCH_ACTIVITY開始” 至 “通過Activity.handleResumeActivity()真正完成待啟動Activity的實例化并執(zhí)行其View樹的繪制”為止。

當(dāng)前源碼的分析是基于 Android8.0。


總結(jié)

1:當(dāng)Zygote進程創(chuàng)建并初始化完App進程后,就會通過反射執(zhí)行ActivityThread.main()對main線程進行初始化。
2:通過ActivityManager.getService()獲取AMS服務(wù)在本進程的BInder 代理,而后通過這個代理對象通知AMS執(zhí)行attachApplication()操作。

這是一次IPC操作,從App進程切換至system_server進程

3:AMS接收到App進程發(fā)起的“attachApplication()操作”操作后會執(zhí)行如下操作:
3.1:根據(jù) 調(diào)用者進程的pid,獲取記錄此進程信息的ProcessRecord。
3.2:注冊“Binder服務(wù)死亡通知”,App進程掛掉之后其Binder服務(wù)也會隨之停止掉,此時AMS需要接收到這個通知,然后去回收一些此進程使用的資源。
3.3:把當(dāng)前App進程的ApplicationThread賦值給ProcessRecord中的thread。并重置此ProcessRecord中一些參數(shù)。
3.4:通過App進程的ApplicationThread服務(wù)在system_server進程的Binder代理對象,執(zhí)行bindApplication()來通知App進程繼續(xù)后續(xù)“綁定”操作。

這是一次IPC操作,從system_server進程切換至App進程

4:App進程接收到AMS發(fā)起的bindApplication()操作后會執(zhí)行如下操作:
4.1:通過 ServiceManager.initServiceCache()更新系統(tǒng)服務(wù)在App進程的Binder緩存。
4.2:通過Handler消息機制,向App進程的主線程發(fā)一個“BIND_APPLICATION”消息,使操作切換至主線程繼續(xù)后續(xù)執(zhí)行。
5:App進程會通過handleBindApplication()處理bindApplication()操作。 具體所做的事情如下:
5.1:設(shè)置App進程名、為低內(nèi)存設(shè)備關(guān)閉硬件加速功能、如果系統(tǒng)的版本號低于3.1,則更換AsyncTask的內(nèi)部的線程池實現(xiàn)方法、系統(tǒng)版本號大于等于 3.0 的話,則開啟嚴(yán)格模式來檢查“是否在主線程開啟了網(wǎng)絡(luò)請求、初始化http代理、創(chuàng)建全局唯一Instrumentation實例 等。
5.2:通過LoadedApk.makeApplication()創(chuàng)建App進程的唯一Application實例,回調(diào)Application的attachBaseContext()、onCreate()。

App進程執(zhí)行完bindApplication()操作后,又會回到system_server進程繼續(xù)后續(xù)操作。

這些操作包括如下部分:
6.1:從“焦點?!敝蝎@取“處于棧頂?shù)拇龁覣ctivity對應(yīng)的ActivityRecord”。
6.2:通知App進程執(zhí)行“scheduleLaunchActivity()”操作,在App進程進行待啟動Activity的實例化、各種生命周期方法的執(zhí)行、相應(yīng)PhoneWindow維護的View樹的繪制等操作。

這是一次IPC操作,從system_server進程切換至App進程

7:App 進程接收到LLAUNCH_ACTIVITY消息之后,會在App進程內(nèi)部的handleLaunchActivity()對待啟動Activity進行激活等初始化操作。 具體操作如下:
7.1:從空閑消息處理器列表中 移除 “在主線程空閑時,執(zhí)行強制GC操作的空閑消息處理器” 。
7.2:在創(chuàng)建待啟動Activity之前,先獲取WMS服務(wù)在本進程的Binder代理并保存至WindowManagerGlobal。
7.3:通過performLaunchActivity()初始化ContextImpl實例、對目標(biāo)Activity進行初始化、執(zhí)行Activity的綁定操作、執(zhí)行Activity的相應(yīng)生命周期方法、等Activity執(zhí)行完Resume之后,才開始對Activity的View樹進行App進程內(nèi)部的測量、擺放、繪制等操作。并通過ViewRootImpl內(nèi)部的“編舞者來接收IO硬件產(chǎn)生的“Vsync”刷新信號,進而對PhoneView維護的視圖樹進行周期性的刷新操作。
7.4:根據(jù)AMS傳遞給App 進程的startsNotResumed,來決定是否需要“禁止Resume待啟動Activity,如果禁止就會執(zhí)行該Activity的pasue操作”。
7.5:如果初始化Activity實例失敗,告訴AMS需要 “移除” 此Activity對應(yīng)保存在AMS 服務(wù)中的Activity棧中的ActivityRecord。


詳細(xì)過程

當(dāng)Zygote進程創(chuàng)建并初始化完App進程后,就會通過反射執(zhí)行ActivityThread.main()對main線程進行初始化。

1.1.ActivityThread.main()

main()方法是子進程執(zhí)行其主線程初始化的唯一入口。

源碼

public static void main(String[] args) {
        //開始記錄ActivityThread的初始化事件
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        ......
        //為主線程創(chuàng)建Looper
        Looper.prepareMainLooper();
        
        //初始化App進程內(nèi)的ActivityThread唯一實例
        ActivityThread thread = new ActivityThread();
        //見小節(jié)[1.2]
        thread.attach(false);

        //sMainThreadHandler就是ActivityThead.H類的實例
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        //ActivityThread初始化完畢之后,結(jié)束記錄該事件的耗時
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        //啟動主線程Looper,開始處理消息
        Looper.loop();

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

1.2.ActivityThread.attach()

總結(jié)
1:通過ViewRootImpl.addFirstDrawHandler()注冊“View樹的首次繪制完畢回調(diào)事件”。
2:通過ViewRootImpl.addConfigCallback()注冊“手機配置信息發(fā)生更改之后的回調(diào)事件?!?br> 3:通過ActivityManager.getService()獲取AMS服務(wù)在本進程的BInder 代理,而后通過這個代理對象通知AMS執(zhí)行attachApplication()操作。

源碼

private void attach(boolean system) {
        //把當(dāng)前ActivityThread實例對象賦值給sCurrentActivityThread 屬性。使用的時候方便通過currentActivityThread()獲取。
        sCurrentActivityThread = this;
        //用于區(qū)分“當(dāng)前進程是否是系統(tǒng)進程”。
        mSystemThread = system;
        if (!system) {
            //見小節(jié)[1.2.1]
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                @Override
                public void run() {
                    ensureJitEnabled();
                }
            });
            ......
            //見小節(jié)[1.3]
            final IActivityManager mgr = ActivityManager.getService();
            try {
             //見小節(jié)[2.1]
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            ......
        } else {
           //是系統(tǒng)進程的話,設(shè)置該進程的name為“system_process”。
           //可以啟動一個模擬器或者刷root之后,打開可debug的進程之后,顯示的那個“system_process”。如果要調(diào)試FrameWorker層的代碼的話,那么此進程就是要debug的那個進程。
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            ......
        }

        ......
        //見小節(jié)[1.2.2]
        ViewRootImpl.ConfigChangedCallback configChangedCallback
                = (Configuration globalConfig) -> {
            synchronized (mResourcesManager) {
                // We need to apply this change to the resources immediately, because upon returning
                // the view hierarchy will be informed about it.
                if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
                        null /* compat */)) {
                    updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
                            mResourcesManager.getConfiguration().getLocales());

                    // This actually changed the resources! Tell everyone about it.
                    if (mPendingConfiguration == null
                            || mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
                        mPendingConfiguration = globalConfig;
                        sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
                    }
                }
            }
        };
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

1.2.1.ViewRootImpl.addFirstDrawHandler():

總結(jié):
1:注冊“View樹繪制第一幀時的回調(diào)事件”。
2:在View樹繪制第一幀時,用于通知注冊了此事件的被觀察者,View開始繪制第一幀了。

源碼

public static void addFirstDrawHandler(Runnable callback) {
        synchronized (sFirstDrawHandlers) {
            if (!sFirstDrawComplete) {
                sFirstDrawHandlers.add(callback);
            }
        }
    }

private void draw(boolean fullRedrawNeeded) {
        ......
        //通知那些注冊了“繪制第一幀”事件的被觀察者,開始繪制第一幀了
        if (!sFirstDrawComplete) {
            synchronized (sFirstDrawHandlers) {
                sFirstDrawComplete = true;
                final int count = sFirstDrawHandlers.size();
                for (int i = 0; i< count; i++) {
                    mHandler.post(sFirstDrawHandlers.get(i));
                }
            }
        }
    ......
    }

1.2.2.ViewRootImpl.addConfigCallback():添加當(dāng)手機自身的配置信息發(fā)生改變之后(橫豎屏切換、字體大小發(fā)生了更改等等)的回調(diào)事件。

Configuration:該類表示的是“設(shè)備的配置信息”。該類定義了許多與手機本身相關(guān)的配置信息。
1.orientation:表示當(dāng)前手機的屏幕狀態(tài)(橫豎屏就是用這個來判斷)。
2.densityDpi:屏幕密度(eg:440dpi)。
3.appBounds:屏幕大小。
4.screenLayout:該參數(shù)是一個“復(fù)合值”。具體的存儲的信息如下:
4.1.屏幕整體大?。?/strong>可通過該值與相應(yīng)的mask進行位運算獲得當(dāng)前屏幕是“SMALL”、“NORMAL”、“LARGE”、“XLARGE”。
4.2.屏幕布局:表示當(dāng)前屏幕中的元素是“從左往右布局”還是“從右往左布局”。取值范圍為:“SCREENLAYOUT_LAYOUTDIR_LTR”、“SCREENLAYOUT_LAYOUTDIR_RTL”。
4.3.屏幕是否是圓形。
5.fontScale:字體的縮放比率。

源碼

public static void addConfigCallback(ConfigChangedCallback callback) {
        synchronized (sConfigCallbacks) {
            sConfigCallbacks.add(callback);
        }
    }

1.3.ActivityManager.getService():獲取AMS服務(wù)在本進程的Binder代理。

源碼

public static IActivityManager getService() {
        //調(diào)用IActivityManagerSingleton.get()會觸發(fā)IActivityManagerSingleton中聲明的create()。
        //見小節(jié)[1.3.1]
        return IActivityManagerSingleton.get();
    }

1.3.1.Singleton.create()

源碼

private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    //見小節(jié)[1.3.2]
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    //見小節(jié)[1.3.7]
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

1.3.2.ServiceManager.getService():獲得相應(yīng)系統(tǒng)服務(wù)在本進程的 IBinder 引用。

總結(jié):
1:如果ServiceManager內(nèi)部的HashMap緩存了此Binder服務(wù)的話,則返回。
2:如果沒有,則通過 getIServiceManager().getService() 重新與system_server進程建立連接,獲取相應(yīng)服務(wù)在本進程的Binder代理。
3:這個Binder代理對象與系統(tǒng)服務(wù)對象不是一個。因為AMS運行在system_server進程,此對象運行在 App進程。采用“進程隔離”的方式,每個進程都有自己的 虛擬內(nèi)存地址空間,且每個進程被分配的虛擬內(nèi)存地址都不一樣,這就導(dǎo)致每個進程可訪問的內(nèi)存區(qū)域是不一樣的,進程之間沒有交集,這就避免了 “修改進程A內(nèi)存區(qū)域會影響到進程B內(nèi)存中的數(shù)據(jù)”。

源碼

public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            //此時,從本地服務(wù)緩存中獲取的AMS服務(wù)的本地代理肯定為 null。
            //因為這些系統(tǒng)服務(wù)的本地代理還沒有通過 initSerivceCache()緩存起來。
            if (service != null) {
                return service;
            } else {
                //見小節(jié)[1.3.3]、[1.3.6]
                return Binder.allowBlocking(getIServiceManager().getService(name));
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }

1.3.3.ServiceManager.getIServiceManager():獲取ServiceManager內(nèi)部保存的IServiceManager實例。

總結(jié):
1:如果IServiceManager實例已經(jīng)初始化過了,則直接返回此實例。
2:如果還沒初始化過,則需要先初始化然后返回此類實例。

源碼

private static IServiceManager getIServiceManager() {
        //非首次調(diào)用,則返回此類實例
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // 初始化IServiceManager類實例
        //見小節(jié)[1.3.4]、[1.3.5]
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

1.3.4.BinderInternal.getContextObject():獲取一個IServiceManager,通過它可以獲取到一些其它系統(tǒng)服務(wù)。

總結(jié):
1:該方法是一個native方法,用于獲取“IServiceManager類型的實例”。
2:該IServiceManager接口的實例可以用來“查詢其它服務(wù)”。

源碼

/**
     * Return the global "context object" of the system.  This is usually
     * an implementation of IServiceManager, which you can use to find
     * other services.
     */
    public static final native IBinder getContextObject();

1.3.5.ServiceManagerNative.asInterface():獲取一個IServiceManager類型的IBinder服務(wù)。

Binder使用上的簡單介紹
1:Binder這種IPC方式采用的是CS架構(gòu)。
2:IBinder表示“此類是可以用來進行IPC通信的,它提供了IPC通信的能力”。
2.1:Binder類實現(xiàn)了IBidner接口,實現(xiàn)了 “onTransact()”。
2.2:通常我們所提供的服務(wù)類要繼承Binder,重寫 OnTransact() 方法用于根據(jù)自己的業(yè)務(wù)處理來自Client端的請求。

總結(jié)
1:首先,判斷通過“BinderInternal.getContextObject()”獲得的IBinder服務(wù)是否是當(dāng)前進程所創(chuàng)建,如果是直接返回此IBInder 服務(wù)。
2:如果不是,則返回一個 ServiceManagerProxy,把服務(wù)端在本進程的IBinder服務(wù)實例保存到這個代理對象中。這樣做是為了 方便以后通過此IBinder實例與服務(wù)的所屬進程進行通信。

源碼

static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        //根據(jù)“descriptor”從本進程中查找該Binder服務(wù)。
        //1:如果此IBinder服務(wù)所屬者是當(dāng)前進程的話,則返回該服務(wù)。
        //2:如果不是,則返回ServiceManagerProxy。其中“obj”是服務(wù)端進程的IBinder服務(wù)在本進程的一個實例。
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        
        return new ServiceManagerProxy(obj);
    }

    //把IBinder服務(wù)在本進程的一個實例保存至ServiceManagerProxy中。
    //方便以后通過此IBinder實例與服務(wù)的所屬進程進行通信。
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }

1.3.6.IServiceManager.getService():通過Binder IPC方式,根據(jù)name從system_server進程獲取系統(tǒng)服務(wù)在本地進程的Binder代理對象。

源碼

/**
     * Retrieve an existing service called @a name from the
     * service manager.  Blocks for a few seconds waiting for it to be
     * published if it does not already exist.
     */
    public IBinder getService(String name) throws RemoteException;

1.3.7.IActivityManager.Stub.asInterface():

總結(jié):
1:把獲取的IBinder對象封裝到AMS服務(wù)在子進程的Binder代理對象中。
2:此代理對象的實際類型為 IActivity.Stub.Proxy。
3:此代理對象與AMS對象一樣都實現(xiàn)了IActivityManager接口,此接口定了AMS向外提供了哪些操作。這樣做的好處是“在使用的時候,就可以直接知道可以使用AMS提供的哪些方法了”。

說明:
1:從8.0開始,AMS這種用于IPC通信的系統(tǒng)服務(wù)的實現(xiàn)方式改為AIDL 來實現(xiàn)。
2:8.0之前AMS內(nèi)提供的 用于處理進程間操作的業(yè)務(wù) 全部是在ActivityManagerNative內(nèi)部來實現(xiàn),而從8.0開始采用AIDL之后,AMS直接繼承自IActivityService.Stub原來處理進程間操作的業(yè)務(wù)全部挪到AMS來中完成。

因為看不到IActivityService.Stub的內(nèi)部實現(xiàn),所以以下代碼就摘抄了一個AS編譯的AIDL文件生成的的asInterface()實現(xiàn)(通過AIDL方式編譯的此方法的實現(xiàn)格式是一樣)。

public static sj.IMyAidlInterface asInterface(android.os.IBinder obj) {
    //判斷IBinder服務(wù)是否為空
    if ((obj==null)) {
        return null;
    }
    
    //查詢此服務(wù)是否是本進程創(chuàng)建的
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);

    if (((iin!=null)&&(iin instanceof sj.IMyAidlInterface))) {
        return ((sj.IMyAidlInterface)iin);
    }
    
    //此服務(wù)不是本進程創(chuàng)建的話,則返回與之對應(yīng)的Proxy對象。
    return new sj.IMyAidlInterface.Stub.Proxy(obj);
}

......

Proxy(android.os.IBinder remote) {
      mRemote = remote;
}

2.1.ActivityManagerService.attachApplication()

總結(jié):
1:通過ActivityManager.getService()獲取AMS服務(wù)在本進程的Binder代理對象后,調(diào)用該代理對象的 attachApplication() 就會進行一次進程切換。
2:App進程會被阻塞住,一直等到system_server進程內(nèi)部的AMS.attachApplication()執(zhí)行完畢為止。

參數(shù)說明:
IApplicationThread threa:App進程的ApplicationThread唯一實例。關(guān)于ApplicationThread的介紹請查看 本章-重要類說明

源碼

@Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            //獲取調(diào)用者進程的pid(已經(jīng)啟動的App進程的id)。
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            //見小節(jié)[2.2]
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }

2.2.ActivityManagerService.attachApplicationLocked()

總結(jié):
1:根據(jù) 調(diào)用者進程的pid,獲取記錄此進程信息的ProcessRecord。如果獲取的ProcessRecord為null的話,則表示“之前創(chuàng)建App進程那步出現(xiàn)了問題(ProcessRecord用于記錄App運行在的進程信息)”,這種情況直接返回不再繼續(xù)后續(xù)操作。
2:注冊“Binder服務(wù)死亡通知”。這里的“服務(wù)端”指的是App進程的ApplicationThread實例(ApplicationThread繼承IApplicationThread.Stub,它是在此Binder IPC通信中扮演的是服務(wù)端角色)。App進程掛掉之后其Binder服務(wù)也會隨之停止掉,此時AMS需要接收到這個通知,然后去回收一些此進程使用的資源(eg:重置此進程對應(yīng)的ProcessRecord中的數(shù)據(jù),進程被kill掉之后其ProcessRecord并不會從mPidsSelfLocked緩存中移除)。
3:把當(dāng)前App進程的ApplicationThread賦值給ProcessRecord中的thread。并重置此ProcessRecord中一些參數(shù)。
4:通過App進程的ApplicationThread服務(wù)在system_server進程的Binder代理對象,執(zhí)行bindApplication()來通知App進程繼續(xù)后續(xù)“綁定”操作。
4.1:如果執(zhí)行“bindApplication()”之后的綁定操作失敗了則:取消掉已經(jīng)注冊的 Binder服務(wù)死亡通知。調(diào)用startProcessLocked()再通知Zygote進程重新走一遍fork子進程流程。

源碼

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

        // 根據(jù)調(diào)用者進程的pid,獲取記錄此進程信息的ProcessRecord.
        ProcessRecord app;
        long startTime = SystemClock.uptimeMillis();
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }

        if (app == null) {  
            ......
            //如果獲取的ProcessRecord為null的話,則表示“之前創(chuàng)建App進程那步出現(xiàn)了問題(ProcessRecord用于記錄App運行在的進程信息)”,這種情況直接返回不再繼續(xù)后續(xù)操作。
            return false;
        }

       ......
        try {
            //注冊“Binder服務(wù)死亡通知”。
            //這里的“服務(wù)端”指的是App進程的ApplicationThread實例(ApplicationThread繼承IApplicationThread.Stub,它是在此Binder IPC通信中扮演的是服務(wù)端角色。App進程掛掉之后其Binder服務(wù)也會隨之停止掉,此時AMS需要接收到這個通知,然后去回收一些此進程使用的資源(eg:重置此進程對應(yīng)的ProcessRecord中的數(shù)據(jù),進程被kill掉之后其ProcessRecord并不會從mPidsSelfLocked緩存中移除)。)
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
            app.deathRecipient = adr;
        } catch (RemoteException e) {
            ......
            return false;
        }

        ......
        //把當(dāng)前App進程的ApplicationThread賦值給ProcessRecord中的thread。
        app.makeActive(thread, mProcessStats);
        //ProcessRecord一些參數(shù)的重置操作。
        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        app.forcingToImportant = null;
        updateProcessForegroundLocked(app, false, false);
        app.hasShownUi = false;
        app.debugging = false;
        app.cached = false;
        app.killedByAm = false;
        app.killed = false;

        ......

        try {
           ......
            //不清楚ProcessRecord中ActiveInstrumentation類型的 instr是做什么的。
            //但是無論此屬性是否為null,AMS服務(wù)都會通過App進程的ApplicationThread服務(wù)在system_server進程的Binder代理對象執(zhí)行bindApplication()來通知App進程繼續(xù)后續(xù)操作。
            if (app.instr != null) {
                //見小節(jié)[2.4]
                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), //見小節(jié)[2.3]
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            } else {
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated), //見小節(jié)[2.3]
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            }
        ......
        } catch (Exception e) {
             //如果此操作出現(xiàn)了問題導(dǎo)致拋出了異常情況。
            app.resetPackageList(mProcessStats);
            //取消掉已經(jīng)注冊的 Binder服務(wù)死亡通知。
            app.unlinkDeathRecipient();
            //調(diào)用startProcessLocked()再通知Zygote進程重新fork一個新的子進程。
            startProcessLocked(app, "bind fail", processName);
            return false;
        }

        boolean badApp = false;
        boolean didSomething = false;
        
        //See if the top visible activity is waiting to run in this process...
        //激活處于“焦點棧棧頂?shù)拇龁覣ctivity”
        //見小節(jié)[3.1]
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                ......
            }
        }
        ......

        return true;
    }

2.3.getCommonServicesLocked.getCommonServicesLocked():獲得一些公共的系統(tǒng)服務(wù)。

總結(jié):
1:獲得一些公共的系統(tǒng)Binder服務(wù)。
1.1:如果isolated為true的話,則只把PMS服務(wù)的IBinder對象回傳給App進程。
1.2:如果isolated為fasle的話,則把PMS、WMS、AlarmManagerService(鬧鐘服務(wù))的IBinder對象回傳給App進程。
2:獲得的這些服務(wù),會通過Binder這種IPC方式回傳給App進程,App進程接收到AMS發(fā)起的binderApplication()請求后,會首先通過 ServiceManager.initServiceCache()更新系統(tǒng)服務(wù)在App進程的Binder緩存。

源碼

private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
        //如果 isolated為true的話,則只把系統(tǒng)服務(wù)中的“PMS”對應(yīng)的Binder對象存儲到Map中。
        if (isolated) {
            if (mIsolatedAppBindArgs == null) {
                mIsolatedAppBindArgs = new HashMap<>();
                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
            }
            return mIsolatedAppBindArgs;
        }

        if (mAppBindArgs == null) {
            mAppBindArgs = new HashMap<>();

           //如果 isolated為false的話,則把系統(tǒng)服務(wù)中的“PMS、WMS、AlarmManagerService”對應(yīng)的Binder對象存儲到Map中。
            mAppBindArgs.put("package", ServiceManager.getService("package"));
            mAppBindArgs.put("window", ServiceManager.getService("window"));
            mAppBindArgs.put(Context.ALARM_SERVICE,
                    ServiceManager.getService(Context.ALARM_SERVICE));
        }
        return mAppBindArgs;
    }

2.4.ApplicationThread.bindApplication()

總結(jié):
1:通過 ServiceManager.initServiceCache()更新系統(tǒng)服務(wù)在App進程的Binder緩存。
2:通過Handler消息機制,向App進程的主線程發(fā)一個“BIND_APPLICATION”消息,使操作切換至主線程繼續(xù)后續(xù)執(zhí)行。
3:該操作是一次IPC過程,涉及到進程切換,從AMS所在的system_server進程切換至App進程。AMS要想主動發(fā)起與App進程的通信,就得借助于Binder這種IPC方式,因為ApplicationThread承擔(dān)的是服務(wù)端的角色,客戶端發(fā)起的請求,服務(wù)端接收后都會把這些操作扔到Bidner線程池中執(zhí)行,這樣做的好處是提高了服務(wù)端的“并發(fā)”性能。

源碼

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

            if (services != null) {
                //通過 ServiceManager.initServiceCache()更新系統(tǒng)服務(wù)在App進程的Binder緩存。
                 //見小節(jié)[2.5]
               ServiceManager.initServiceCache(services);
            }

            AppBindData data = new AppBindData();
            ......
            //見小節(jié)[2.6]
            sendMessage(H.BIND_APPLICATION, data);
        }

2.5.ServiceManager.initServiceCache():更新系統(tǒng)服務(wù)在App進程的Binder緩存。

源碼

public static void initServiceCache(Map<String, IBinder> cache) {
        if (sCache.size() != 0) {
            throw new IllegalStateException("setServiceCache may only be called once");
        }
        sCache.putAll(cache);
    }

2.6.ActivityThread.handleBindApplication()

總結(jié):
1:做一些準(zhǔn)備操作。 記錄進程的開始時間、設(shè)置App進程名、為低內(nèi)存設(shè)備關(guān)閉硬件加速功能、如果系統(tǒng)的版本號低于3.1,則更換AsyncTask的內(nèi)部的線程池實現(xiàn)方法、系統(tǒng)版本號大于等于 3.0 的話,則開啟嚴(yán)格模式來檢查“是否在主線程開啟了網(wǎng)絡(luò)請求、初始化http代理、創(chuàng)建全局唯一Instrumentation實例 等。
2:通過LoadedApk.makeApplication()創(chuàng)建App進程的唯一Application實例。

源碼

private void handleBindApplication(AppBindData data) {
        ......
        //記錄進程的開始時間。
        Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
        ......
        //設(shè)置App進程名
        Process.setArgV0(data.processName);
        //設(shè)置App進程在ddms模塊顯示的進程名
        android.ddm.DdmHandleAppName.setAppName(data.processName,
                                                UserHandle.myUserId());

        if (data.persistent) {
            //為 低內(nèi)存設(shè)備關(guān)閉硬件加速功能,這是為了節(jié)省資源開銷。
            if (!ActivityManager.isHighEndGfx()) {
                ThreadedRenderer.disable(false);
            }
        }

        ......

        // 如果系統(tǒng)的版本號低于3.1,則設(shè)置AsyncTask的內(nèi)部的線程池實現(xiàn)方法。
        if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
            AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }

        ......

        //系統(tǒng)版本號大于等于 3.0 的話,則開啟嚴(yán)格模式來檢查“是否在主線程開啟了網(wǎng)絡(luò)請求,如果開始了會拋出NetworkOnMainThreadException”。
        if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
            StrictMode.enableDeathOnNetwork();
        }

        //??
        if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
            StrictMode.enableDeathOnFileUriExposure();
        }

        ......
        //如果App可debug調(diào)試的話,則進行debug調(diào)試的相關(guān)設(shè)置
        if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) {
            ......
        }

        // 根據(jù)App是否可debug調(diào)試,來設(shè)置是否可以trace進程信息。
        boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        Trace.setAppTracingAllowed(isAppDebuggable);
        if (isAppDebuggable && data.enableBinderTracking) {
            Binder.enableTracing();
        }

        //初始化http代理
        final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
        if (b != null) {
            // In pre-boot mode (doing initial launch to collect password), not
            // all system is up.  This includes the connectivity service, so don't
            // crash if we can't get it.
            final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
            try {
                final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
                Proxy.setHttpProxySystemProperty(proxyInfo);
            } catch (RemoteException e) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw e.rethrowFromSystemServer();
            }
        }

        ......
        
        // 創(chuàng)建全局唯一Instrumentation實例,該mInstrumentation會在Activity創(chuàng)建完畢執(zhí)行其attach()時保存至Activity內(nèi)部。
        if (ii != null) {
            try {
                //創(chuàng)建Instrumentation實例
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {}
            ......
            mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
           ......
        } else {
            mInstrumentation = new Instrumentation();
        }

        ......
        try {
            //創(chuàng)建App進程的唯一Application實例
            //見小節(jié)[2.7]
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            //回調(diào)Instrumentation.onCreate()
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
           ......
            //回調(diào)Application的onCreate()生命周期方法
            try {
                //見小節(jié)[2.8]
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ......
            }
        } finally {
            StrictMode.setThreadPolicy(savedPolicy);
        }
        ......
    }

2.7.LoadedApk.makeApplication()

總結(jié):
1:該方法做事是:創(chuàng)建Applicaton實例并執(zhí)行該實例的attachBaseContext()與onCreate()生命周期方法。
2:判斷App進程的Application是否實例化了,如果已經(jīng)創(chuàng)建了則返回該Application。
3:系統(tǒng)采用反射的方式實例化Applation實例,第一步就是先指定“實例化Application的類的全限定名”。
4:通過Instrumentation.newApplication()初始化Application實例并回調(diào)其attachBaseContext()。
5:保存創(chuàng)建完畢的Application實例。
6:通過Instrumentation.callApplicationOnCreate()回調(diào)Application的onCreate()。

源碼

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        //判斷App進程的唯一Application是否創(chuàng)建了,如果創(chuàng)建則直接返回。
        //一個進程只有一個Application實例。
        if (mApplication != null) {
            return mApplication;
        }
    
       //記錄 創(chuàng)建Application花費的時間
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

        Application app = null;
        
       //指定“實例化Application的類的全限定名”。
       //ApplicationInfo記錄的是Manifest文件中<application>中的屬性信息。
       //如果“<application>未指定自定義Applcation”或者 “強制使用默認(rèn)的Application”來初始化Application實例的話,則使用默認(rèn)Application來

初始化
        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            //創(chuàng)建ContextImpl實例。
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            //見小節(jié)[2.7.1]
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ......
        }

        mActivityThread.mAllApplications.add(app);
        //保存創(chuàng)建完畢的Application實例
        mApplication = app;
        
        //傳入的instrumentation為null,不走這里
        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ......
            }
        }

        ......

        return app;
    }

2.7.1.Instrumentation.newApplication()

總結(jié):實例化Application實例并回調(diào)Application的attachBaseContext()生命周期方法。

源碼

public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        return newApplication(cl.loadClass(className), context);
    }


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


/* package */ final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }

2.8.Instrumentation.callApplicationOnCreate()

總結(jié):實例化Application實例并回調(diào)Application的attachBaseContext()生命周期方法。

源碼

public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }

3.1.ActivityStackSupervisor.attachApplicationLocked()

總結(jié):從“焦點?!敝蝎@取“處于棧頂?shù)拇龁覣ctivity對應(yīng)的ActivityRecord”并激活此ActivityRecord描述的App進程的Activity。
1:一個ActivityDisplay實例表示一塊屏幕,一個ActivityDisplay實例中存儲了多個ActivityStack實例。
2:遍歷每個ActivityDisplay中的ActivityStack集合,找到ActivityDisplay中的那個“焦點棧(ActivityStackSupervisor.mFocusedStack)”。
3:找到“焦點?!敝?,調(diào)用其topRunningActivityLocked()從其內(nèi)部保存TaskRecord列表中找到“處于棧頂?shù)拇龁覣ctivity對應(yīng)的ActivityRecord”。
4:調(diào)用ActivityStackSupervisor.realStartActivityLocked()激活處于焦點棧的待啟動Activity。

源碼

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        //獲取App進程名
        final String processName = app.processName;
        boolean didSomething = false;
        //遍歷ActivityDisplay集合。
        //一個ActivityDisplay實例表示一塊屏幕,一個ActivityDisplay實例中存儲了多個ActivityStack實例。
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            //遍歷每個ActivityDisplay中的ActivityStack集合。
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                //找到ActivityDisplay中的那個“焦點?!?。
                if (!isFocusedStack(stack)) {
                    continue;
                }
                //從“焦點?!敝蝎@取“處于棧頂?shù)拇龁覣ctivity”。
                ActivityRecord hr = stack.topRunningActivityLocked();
                if (hr != null) {
                    //待啟動Activity對應(yīng)的ActivityRecord信息只是添加到了AMS中的“Activity?!敝?具體是保存到ActivityTask中的TaskRecord列表中)。
                    //該Activity實例還沒有在App進程進行實例化,此時“ActivityRecord中保存的用于描述其所屬進程的ProcessRecord還未被賦值”。所以ActivityRecord.app為null。
                    //檢查“待啟動Activity是否未被添加到所屬進程”、“App進程的uid與待啟動Activity在Manifest中聲明的uid一致”、“App進程名與從Manifest文件中解析出的進程名一致”這3個條件是否都滿足。
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                            //見小節(jié)[3.2]
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                  + hr.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
        return didSomething;
    }

3.2.ActivityStackSupervisor.realStartActivityLocked()

總結(jié):
1:檢查是否“所有的ActivityStack中的mPausingActivity表示的正在處于暫停狀態(tài)的Activity執(zhí)行完畢暫停操作了”。如果還有ActivityStack種的Activity正在執(zhí)行暫停操作的話,則先不會執(zhí)行待啟動 Activity 的激活操作。
2:把描述App進程信息的ProcessRecord對象保存至ActivityRecord中。
3:通知App進程執(zhí)行“ scheduleLaunchActivity()”操作,在App進程進行待啟動Activity的實例化、各種生命周期方法的執(zhí)行、相應(yīng)PhoneWindow維護的View樹的繪制等操作。**

源碼

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
        //檢查是否“所有的ActivityStack中的mPausingActivity表示的正在處于暫停狀態(tài)的Activity執(zhí)行完畢暫停操作了”
        if (!allPausedActivitiesComplete()) {
            ......
            return false;
        }

        ......
    
    //把描述App進程信息的ProcessRecord對象保存至ActivityRecord中。
    r.app = app;
    ......
        try {
            ......
            //見小節(jié)[3.3]
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global and
                    // override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);

           ......
        } catch (RemoteException e) {
            ......
        }

        ......
        //andResume為true,走這里
        //見小節(jié)[4.1]
        if (andResume) {
            stack.minimalResumeActivityLocked(r);
        } else {
            ......
            r.state = PAUSED;
        }

        ......

        return true;
    }

3.3.ApplicationThread.scheduleLaunchActivity()

總結(jié):通過Binder IPC方式,通知App進程執(zhí)行待啟動Activity的啟動操作。
1:緩存AMS傳遞給App進程的參數(shù)信息(eg:startsNotResumed被賦值為了false,該值表示“是否需要禁止Resume待啟動Activity”。如果禁止就會執(zhí)行該Activity的pasue操作。true:禁止,false:不禁止)。
1:ApplicationThread作為Binder通信的服務(wù)端,其內(nèi)部操作是通過Handler消息機制,向App進程的主線程發(fā)一個“LAUNCH_ACTIVITY”消息,使操作切換至主線程繼續(xù)后續(xù)執(zhí)行。
2:該操作是一次IPC過程,涉及到進程切換,從AMS所在的system_server進程切換至App進程。AMS要想主動發(fā)起與App進程的通信,就得借助于Binder這種IPC方式,因為ApplicationThread承擔(dān)的是服務(wù)端的角色,客戶端發(fā)起的請求,服務(wù)端接收后都會把這些操作扔到Bidner線程池中執(zhí)行,這樣做的好處是提高了服務(wù)端的“并發(fā)”性能。

源碼

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

           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;
            
            //該值為false,在AMS所在的system_server通過Binder請求App進程的時候,notResumed為賦值為了“!andResume”,而andResume為true。
            //該值表示“是否禁止Resume待啟動Activity”,如果禁止就會執(zhí)行該Activity的pasue操作。true:禁止,false:不禁止。
            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

由于文章字?jǐn)?shù)過長,請查看App啟動流程:App進程內(nèi)部操作-2。


重要類說明

ApplicationThread
  • 從Android8.0開始,很多用于Binder IPC的類改用AIDL的方式實現(xiàn),其中ApplicationThread的實現(xiàn)也發(fā)生了改變。
  • 該類由原來繼承自ApplicationThreadNative 改為在8.0版本繼承自 IApplicationThread.Stub。但是不管怎么變,我們可以知道 ApplicationThread還是用來做IPC通信的,且它在Binder這種CS架構(gòu)中擔(dān)任的是 服務(wù)端角色。

ServiceManager
  • IServiceManager sServiceManager:該IServiceManager接口的實例可以用來“查詢其它服務(wù)”(eg:從system_server進程獲取AMS服務(wù)的本進程代理)。
  • HashMap<String, IBinder> sCache:用于緩存系統(tǒng)服務(wù)在本進程的Binder代理對象。
  • initServiceCache():緩存系統(tǒng)服務(wù)在App進程的Binder服務(wù)。當(dāng)App冷啟動完畢后,會執(zhí)行“AMS.attachApplication()”,在該方法內(nèi)部經(jīng)過層層調(diào)用,會通過傳入的App進程內(nèi)唯一的ApplicationThread實例通過Binder這種IPC方式,回調(diào)執(zhí)行子進程的 bindApplication() 用于“初始化App進程的唯一Application實例”。在初始化之前,會首先執(zhí)行 SystemService.initServiceCache()緩存系統(tǒng)服務(wù)在App進程的Binder服務(wù)”。
  • getService():獲取系統(tǒng)服務(wù)在本進程的Binder代理對象。
    1:如果ServiceManager內(nèi)部的HashMap緩存了此Binder服務(wù)的話,則返回。
    2:如果沒有,則通過 getIServiceManager().getService() 通過Binder驅(qū)動獲取Native層ServiceManager的Binder服務(wù)后,再通過ServiceManager獲取已向其注冊的相應(yīng)Binder服務(wù)在本進程的Binder代理對象。
    3:這個Binder代理對象與系統(tǒng)服務(wù)對象不是一個。因為AMS運行在system_server進程,此對象運行在 App進程。采用“進程隔離”的方式,每個進程都有自己的 虛擬內(nèi)存地址空間,且每個進程被分配的虛擬內(nèi)存地址都不一樣,這就導(dǎo)致每個進程可訪問的內(nèi)存區(qū)域是不一樣的,進程之間沒有交集,這就避免了 “修改進程A內(nèi)存區(qū)域會影響到進程B內(nèi)存中的數(shù)據(jù)”。

Instrumentation

作用:
1:用于檢測,Application、Activity各個生命周期方法的執(zhí)行。
之所以能檢測,是因為在Instrumentation內(nèi)部的相應(yīng)方法內(nèi)部,會執(zhí)行Application、Activity相應(yīng)生命周期方法的執(zhí)行。
也可以說“Application、Activity各個生命周期方法的執(zhí)行是通過Instrumentation中的相應(yīng)方法來觸發(fā)的”。
2:用于檢測,Activity啟動結(jié)果是否成功。
Activity 通過Intent進行跳轉(zhuǎn)的操作,被封裝到該類的execStartActivity()中去進一步執(zhí)行。
2.1:在啟動目標(biāo)Activity時會通過執(zhí)行該類的execStartActivity()。
2.2:首先,通過AMS.startActivity()啟動目標(biāo)Activity。不論啟動是否成功,都會返回一個int類型的result。
2.3:其次,會通過checkStartActivityResult()來檢查Activity啟動結(jié)果。
返回的啟動結(jié)果在[-100,-1]范圍的話,則會根據(jù)實際的res值拋出相應(yīng)的異常,用于提示此次啟動Activity具體是因為什么問題而導(dǎo)致啟動失敗了。
(像是常見的,Activity沒有在manifest文件注冊導(dǎo)致的拋出ActivityNotFoundException的原因等)。
3:其他使用場景:
3.1:自定義檢測器(這個好像是用于Android 測試的),可以監(jiān)聽Application、Activity的各個生命周期方法調(diào)用。

就像該類的說明一下,此類是“實現(xiàn)應(yīng)用程序檢測代碼的基類”。
要想自定義“檢測器的話”,可以在Manifest文件中通過<instrumentation>指定具體的自定義檢測器。
3.2:可以Hook Instrumentation來達(dá)到監(jiān)聽Application、Activity 的目的。因為它在App進程中是唯一的,Application、Activity各個生命周期方法的執(zhí)行是通過Instrumentation中的相應(yīng)方法來觸發(fā)的。所以說Instrumentation作為Hook點來說是比較“穩(wěn)定”的,因為它在App進程中只有一個實例。


ActivityClientRecord :
  • 在App進程每個Acticity組件都有一個該類的對象來對已啟動Activity組件進行描述。
  • 該類與ActivityRecord相對應(yīng)。
  • 該類存儲在App進程,而ActivityRecord則存儲在SystemServer進程中的AMS中的Activity棧結(jié)構(gòu)中。

Activity

重要屬性:
1:mStartedActivity
作用:該屬性表示“是否啟動了其他Activity”。該屬性只有在Activity的幾個startXX()(
startActivityForResult()、startActivityIfNeeded()、startActivityForResultAsUser()等等)方法被重置為true,默認(rèn)值為false。
1:如果mStartedActivity為true,則表示啟動了其他Activity,進一步則會使當(dāng)前Activity不可見。
2:如果為false,則表示可見。


ThreadedRenderer
StrictMode
最后編輯于
?著作權(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)容