1彪薛、handler是什么?
? ? ? ? handler是更新UI界面的機制怠蹂,也是消息處理的機制,我們可以發(fā)送消息善延,也可以處理消息
2、為什么要有Handler城侧?
? ? ? ? Android在設計的時候易遣,封裝了一套消息創(chuàng)建、傳遞嫌佑、處理機制豆茫,如果不遵循這樣的機制就沒辦法更新UI信息侨歉,就會拋出異常。
3揩魂、handler怎么用为肮?
? ? ? ? 1、post(Runnable);
? ? ? ? ?2肤京、postDelayed(Runnable ,long);
? ? ? ? ?3颊艳、sentMessage
? ? ? ? ?4、sentMessageDelayed
4忘分、Android為什么要設置只能通過Handler機制更新UI棋枕?
? ? ? ? ? ?最根本的問題解決多線程并發(fā)的問題;
? ? ? ? ?假設如果在一個Activity中妒峦,有多個線程去更新UI重斑,并且都沒有加鎖機制,馬么會產(chǎn)生生么樣的 ? ? ? ? ?問題肯骇?——更新界面混亂窥浪;
? ? ? ? 如果對更新UI 的操作都加鎖處理的話會產(chǎn)生什么樣子的問題?——性能下降
? ? ? ? ?對于上述問題的考慮笛丙,Android提供了一套更新UI的機制漾脂,我們只需要遵循這樣的機制就好 ? ? ? ? ? ? ? ? 了。
? ? ? ? 不用關心多線程的問題胚鸯,更新UI的操作骨稿,都是在主線程的消息隊列當中輪詢處理的。
5姜钳、handler的原理是什么坦冠?
? ? ? ? ?1、handler封裝消息的發(fā)送(主要包括消息發(fā)送給誰)
? ? ? ? ?2哥桥、Looper——消息封裝的載體辙浑。(1)內(nèi)部包含一個MessageQueue,所有的Handler發(fā)送的 ? ? ? ? ? ? ? ? 消息都走向這個消息隊列拟糕;(2)Looper.Looper方法判呕,就是一個死循環(huán),不斷地從 ? ? ? ? ? ? ? ? ? ? ? ? ? MessageQueue取消息已卸,如果有消息就處理消息佛玄,沒有消息就阻塞。
? ? ? ? 3累澡、MessageQueue梦抢,一個消息隊列,添加消息愧哟,處理消息
? ? ? ? ?4奥吩、handler內(nèi)部與Looper關聯(lián)哼蛆,handler->Looper->MessageQueue,handler發(fā)送消息就是向 ? ? ? ? ? ? ? ? ? MessageQueue隊列發(fā)送消息。
? ? ? ? ? ? ?總結:handler負責發(fā)送消息霞赫,Looper負責接收handler發(fā)送的消息腮介,并把消息回傳給handler ? ? ? ? ? ? ?自己。
? ? ? ? ? ? ? MessageQueue存儲消息的容器端衰。
6叠洗、HandlerThread的作用是什么?
? ? ? ? ? ? HandlerThread thread=new HandlerThread("handler thread");自動含等待機制旅东,等Looper創(chuàng)建好了灭抑,才創(chuàng)建Handler,避免出現(xiàn)空指針異常抵代。
7腾节、主線程
? ? ? ? ?* ActivityThread 默認創(chuàng)建main線程,main中默認創(chuàng)建Looper荤牍,Looper默認創(chuàng)建 ? ? ? ? ? ? ? ? ? ?MessageQueue
?* threadLocal保存線程的變量信息案腺,方法包括:set,get
8康吵、Android更新UI的方式劈榨?
? ? ? ? ? 1、runOnUIThread
? ? ? ? ? ?2涎才、handler post
? ? ? ? ? 3鞋既、handler sendMessage
? ? ? ? ? ?4、view post
9耍铜、非UI線程真的不能更新UI嗎?
? ? ? ?不一定跌前,之所以子線程不能更新界面棕兼,是因為Android在線程的方法里面采用checkThread進行判斷是否是主線程,而這個方法是在ViewRootImpl中的抵乓,這個類是在onResume里面才生成的伴挚,因此,如果這個時候子線程在onCreate方法里面生成更新UI灾炭,而且沒有做阻塞茎芋,就是耗時多的操作,還是可以更新UI的蜈出。
10田弥、使用Handler遇到的問題?
? ? ? 比如說子線程更新UI铡原,是因為觸發(fā)了checkThread方法檢查是否在主線程更新UI偷厦,還有就是子線程中沒有Looper商叹,這個原因是因為Handler的機制引起的,因為Handler發(fā)送Message的時候只泼,需要將Message放到MessageQueue里面剖笙,而這個時候如果沒有Looper的話,就無法循環(huán)輸出MessageQueue了请唱,這個時候就會報Looper為空的錯誤弥咪。
11滤灯、主線程怎么通知子線程纺座?
? ? ? 可以利用HandlerThread進行生成一個子線程的Handler镜悉,并且實現(xiàn)handlerMessage方法诲泌,然后在主線程里面也生成一個Handler恬叹,然后通過調(diào)用sendMessage方法進行通知子線程识樱。同樣迂烁,子線程里面也可以調(diào)用sendMessage方法進行通知主線程恭陡。這樣做的好處比如有些圖片的加載啊勋功,網(wǎng)絡的訪問啊可能會比較耗時坦报,所以放到子線程里面做是比較合適的。
12狂鞋、Handler的工作原理
? ? 一般情況下片择,在主線程中我們綁定了Handler,并在事件觸發(fā)上面創(chuàng)建新的線程用于完成某些耗時的操作骚揍,當子線程中的工作完成之后字管,會對Handler發(fā)送一個完成的信號,而Handler接收到信號后信不,就進行主UI界面的更新操作嘲叔。
andriod提供了 Handler 和 Looper 來滿足線程間的通信。
Handler 先進先出原則抽活。
Looper類用來管理特定線程內(nèi)對象之間的消息交換硫戈。
1)Looper: 一個線程可以產(chǎn)生一個Looper對象,由它來管理此線程里的Message Queue(消息隊列)下硕。
2)Handler: 你可以構造Handler對象來與Looper溝通丁逝,以便push新消息到Message Queue里;或者接收Looper從Message Queue取出)所送來的消息。
3) Message Queue(消息隊列):用來存放線程放入的消息梭姓。
4)線程:UI thread 通常就是main thread霜幼,而Android啟動程序時會替它建立一個Message Queue。
Android程序啟動后會起一個進程誉尖,所有的組件都在這個進程里面運行罪既。開始這個進程只包含一個線程(備注進程怎么能包含線程,我認為說法有誤),叫做UI主線程萝衩,負責處理UI界面的顯示更新回挽。對于一些費時的操作(超過5S會卡頓)需要單獨啟動一個子線程去處理。子線程處理完畢將結果通知給UI主線程猩谊,主線程得到結果后更新UI界面千劈。子線程與UI主線程的通信在android中使用了消息機制來完成,那么是怎么完成的呢牌捷?這就和handler 機制的原理墙牌,簡而言之言而總之,就是需要兩樣樣古老的東西暗甥,消息隊列喜滨、輪詢。也就是說撤防,主線程起來以后有一個消息隊列虽风,同時和該隊列配對的有一個輪詢,而子線程有這個消息隊列的引用寄月,那這樣辜膝,子線程處理完以后就會向主線程的消息隊列發(fā)消息,主線程輪詢自己的隊列漾肮,發(fā)現(xiàn)有未處理的消息就進行處理厂抖。