這里介紹一些Android的一些冷知識(shí)。
App進(jìn)程是從哪里開(kāi)始啟動(dòng)的
ActivityManagerService類(lèi)的源碼在Sdk里有,是Android中最核心的服務(wù)之一,負(fù)責(zé)系統(tǒng)中四大組件的啟動(dòng)、切換、調(diào)度及應(yīng)用進(jìn)程的管理和調(diào)度等等工作。這個(gè)類(lèi)是運(yùn)行在系統(tǒng)進(jìn)程里,由系統(tǒng)管理,通過(guò)跨進(jìn)程通信的方式與我們的App進(jìn)行通信。這個(gè)類(lèi)有個(gè)方法
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
......
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
......
}
我們的App進(jìn)程最初就是由這個(gè)方法創(chuàng)建的。
App的入口方法在哪里?
任何語(yǔ)言寫(xiě)的任何程序都會(huì)有執(zhí)行入口。Android App的入口是ActivityThread的main方法。具體定義是在ActivityManagerService的startProcessLocked方法里。
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
......
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
checkTime(startTime, "startProcess: returned from zygote!");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
......
}
if (entryPoint == null) entryPoint = "android.app.ActivityThread";這一行定義了App的入口類(lèi)。
App創(chuàng)建Activity的地方在哪里
創(chuàng)建Activity的消息是從ActivityManagerService通過(guò)跨進(jìn)程通信的方式發(fā)送到
-> ApplicationThread
-> scheduleLaunchActivity
mH->handleMessage -> LAUNCH_ACTIVITY
-> handleLaunchActivity
-> performLaunchActivity
-> mInstrumentation.newActivity
-> (Activity)cl.loadClass(className).newInstance();
最終通過(guò)反射的方式創(chuàng)建出了Activity實(shí)例。
Activity實(shí)例引用被誰(shuí)持有?
Activity創(chuàng)建了實(shí)例對(duì)象后,肯定會(huì)被某個(gè)對(duì)象持有,否則引用計(jì)數(shù)為0后,Activity實(shí)例就會(huì)被GC回收掉。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity activity = null;
......
activity = mInstrumentation.newActivity(cl,component.getClassName(), r.intent);
......
r.activity = activity;
mActivities.put(r.token, r);
......
}
Activity在創(chuàng)建之后就被mActivities持有。mActivities被ActivityThread持有。ActivityThread對(duì)象是在App的入口main方法實(shí)例化的。main方法除非進(jìn)程被殺死否則main是不會(huì)結(jié)束的。
public static void main(String[] args) {
......
ActivityThread thread = new ActivityThread();
......
}
Activity實(shí)例什么時(shí)候被銷(xiāo)毀?
前面說(shuō)到Activity被ActivityThread的mActivities持有。那什么時(shí)候Activity實(shí)例被銷(xiāo)毀呢?說(shuō)到銷(xiāo)毀大家可能會(huì)想到Activity生命周期的onDestory方法。
-> ApplicationThread
-> scheduleDestroyActivity
mH->handleMessage -> DESTROY_ACTIVITY
-> handleDestroyActivity
-> performDestroyActivity
// 從這里繼續(xù)會(huì)執(zhí)行到Activity的onDestory方法
-> mInstrumentation.callActivityOnDestroy(r.activity);
// Activity實(shí)例從mActivities被移除
-> mActivities.remove(token);
當(dāng)Activity實(shí)例從mActivities里移除后,如果當(dāng)前Activity實(shí)例沒(méi)有被其他對(duì)象強(qiáng)引用或者說(shuō)Activity沒(méi)有內(nèi)存泄漏,那么下次GC的時(shí)候Activity實(shí)例就會(huì)被銷(xiāo)毀掉。