讀Android源碼-冷啓動時的ActivityThread

 

冷啓動建立應用時,ActivityThread的主要方法:服務器

  1. main()
    -- 1. 開啓消息循環
    -- 2. 通知ActivityManagerService
    -- 3. 添加GCWatcher
  2. handleBindApplication()
    -- 1. 建立LoadedApk
    -- 2. 建立Instrumentation
    -- 3. 建立Application
    -- 4. 經過Instrumentation調用Application的onCreate()方法

main()

main方法是一個應用建立的入口,他主要作了3件事app

1. 開啓消息循環ide

調用Looper.prepareLoop() Looper.loop(),開啓主線程的消息循環,以便於ApplicationThread調用ActivityThread中的生命週期方法。oop

public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

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

2. 通知ActivityManagerServicethis

調用ActivityThread.attach()方法,attach()方法在調用了attachApplication()將ApplicationThread這個Binder交給了ActivityManagerService,意味着ActivityManagerService能夠經過ApplicationThread控制咱們的應用,創建了服務器端對客戶端的通訊渠道。spa

private void attach(boolean system){
    ...
    final IActivityManager mgr = ActivityManager.getService();
    try {
        mgr.attachApplication(mAppThread);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
    ...
}

SDK26之後,去除了Native和Proxy,而是直接從ActivityManager(ServiceManager)中獲取ActivityManagerService的Binder對象進行通訊線程

3. 添加GCWatcherrest

在attach()方法中,添加了監聽dialvik內存使用狀況得監聽者GcWatcher,當內存使用超過總容量的3/4,則打印Log進行記錄,而且調用ActivityManagerService的releaseSomeActivities()進行內存釋放操做,以防止內存溢出致使應用崩潰。code

private void attach(boolean system){
    ...
    BinderInternal.addGcWatcher(new Runnable() {
        @Override public void run() {
            if (!mSomeActivitiesChanged) {
                return;
            }
            Runtime runtime = Runtime.getRuntime();
            long dalvikMax = runtime.maxMemory();
            long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
            if (dalvikUsed > ((3*dalvikMax)/4)) {
                if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                        + " total=" + (runtime.totalMemory()/1024)
                        + " used=" + (dalvikUsed/1024));
                mSomeActivitiesChanged = false;
                try {
                    mgr.releaseSomeActivities(mAppThread);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
        }
    });
    ...
}

handleBindApplication()

ActivityManagerService=AMS
handleBindApplication的被調用時機是:對象

  1. 經過上面AMS.attachApplication()後,AMS得到了控制應用的Binder對象ApplicationThread。
  2. AMS進行了一系列操做後(這裏先省略),調用了ApplicationThread的bindApplication()
  3. bindApplication中經過消息機制,sendMessage到ActivityThread,調用了ActivityThread的handleBindApplication()

handleBindApplication是建立用於所需組件的入口,他主要作了4件事:

1. 建立LoadedApk

LoadedApk對象包含應用的全部信息

private void handleBindApplication(AppBindData data){
    ...
    final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                    appContext.getClassLoader(), false, true, false);
    ...
}

2. 建立Instrumentation

Instrumentation是應用組件的管家,組件的生命週期方法都須要經過它來調用,是客戶端與服務器端通訊的最後一步。

private void handleBindApplication(AppBindData data){
    ...
    final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
    try {
        final ClassLoader cl = instrContext.getClassLoader();
        mInstrumentation = (Instrumentation)
            cl.loadClass(data.instrumentationName.getClassName()).newInstance();
    } catch (Exception e) {
        throw new RuntimeException(
            "Unable to instantiate instrumentation "
            + data.instrumentationName + ": " + e.toString(), e);
    }
    ...
}

3. 建立Application

調用了LoadedApk.makeApplication()進行Application的建立

private void handleBindApplication(AppBindData data){
    ...
    app = data.info.makeApplication(data.restrictedBackupMode, null);
    ...
}
  • 先經過ContextImpl.createAppContext()得到Application的Context
  • 再經過Instrumentation.newApplication(),用ClassLoder建立Applicaition
  • 建立後Applicaition調用自身的attach(Context)方法,將Context與Applicaition綁定,完成建立
LoadedApk.class
public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
    ...
    Application app = null;
    ...
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    app = mActivityThread.mInstrumentation.newApplication(
            cl, appClass, appContext);
    ...
    return app;
}

4. 經過Instrumentation調用Application的onCreate()方法

private void handleBindApplication(AppBindData data){
    ...
    mInstrumentation.callApplicationOnCreate(app);
    ...
}
相關文章
相關標籤/搜索