Android消息機制字典型探究(一)
子線程為啥不能更新UI?
本文原創(chuàng),轉(zhuǎn)載請經(jīng)過本人準(zhǔn)許。
寫在前面:
看到Android消息機制這幾個字眼,相信大家腦海中第一時間就浮現(xiàn)出了Handler這個單詞,關(guān)于這個知識點,幾乎是面試必問的問題,重要程度不言而喻。我曾花了大致一周多的時間去研究它,本打算將其有關(guān)的所有知識點完完全全地寫出,但發(fā)現(xiàn)篇幅會過于冗長而影響閱讀。所以準(zhǔn)備拆分成幾個知識點模塊,循序善誘,一步步帶領(lǐng)大家弄清楚Android的消息機制。
既然沒有了篇幅限制,自然可以全面的去講一講有關(guān)Handler的一切,我先來說說當(dāng)時是怎么接觸到Handler這個類的。
在我自學(xué)Android過程中,寫了一個訪問網(wǎng)絡(luò)請求圖片并顯示的Demo,在子線程中我直接給ImageView設(shè)置了圖片,造成了崩潰。崩潰信息如下:
Only the original thread that created a view hierarchy can touch its views.
這個錯誤信息在字面上翻譯過來就是:只有創(chuàng)建視圖層級的原始線程,有權(quán)利處理它的視圖。說白了,就是我們經(jīng)常說的“子線程不能更新UI”。這句話體現(xiàn)了主線程在處理視圖上具有唯一權(quán)力,這也就是為什么主線程也可以稱為UI線程。
在解決這個崩潰問題之前,我對Android中子線程不能更新UI產(chǎn)生了非常大的好奇心。
Google如此設(shè)計的原因是什么呢?
- 表象
我們先從表象上分析一下,假設(shè)可以在子線程更新UI,會產(chǎn)生那些后果呢?
如果不同的線程控制同一塊UI,因為時間的延時性,網(wǎng)絡(luò)的延遲性,很有可能界面圖像會亂套,會花掉。而且出了問題也非常不容易排查問題出在了哪里。從硬件上考慮,每個手機只有一個顯示芯片,根本上不可能同時處理多個繪制請求),減少更新線程數(shù),其實是提高了更新效率。 - 本質(zhì)
如果可以并發(fā)的更新UI,事實上是 “is not thread safe”的,也就是線程不安全。我們都知道,線程安全問題其實就是,不同的線程對同一塊資源的調(diào)用。在更新UI的同時,會涉及context資源的調(diào)用,所以產(chǎn)生了線程安全問題。
相關(guān)閱讀:
所以在Android中是不允許在子線程更新UI的、
本文開了一個小頭,在下一篇中,將討論如何解決本文中的崩潰問題。賣個關(guān)子,一共有三種方式哦,敬請期待~