冷啓動建立應用時,ActivityThread的主要方法:服務器
- main()
-- 1. 開啓消息循環
-- 2. 通知ActivityManagerService
-- 3. 添加GCWatcher- handleBindApplication()
-- 1. 建立LoadedApk
-- 2. 建立Instrumentation
-- 3. 建立Application
-- 4. 經過Instrumentation調用Application的onCreate()方法
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(); } } } }); ... }
ActivityManagerService=AMS
handleBindApplication的被調用時機是:對象
- 經過上面AMS.attachApplication()後,AMS得到了控制應用的Binder對象ApplicationThread。
- AMS進行了一系列操做後(這裏先省略),調用了ApplicationThread的bindApplication()
- 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); ... }
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); ... }