Application的孵化

眾所周知摇零,Android 中的用戶進程是由 Zygote 孵化的。通知Zygote fork()進程是在 ActivityManagerService 中胃珍,同時 Zygote 與 ActivityManagerService是用過 socket 通信的耍休。
詳見Zygote進程及其孵化子進程

當子進程fork 后灶泵,會調(diào)用ActivityThread.main(String[ ]),這部分是在子進程补箍,即 app 進程運行的改执;

//android.app.ActivityThread

public static void main(String[] args){
  ...
  //現(xiàn)在還不知道這個用戶進程的名字
  Process.setArgVo("<pre-initialized>");
  //這個就是傳說中的主線程了,開啟了一個 looper
  Looper.prepareMainLooper();
  //構(gòu)造函數(shù)比較簡單坑雅,只是單純的創(chuàng)造了mResourceManager=ResourceManager.getInstance()
  ActivityThread thread = new ActivityThread();
  //system=false
  thread.attach(false);
  
  if(sMainThreadHandler == null){
    //這個就是 H 類辈挂,用以處理啟動 activity 等消息的 Handler
    sMainThreadHandler = thread.getHandler();
  }

   Lopper.loop();
}
private void attach(boolean system){
  //這東西是整個應(yīng)用的單例,并且是 static 的裹粤,經(jīng)常作為黑科技的 hook 點
  sCurrentActivityThread = this;
  mSystemThread = system;//這里是 false终蒂,表示是普通的進程
  if(!system){
    //與 AMS binder 通信,執(zhí)行system_server中 AMS 的attachApplication()
    final IActivityManager mgr = ActivityManagerNative.getDefault();
    //mAppThread 是 ApplicationThread 類遥诉,包含很多可以和mH 通訊的方法,是進行 Binder 通信的
    mrg.attachApplication(mAppThread);
    ...
  }else{
    //系統(tǒng)應(yīng)用拇泣,不關(guān)心
    ...
  }
}

轉(zhuǎn)到 AMS:

//AMS
public final void attachApplication(IApplicationThread thread){
  //Binder.getCallingPid(),獲得調(diào)用該方法的進程 id,在本例中就是這個用戶 app
  int callingPid = Binder.getCallingPid();
  attachApplicationLocked(thread, callingPid);
}
private final boolean attachApplicationLocked(IApplicationThread thread, int pid){
  // 獲取進程相關(guān)的信息
  ProcessRecord app = mPidSelfLocked.get(pid);
  ...
  //binder 通信矮锈,又回到了用戶 app
  //通過AMS 獲得用戶進程相關(guān)信息霉翔,并且恰當?shù)姆祷亟o用戶進程
  thread.bindApplication(...);
  ...
  //這里會啟動 app 的 launcher Activity
  if(mStackSupervisor.attachApplicationLocker(app)){
  ...
  }
}
//bindApplication(...)@ActivityThread$ApplicationThread
public final void bindApplication(...N 多參數(shù),與當前進程相關(guān)){
  //獲得該進程相關(guān)的 PackageInfo
  IPackageManager pm = getPackageManager();
  android.content.pm.PackageInfo pi = pm.getPackageInfo(appInfo.packageName,0,UserHandler,myUserId);
  
  AppBindData data = new AppBindData();
  {通過AMS返回的數(shù)據(jù)組裝用戶進程需要的 AppBindData}
  ..sendMessage(H.BINDER_APPLICATION,data);
}

mH分發(fā)苞笨,調(diào)用handleBinderApplication(AppBindData)@ActivityThread
``
private void handleBindApplication(AppBindData data){
// 終于正確設(shè)置了進程名
android.ddm.DdmHandleAppName.setAppName(data.processName,UserHandle.myUserId());

final ContextImpl appContext = ContextImpl.createAppContext(this,data.info);
...
ContextImpl instrContext = Context.createAppContext(this, pi);
//創(chuàng)建關(guān)鍵管家類 Instrumentation
java.lang.ClassLoader cl=instrContext.getClassLoader();
mInstrumentation = (Instrumentation)cl.loadClass(data.instrumentionName.getClassName()).newInstance();
mInstrumentation.init(...);
}
...
//里面通過反射創(chuàng)建 Application债朵,并且創(chuàng)建一個 ContextImpl 綁定到 app 上
Application app = data.info.makeApplication(data.restrictedBackupMpde,null)
...
//調(diào)用onCreate()@Application
mInstrumentation.callApplicationOnCreate(app);


