前言:
應(yīng)用冷啟動(dòng)時(shí)需要?jiǎng)?chuàng)建進(jìn)程,開(kāi)啟主線程娄琉,實(shí)例化應(yīng)用所需組件次乓。
讀ActivityThread源碼有助于我們了解這個(gè)過(guò)程中,客戶端做的那些事孽水。
冷啟動(dòng)創(chuàng)建應(yīng)用時(shí)票腰,ActivityThread的主要方法:
- main()
-- 1. 開(kāi)啟消息循環(huán)
-- 2. 通知ActivityManagerService
-- 3. 添加GCWatcher- handleBindApplication()
-- 1. 創(chuàng)建LoadedApk
-- 2. 創(chuàng)建Instrumentation
-- 3. 創(chuàng)建Application
-- 4. 通過(guò)Instrumentation調(diào)用Application的onCreate()方法
main()
main方法是一個(gè)應(yīng)用創(chuàng)建的入口,他主要做了3件事
1. 開(kāi)啟消息循環(huán)
調(diào)用Looper.prepareLoop() Looper.loop()女气,開(kāi)啟主線程的消息循環(huán)杏慰,以便于ApplicationThread調(diào)用ActivityThread中的生命周期方法。
public static void main(String[] args) {
...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
Looper.loop();
}
2. 通知ActivityManagerService
調(diào)用ActivityThread.attach()方法炼鞠,attach()方法在調(diào)用了attachApplication()將ApplicationThread這個(gè)Binder交給了ActivityManagerService缘滥,意味著ActivityManagerService可以通過(guò)ApplicationThread控制我們的應(yīng)用,建立了服務(wù)器端對(duì)客戶端的通信渠道谒主。
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對(duì)象進(jìn)行通信
3. 添加GCWatcher
在attach()方法中霎肯,添加了監(jiān)聽(tīng)dialvik內(nèi)存使用情況得監(jiān)聽(tīng)者GcWatcher擎颖,當(dāng)內(nèi)存使用超過(guò)總?cè)萘康?/4凹耙,則打印Log進(jìn)行記錄,并且調(diào)用ActivityManagerService的releaseSomeActivities()進(jìn)行內(nèi)存釋放操作肠仪,以防止內(nèi)存溢出導(dǎo)致應(yīng)用崩潰。
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的被調(diào)用時(shí)機(jī)是:
- 通過(guò)上面AMS.attachApplication()后备典,AMS獲得了控制應(yīng)用的Binder對(duì)象ApplicationThread异旧。
- AMS進(jìn)行了一系列操作后(這里先省略),調(diào)用了ApplicationThread的bindApplication()
- bindApplication中通過(guò)消息機(jī)制提佣,sendMessage到ActivityThread吮蛹,調(diào)用了ActivityThread的handleBindApplication()
handleBindApplication是創(chuàng)建用于所需組件的入口,他主要做了4件事:
1. 創(chuàng)建LoadedApk
LoadedApk對(duì)象包含應(yīng)用的所有信息
private void handleBindApplication(AppBindData data){
...
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
...
}
2. 創(chuàng)建Instrumentation
Instrumentation是應(yīng)用組件的管家拌屏,組件的生命周期方法都需要通過(guò)它來(lái)調(diào)用潮针,是客戶端與服務(wù)器端通信的最后一步。
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. 創(chuàng)建Application
調(diào)用了LoadedApk.makeApplication()進(jìn)行Application的創(chuàng)建
private void handleBindApplication(AppBindData data){
...
app = data.info.makeApplication(data.restrictedBackupMode, null);
...
}
- 先通過(guò)ContextImpl.createAppContext()獲得Application的Context
- 再通過(guò)Instrumentation.newApplication()倚喂,用ClassLoder創(chuàng)建Applicaition
- 創(chuàng)建后Applicaition調(diào)用自身的attach(Context)方法每篷,將Context與Applicaition綁定,完成創(chuàng)建
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. 通過(guò)Instrumentation調(diào)用Application的onCreate()方法
private void handleBindApplication(AppBindData data){
...
mInstrumentation.callApplicationOnCreate(app);
...
}
更新中...