ActivityThread

我們學(xué)習(xí) Android 過(guò)程中會(huì)發(fā)現(xiàn)讹挎,我們的文件都是 .java 文件,也就是說(shuō) Android 開(kāi)發(fā)還是用的 Java 語(yǔ)言來(lái)編寫(xiě)的薯鳍。也正是這樣对扶,所以你們來(lái)學(xué) Android ,也會(huì)讓你們先學(xué)習(xí)一段時(shí)間 Java 菜谣。掌握好了 Java 的相關(guān)知識(shí)珠漂,學(xué)起 Android 來(lái)可謂是事半功倍。好了尾膊,你們是不是感覺(jué)有點(diǎn)扯遠(yuǎn)了啊媳危,不是說(shuō)好講 ActivityThread 類的么,其實(shí)并不如此冈敛。

你們?cè)趧傞_(kāi)始從 Java 學(xué)習(xí)轉(zhuǎn)到 Android 學(xué)習(xí)的過(guò)程中待笑,有一個(gè)重大的改變不知道你們又沒(méi)有發(fā)現(xiàn)。那就是 Java 中的 main() 方法抓谴,程序的入口不見(jiàn)了暮蹂,取而代之的是 onCreate() 方法。你們沒(méi)有一點(diǎn)疑惑么癌压?初學(xué)階段直接無(wú)腦接受是對(duì)的仰泻,但是作為一個(gè)工作幾年了的人來(lái)說(shuō),就有必要去深入研究一下了滩届。明明 Android 也就是 Java 語(yǔ)言也編寫(xiě)的集侯,差別咋就這么大呢?

其實(shí)呢丐吓, Android 中還是有 main() 方法的浅悉,只是隱藏的比較深而已。今天券犁,就由我 AIqingfeng 來(lái)帶你們一探究竟~术健!

我們先找到 ActivityThread 這個(gè)類,看一下注釋(較少粘衬,值得一看):

This manages the execution of the main thread in an
application process, scheduling and executing activities,
broadcasts, and other operations on it as the activity
manager requests.

翻譯一下就是:在 Application 進(jìn)程中管理執(zhí)行主線程荞估,調(diào)度和執(zhí)行 活動(dòng)和廣播咳促,和活動(dòng)管理請(qǐng)求的其它操作。

一勘伺、入口

Android 上一個(gè)應(yīng)用的入口跪腹,應(yīng)該是 ActivityThread 類,和普通的Java 類一樣飞醉,入口是一個(gè) main() 方法冲茸。

