源碼面試題

1. activity的啟動流程怯疤?

lanuch ->actvitymange->activitymagerservice(ActivityManagerService(AMS)負(fù)責(zé)系統(tǒng)中四大組件的啟動、切換新锈、調(diào)度及應(yīng)用程序的管理和調(diào)度等工作) binder->
Lanuch:也是應(yīng)用,也是一個acitivity
instrumentation:execStartActivity()
activitymanager:產(chǎn)生與IActivityManger, 這個是寫在aidl文件中的類,
activitymangerservice(ams):ActivityManagerService(AMS)負(fù)責(zé)系統(tǒng)中四大組件的啟動兆览、切換、調(diào)度及應(yīng)用程序的管理和調(diào)度等工作,是服務(wù)端進程:中間通過binder機制塞关,Aidl文件抬探。進行顯示還是隱式跳轉(zhuǎn)的判斷
ActivityStackSupervisor:中進行一列的處理,獲取當(dāng)前activity的啟動模式帆赢,當(dāng)前intent是隱式還是顯示小压,暫停正在啟動的頁面砰左,以及啟動activity的進程,啟動前判斷當(dāng)前應(yīng)用的進程是否啟動场航,如果沒有啟動通知ActivityMangerService
Process:打開用來與Zygote進程通信的Socket缠导,
ActivityThread:穿件新進程的時候,執(zhí)行activityThread的main方法溉痢,然后attach到AMS僻造,并將新進程的ApplicationThread對象傳給AMS.
ActivityManagerService:調(diào)用ActivityStackSuperVisor來在新的進程中啟動Activity
ActivityStackSuperVisor:通過applicationThread 啟動acitivity
ApplicationThread:發(fā)送message到ActivityThread中
ActivityThread:處理message,通過反射獲取到需要啟動的acivity和application


為什么Handler能夠跨線程通信孩饼?

Handler的創(chuàng)建與Looper有關(guān)髓削,我們可以在主線程中創(chuàng)建,也可以在子線程中創(chuàng)建镀娶,由于主線程中已經(jīng)創(chuàng)建好了Looper立膛,
首先主線程中會自動創(chuàng)建主線程的loopre對象在ActivityThread中

    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
        // It will be in the format "seq=114"
        long startSeq = 0;
        if (args != null) {
            for (int i = args.length - 1; i >= 0; --i) {
                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
                }
            }
        }
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

在子線程中創(chuàng)建首先調(diào)用 Looper.prepare(),再然后 Looper.loop();具體的

  new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
              Handler handler = new Handler(){
                  @Override
                  public void handleMessage(Message msg) {
                      super.handleMessage(msg);
                      Log.e("info","--->");
                      Toast.makeText(MainActivity.this,"da",Toast.LENGTH_LONG).show();
                  }
              };

                handler.sendEmptyMessage(1);
                Looper.loop();

            }
        }).start();

現(xiàn)在分析為什么主線程創(chuàng)建的Handler,而子線程利用Handler能夠發(fā)送消息到主線程?
前面已經(jīng)說過梯码,主線程會默認(rèn)創(chuàng)建一個主線程的Looper宝泵,當(dāng)我們從子線程handler.sendEmptyMessage(1)消息的時候,知道這個過程是將msg壓入到消息隊列的過程轩娶。當(dāng)msg進入到messagequeue中儿奶,壓入到messagequeue中之前有個msg與handler的綁定關(guān)系“ msg.target = this”,其中這是就是發(fā)送當(dāng)前msg的Handler鳄抒,主線程中默認(rèn)調(diào)用了由于調(diào)用了Looper.looper()方法闯捎。將不斷輪詢其中的msg,最終調(diào)用的處理的地點是msg.target.dispatchMessage(msg);
主要看msg.target這個對象许溅,從上面可知這是發(fā)送當(dāng)前msg的Handler對象瓤鼻。在源碼中msg和Handler有個綁定的關(guān)系。誰發(fā)送的msg贤重,該msg保存發(fā)送Handler的引用茬祷,最后交由這個Handler來處理msg。


Looper中有個無限輪詢消息隊列的操作游桩,為什么沒有導(dǎo)致App沒有報ANR牲迫?

產(chǎn)生ANR的原因有2種:

  • 在指定時間內(nèi)沒有響應(yīng)輸入的事件.
  • 處理響應(yīng)的事件超時耐朴。
    Android程序的入口就是ActivityThread 的main方法借卧,如果main方法執(zhí)行完了,那么應(yīng)用也就執(zhí)行完了筛峭,所以looper是無限循環(huán)是有必要的铐刘,不然程序會自動退出。所以在Android中其他的所有操作都是在這個無限循之內(nèi)影晓。looper.loop()理論上可能會造成堵塞镰吵,所說的堵塞是指處理事件不夠快檩禾,就不會造成ANR,Looper.loop()本身是不會堵塞的疤祭。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盼产,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子勺馆,更是在濱河造成了極大的恐慌戏售,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件草穆,死亡現(xiàn)場離奇詭異灌灾,居然都是意外死亡,警方通過查閱死者的電腦和手機悲柱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門锋喜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人豌鸡,你說我怎么就攤上這事嘿般。” “怎么了涯冠?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵博个,是天一觀的道長。 經(jīng)常有香客問我功偿,道長朽缴,這世上最難降的妖魔是什么捡需? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上普舆,老公的妹妹穿的比我還像新娘。我一直安慰自己仪芒,他們只是感情好蛮粮,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著颤诀,像睡著了一般字旭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上崖叫,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天遗淳,我揣著相機與錄音,去河邊找鬼心傀。 笑死屈暗,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播养叛,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼种呐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弃甥?” 一聲冷哼從身側(cè)響起爽室,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎淆攻,沒想到半個月后肮之,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡卜录,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年戈擒,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艰毒。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡筐高,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丑瞧,到底是詐尸還是另有隱情柑土,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布绊汹,位于F島的核電站稽屏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏西乖。R本人自食惡果不足惜狐榔,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望获雕。 院中可真熱鬧薄腻,春花似錦、人聲如沸届案。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽楣颠。三九已至尽纽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間童漩,已是汗流浹背弄贿。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留睁冬,地道東北人挎春。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓看疙,卻偏偏與公主長得像豆拨,于是被迫代替她去往敵國和親直奋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359