本著深入淺出的原則,本文詳細介紹了從線程到Handler消息傳遞機制的內容,中間多引用博客,如果不了解,還是要詳細看下鏈接里面的內容,適合像我這種基礎不扎實的同學學習下。
首先,廢話下為什么要有異步任務:
如果在主線程(UI線程)操作一些耗時的操作容易造成卡頓,
Android 規定主線程中不可以做耗時操作(訪問網絡,操作數據庫)
現在最基礎的異步任務的使用方法:
1.使用Handler消息傳遞機制;
2.使用AsyncTask異步任務;
要是這時候你不熟悉實現多線程的方式,請狂點
java線程系列---Runnable和Thread的區別
結論:
實現方式是1.實現Runnable接口 2.繼承Thread類
多線程肯定永遠以實現Runnable接口為主
使用Runnable實現多線程可以達到資源共享目的
另外,Thread類也是Runnable親兒子
要是這時候你不能隨手寫出Handler的實現方式,請狂點
Android Handler詳細使用方法實例
用法:
1.將handler綁定到它所建立的線程中,簡單粗暴沒情趣
//使用handler時首先要創建一個handler(UI線程)
Handler handler = new Handler();
//將線程接口立刻送到線程隊列中
handler.removeCallbacks(update_thread);
Runnable update_thread = new Runnable()
{
public void run()
{
//UI操作
}
};
handler.post(update_thread);
//將接口從線程隊列中移除
2.handler的消息隊列機制,慢條斯理前戲足
// 調用:
update_progress_handler.post(update_thread);
//創建一個handler,內部完成處理消息方法
Handler update_progress_handler = new Handler()
{
@Override
public void handleMessage(Message msg) {
// UI線程
// msg.arg1 = "bilibili"
}
};
Runnable update_thread = new Runnable()
{
public void run() {
Message msg = update_progress_handler.obtainMessage();
//把消息發送到消息隊列中,msg對應handleMessage的入參
msg.arg1 = "bilibili";
update_progress_handler.sendMessage(msg);
}
};
//移除
update_progress_handler.removeCallbacks(update_thread);
3.自己看鏈接吧...
handler.sendMessage(msg) 和 handler.post(Runnable) 都知道什么情況下用了,接下來就是硬菜了
請狂點:
Android 異步消息處理機制 讓你深入理解 Looper、Handler、Message三者關系
結論
1、首先Looper.prepare()在本線程中保存一個Looper實例,然后該實例中保存一個MessageQueue對象;因為Looper.prepare()在一個線程中只能調用一次,所以MessageQueue在一個線程中只會存在一個。
2、Looper.loop()會讓當前線程進入一個無限循環,不端從MessageQueue的實例中讀取消息,然后回調msg.target.dispatchMessage(msg)方法。
3、Handler的構造方法,會首先得到當前線程中保存的Looper實例,進而與Looper實例中的MessageQueue想關聯。
4、Handler的sendMessage方法,會給msg的target賦值為handler自身,然后加入MessageQueue中。
5、在構造Handler實例時,我們會重寫handleMessage方法,也就是msg.target.dispatchMessage(msg)最終調用的方法
還有需要注意的,因為最終調用的方法都是這個
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
分發消息流程:
當Message的msg.callback不為空時,則回調方法msg.callback.run();
當Handler的mCallback不為空時,則回調方法mCallback.handleMessage(msg);
最后調用Handler自身的回調方法handleMessage(),該方法默認為空,Handler子類通過覆寫該方法來完成具體的邏輯。
消息分發的優先級:
Message的回調方法:message.callback.run(),優先級最高;
Handler中Callback的回調方法:Handler.mCallback.handleMessage(msg),優先級僅次于1;
Handler的默認方法:Handler.handleMessage(msg),優先級最低。
對于很多情況下,消息分發后的處理方法是第3種情況,即Handler.handleMessage(),一般地往往通過覆寫該方法從而實現自己的業務邏輯。
懵懵懂懂是嘛?換個方向給你說一遍,補充下內容,能更好的了解整個過程
Android消息機制的原理剖析—閉環總結
結論
(a)MessageQueue和Looper:一對一關系,MessageQueue的創建后放置在Looper中。
(b)Looper和線程:一個線程只有一個,創建之后保存在ThreadLocal中,想要獲取ThreadLocal.get()即可。
(c)Handler和Looper:Handler創建時候,從ThreadLocal中獲取Looper,Handler變量指向這個Looper,Handler和Looper綁定。
(d)Message和Handler:Handler發送Message時候,Message的target屬性指向這個Handler,也是這個Handler來分發處理這個Message
(e)消息池:only one,所有線程共享。
現在Android的消息機制都玩的溜了,不過對于偶爾用到一次用到就要考慮什么異步消息處理機制,還要專門使用一個Handler來發送和接收消息,就好比每次哄好了好不容易脫光了衣服還要先洗澡一樣...
這個時候,就必須要學會AsyncTask了
Android AsyncTask完全解析,帶你從源碼的角度徹底理解
強突:
* 執行次序 執行時機 方法名稱 調用方
* 1 異步任務執行前 onPreExecute UI線程
* 2 異步任務執行中 doInBackground 后臺線程
* 3 異步任務執行中 publishProgress 后臺線程
* 4 異步任務執行中 onProgressUpdate UI線程
* 5 異步任務執行后 onPostExecute UI線程
使用:
private class MyTask extends AsyncTask<String, Integer, String> {
@Override
protected void onPreExecute() {
//onPreExecute方法用于在執行后臺任務前做一些UI操作
}
//doInBackground方法內部執行后臺任務,不可在此方法內修改UI
@Override
protected String doInBackground(String... params) {
//doInBackground方法內部執行后臺任務,不可在此方法內修改UI
// 后臺線程向UI線程發布進度狀態
publishProgress(i);
return null;
}
@Override
protected void onProgressUpdate(Integer... progresses) {
//onProgressUpdate方法用于更新進度信息
}
@Override
protected void onPostExecute(String result) {
//onPostExecute方法用于在執行完后臺任務后更新UI,顯示結果
}
@Override
protected void onCancelled() {
//onCancelled方法用于在取消執行中的任務時更改UI
}
}
調用:
//注意每次需new一個實例,新建的任務只能執行一次,否則會出現異常
mTask = new MyTask();
mTask.execute();
//取消一個正在執行的任務,onCancelled方法將會被調用
mTask.cancel(true);
結論:
AsyncTask也是使用的異步消息處理機制,只是做了非常好的封裝