public static void main(String[] args) {
    // 看源碼很重要的一個(gè)能力就是‘眼中只有你’,認(rèn)不到的都忽略缅帘,看認(rèn)得到的
    ···
    // 創(chuàng)建主線程的Looper對(duì)象轴术,發(fā)現(xiàn)和工作線程創(chuàng)建Looper對(duì)象調(diào)用的方法不一樣,這里先記下钦无,以后在詳解逗栽。
    // 主線程原來(lái)也有Looper對(duì)象啊
    Looper.prepareMainLooper();

    // 這里創(chuàng)建了一個(gè)活動(dòng)線程,也就是我們的主線程失暂。
    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    // 如果主線程的Handler為空(可以看出彼宠,一個(gè)好的命名可讀性是多么高),那就為主線程創(chuàng)建一個(gè)Handler弟塞。
    // 然后我們還可以在主線程創(chuàng)建Handler凭峡,說(shuō)明一個(gè)線程對(duì)應(yīng)多個(gè)Handler。多讀源碼宣肚,很多問(wèn)題都得到了解決啊想罕。
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    Looper.loop();
    
    // 這里拋了個(gè)異常霉涨,主線程loop異常退出按价。說(shuō)明主線程loop不能退出,這里和前面建立Looper對(duì)象的調(diào)用方法有關(guān)
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

二笙瑟、變量

好了楼镐,現(xiàn)在我們解決了我們開(kāi)始的疑惑后,再來(lái)深度學(xué)習(xí)一下這個(gè)類的一些知識(shí)吧往枷。

ActivityThread 有幾個(gè)比較重要的成員變量框产,會(huì)在創(chuàng)建ActivityThread對(duì)象時(shí)初始化。

final ApplicationThread mAppThread = new ApplicationThread();

ApplicationThread繼承自ApplicationThreadNative错洁, 而ApplicationThreadNative又繼承自Binder并實(shí)現(xiàn)了IApplicationThread接口秉宿。IApplicationThread繼承自IInterface。這是一個(gè)很明顯的binder結(jié)構(gòu)屯碴,用于與Ams通信描睦。IApplicationThread接口定義了對(duì)一個(gè)程序(Linux的進(jìn)程)操作的接口。ApplicationThread通過(guò)binder與Ams通信导而,并將Ams的調(diào)用忱叭,通過(guò)下面的H類(也就是Hnalder)將消息發(fā)送到消息隊(duì)列隔崎,然后進(jìn)行相應(yīng)的操作,入activity的start韵丑, stop爵卒。

final H mH = new H();

這個(gè) H 大家首先會(huì)想到什么啊,不要開(kāi)車哈撵彻〉鲋辏看到 H 想到了 Handler 。發(fā)現(xiàn) HActivityThread 內(nèi)部類千康,繼承自 Handler 享幽,果然沒(méi)錯(cuò)。所以大家遇到不清楚的拾弃,不要怕,大膽的猜測(cè)一下摆霉。Handler 最重要的的也就是 handleMessage() 方法了豪椿。查看一下其方法:

ActivityThread.java

public void handleMessage(Message ms ) {
    switch (msg.what) {
        // 呀哈,這些看著和 onCreate() 携栋、onResume() 搭盾、onStop() 方法有很大關(guān)系啊。
        case LAUNCH_ACTIVITY: {
            // 處理加載活動(dòng)婉支,這里進(jìn)去就可以得到答案啦鸯隅。
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
        } break;
        case RESUME_ACTIVITY:
        case STOP_ACTIVITY:
    }
}

點(diǎn)進(jìn)來(lái)咯。 ActivityThread.java

private void handleLaunchActivity(···) {
    // 執(zhí)行加載活動(dòng)向挖,返回一個(gè)活動(dòng)對(duì)象蝌以。有興趣可以在進(jìn)去看看。
    Activity a = performLaunchActivity(r, custonIntent);
}

興趣是最好的老師何之。ActivityThread.java

private Activity performLaunchActivity(···) {
    Activity activity = null;
    try {
         // 活動(dòng)在這里被創(chuàng)建跟畅,還可以進(jìn)去看看。認(rèn)不到的單詞google一下溶推,Instrumentation : 儀器徊件。
         activity = mInstrumentation.newActivity(···);
    }
    if (r.isPersistable()) {
                    // 看名字就感覺(jué)調(diào)用了 Activity 的 onCreate() 方法
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
}

先探索一下 Activity 創(chuàng)建這條路吧。最底層啦蒜危。Instrumentation.java

public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, illegalAccessException, ClassNotFoundException {
    // 類加載器根據(jù)類名創(chuàng)建了一個(gè)實(shí)例虱痕。再下去就是native方法了。
    return (Activity) cl.loadClass(className).newInstance();
}

Native方法辐赞,C語(yǔ)言啦部翘,活動(dòng)創(chuàng)建之路結(jié)束了。Class.java

public native T newInstance() throws InstantiationException, IllegalAccessException;

再來(lái)看看 Activity 中 onCreate() 方法執(zhí)行之路吧占拍。 Instrumentation.java

public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        // pre: 前略就,執(zhí)行 Create 操作之前
        prePerformCreate(activity);
        // 執(zhí)行 Create 操作
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }

到了 Activity 了捎迫,哪里我們自己 Activity 還遠(yuǎn)么~! Activity.java

final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        // 哼哼表牢,終于找到你了窄绒,onCreate() 方法。
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

來(lái)崔兴,仔細(xì)瞅瞅~彰导! Activity.java

@MainThread // 主線程
@CallSuper // 必須調(diào)用super.onCreate(bundle);
protected void onCreate(@Nullable Bundle savedInstanceState) {
            // 看這里,是不是我們恢復(fù)數(shù)據(jù)那些操作啊敲茄,看看源碼怎么寫(xiě)的~位谋!
            if (savedInstanceState != null) {
            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
            // Activity 中管理的 Fragment
            mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
                    ? mLastNonConfigurationInstances.fragments : null);
        }
       // 分發(fā) Create 操作
        mFragments.dispatchCreate();
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市堰燎,隨后出現(xiàn)的幾起案子掏父,更是在濱河造成了極大的恐慌凉倚,老刑警劉巖躏率,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異碴裙,居然都是意外死亡仅讽,警方通過(guò)查閱死者的電腦和手機(jī)陶缺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)洁灵,“玉大人饱岸,你說(shuō)我怎么就攤上這事』涨В” “怎么了苫费?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)罐栈。 經(jīng)常有香客問(wèn)我黍衙,道長(zhǎng),這世上最難降的妖魔是什么荠诬? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任琅翻,我火速辦了婚禮,結(jié)果婚禮上柑贞,老公的妹妹穿的比我還像新娘方椎。我一直安慰自己,他們只是感情好钧嘶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布棠众。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪闸拿。 梳的紋絲不亂的頭發(fā)上空盼,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音新荤,去河邊找鬼揽趾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛苛骨,可吹牛的內(nèi)容都是我干的篱瞎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼痒芝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼俐筋!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起严衬,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤澄者,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后瞳步,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體闷哆,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年单起,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劣坊。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嘀倒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出局冰,到底是詐尸還是另有隱情测蘑,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布康二,位于F島的核電站碳胳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏沫勿。R本人自食惡果不足惜挨约,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望产雹。 院中可真熱鬧诫惭,春花似錦、人聲如沸蔓挖。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瘟判。三九已至怨绣,卻和暖如春角溃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背篮撑。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工减细, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人咽扇。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓邪财,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親质欲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子树埠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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