//以上,在用戶進程完成了當前進程相關(guān)的信息的查詢以及綁定瀑凝,并且生成了上下文 Instrumentation與Application兩個重要的類序芦。

//接下里另外一條線進行 Launcher Activity的啟動了

//attachApplicationLocker(AppliationThread)@ActivityStackSupervisor

boolean attachApplication(ProcessRecord app){
ActivityRecord hr = stack.topRunningActivityLocaked(null);
//關(guān)鍵
realStartActivityLocked(hr, app, true, true);
}

final boolean readlStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig){
//只看關(guān)鍵一句
//app.thread是用戶進程 ApplicationThread binder對象
app.thread.scheduleLaunchActivity(...);
}

又回到了用戶進程,scheduleLanchActivity()@ActivityThread$ApplicationThread

public final void scheduleLaunchActivity(...){
ActivityClientRecord r = new ActivityClientRecord();
{組裝 ActivityClientRecord 信息}
sendMessage(H.LAUNCH_ACTIVITY,r);
}


H

{
handleLaunchaerActivity(ActivityClientRecord r,null);
}


//ActivityThread
private void handleLaunchActivity(ActivityClientRecord r,Intent customIntent){
// 生成 Activity 并且初始化
Activity a = performLaunchActivity(r, customIntent);
//調(diào)用onRestart() ,onStart()與 onResume()
handleResumeActivity(...);
}


private Activity performLaunchActivity(ActivityClientRecord r,Intent customIntent){
//反射生成 Activity
Activity activity=mInstrumentation.newActivity(clmcomponent.getClassName(),r.intent);
//單例,即App 的 Application
Application App=r.packageInfo.makeAppliction(falsemmInstrumentation)粤咪;
//實例化一個 ContextImpl
Context appContext = createBaseContextForActivity(r, activity);
//綁定到 activity谚中,也可以看到 Instrumentation 是共享的
//調(diào)用 attach(Context)@activity
activity.attach(appContext,this,getInstrumentation()...);
//onCreate()@Activity生命周期
mInstrumentation.callActivityOnCreate();
//onPostCreate()@Activity生命周期
//mInstrumentation.callActivityOnPostCreate();
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子藏杖,更是在濱河造成了極大的恐慌将塑,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝌麸,死亡現(xiàn)場離奇詭異点寥,居然都是意外死亡,警方通過查閱死者的電腦和手機来吩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門敢辩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人弟疆,你說我怎么就攤上這事戚长。” “怎么了怠苔?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵同廉,是天一觀的道長。 經(jīng)常有香客問我柑司,道長迫肖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任攒驰,我火速辦了婚禮蟆湖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘玻粪。我一直安慰自己隅津,他們只是感情好,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布劲室。 她就那樣靜靜地躺著伦仍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪痹籍。 梳的紋絲不亂的頭發(fā)上呢铆,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音蹲缠,去河邊找鬼棺克。 笑死,一個胖子當著我的面吹牛线定,可吹牛的內(nèi)容都是我干的娜谊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼斤讥,長吁一口氣:“原來是場噩夢啊……” “哼锅减!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起纺非,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搀缠,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體近迁,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡艺普,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鉴竭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歧譬。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖搏存,靈堂內(nèi)的尸體忽然破棺而出瑰步,到底是詐尸還是另有隱情,我是刑警寧澤璧眠,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布缩焦,位于F島的核電站,受9級特大地震影響蛆橡,放射性物質(zhì)發(fā)生泄漏舌界。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一泰演、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧葱轩,春花似錦睦焕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至袜炕,卻和暖如春本谜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背偎窘。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工乌助, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人陌知。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓他托,卻偏偏與公主長得像,于是被迫代替她去往敵國和親仆葡。 傳聞我的和親對象是個殘疾皇子赏参,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容