Android的Message機制(簡單小結)
網上以文件形式流傳,不知道原文在哪,感謝原作者了!
================簡單調整了下格式就共享了===============================================
對於Android的Message機制主要涉及到三個主要的類,分別是Handler、Message、Looper;首先對每個類做一個簡單介紹;然後再介紹所謂的Android的Message機制是如何實現的,最後給了一個示例。
一、介紹三個相關的類
1、 Handler主要有兩個用途:首先是可以定時處理或者分發訊息,其次是可以新增一個執行的行為在其它執行緒中執行,
對於Handler中的方法,可以選擇你關心的操作去覆蓋它,處理具體的業務操作,常見的就是對訊息的處理可以覆蓋public void
Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) {//覆蓋handleMessage方法 switch (msg.what) {//根據收到的訊息的what型別處理 case BUMP_MSG: Log.v("handler", "Handler===="+msg.arg1);//列印收到的訊息 break; default: super.handleMessage(msg);//這裡最好對不需要或者不關心的訊息拋給父類,避免丟失訊息 break; } } };
2、 訊息android.os.Message
android.os.Message是定義一個Messge包含必要的描述和屬性資料,並且此物件可以被髮送給android.os.Handler處理。屬性欄位:arg1、arg2、what、obj、replyTo等;其中arg1和arg2是用來存放整型資料的;what是用來儲存訊息標示的;obj是Object型別的任意物件;replyTo是訊息管理器,會關聯到一個handler,handler就是處理其中的訊息。通常對Message物件不是直接new出來的,只要呼叫handler中的obtainMessage方法來直接獲得Message物件。
3、 Looper類主要用於一個執行緒迴圈獲取訊息佇列中的訊息。
Looper的作用主要是負責管理訊息佇列,負責訊息的出列和入列操作。
二、Android的Message機制是如何實現?
1、為什麼要使用Message機制主要是為了保證執行緒之間操作安全,同時不需要關心具體的訊息接收者,使訊息本身和執行緒剝離開,這樣就可以方便的實現定時、非同步等操作。
2、Message機制原理示意圖:
Activity <---------------> EHandler<-----> Looper<-----> MessageQueue
IntentReceiver <-----> EHandler <-----> Looper<-----> MessageQueue
圖 1
3、 如何實現?(具體描述上圖的訊息流的過程)
實現Message機制需要Handler、Message、Looper三個之間的互相作用來實現;當執行緒A需要發訊息給執行緒B的時候,執行緒B要用自己的Looper例項化Handler類,就是構造handler物件時,把當前執行緒的Looper傳給Handler建構函式,handler本身會儲存對Looper的引用,handler構造好以後,就可以用handler的obtainMessage方法例項化Message物件,只要把要傳的資料給Handler,Handler就會構造Message物件,並且把Message物件新增到訊息佇列裡面。然後就可以呼叫handler的sendMessage方法把Message物件傳送出去,Looper就把訊息放到訊息佇列中;最後當Looper知道訊息佇列不為空時候,就會迴圈的從訊息佇列中取訊息,取出訊息就會呼叫剛才例項化好的Handler物件的handleMessage方法取處理訊息,整個Message過程就是這樣。(如圖1所示)
三、下面介紹一個關於Message機制的簡單的示例,具體的程式碼如下:
1、 下面是一個新起的一個執行緒發訊息的示例
handler本身不僅可以傳送訊息,還可以用post的方式新增一個實現Runnable介面的匿名物件到訊息佇列中,在目標收到訊息後就可以回撥的方式在自己的執行緒中執行run的方法體,這就是handler兩種典型的使用方式!
class NoLooperThread extends Thread {
private EventHandler mNoLooperThreadHandler;
public void run() {
Looper myLooper, mainLooper;
myLooper= Looper.myLooper(); //獲得自己的Looper
mainLooper= Looper.getMainLooper(); //獲得自己的main的looper
String obj;
if (myLooper == null) {
mNoLooperThreadHandler = new EventHandler(mainLooper);
obj= "NoLooperThread has no looper andhandleMessage function executed in main thread!";
}else
{
mNoLooperThreadHandler = new EventHandler(myLooper);
obj= "This is from NoLooperThread self andhandleMessage function executed in NoLooperThread!";
}
mNoLooperThreadHandler.removeMessages(0); //清空訊息佇列
if (false == postRunnable) {
Message m = mNoLooperThreadHandler.obtainMessage(2, 1, 1, obj); //生成訊息物件
mNoLooperThreadHandler.sendMessage(m); //傳送訊息
Log.e(sTag, "NoLooperThread id:" + this.getId());
}else {
mNoLooperThreadHandler.post(new Runnable() { //新增一個Runnable介面的實現到訊息佇列,此Runnable介面的實現不在此 執行緒中執行,會在接收的執行緒中執行。
public void run() {
tv.setText("update UI through handler post runnalbe mechanism!");
noLooerThread.stop();
}
});
}
}
2、下面是一個定時迴圈發訊息的示例,如下程式碼:
詳細的解釋參考程式碼的註釋
Handler handler = new Handler() { //建立處理物件handler
publicvoid handleMessage(Message msg) {
switch (msg.what) {
caseMES: {
final int N = mCallbacks.beginBroadcast(); //Copy一份回撥list,並且標記一個狀態
for (int i = 0; i <N; i++) {
try {
mCallbacks.getBroadcastItem(i).getValue(mMediaPlayer01.getCurrentPosition()); //遍歷所有回撥介面 }catch (Exception e) {
e.printStackTrace();
}
}
mCallbacks.finishBroadcast(); //完成後狀態復位
sendMessageDelayed(obtainMessage(MES),1 * 1000);
}
break;
default:
super.handleMessage(msg);
}
}
};
NOTE: 整個hadleMessage方法相當一個巢狀的迴圈四、總結:
所謂的訊息機制其實很簡單,實現這種機制需要只需要四步:
1、例項化Looper(因為例項化Handler時需要一個looper);
2、例項化Handler,這裡需要覆蓋handleMessage方法,處理收到的訊息;
3、 例項化Message物件,呼叫已經例項化好的handler物件的obtainMessage方法,把資料傳給obtainMessage方法,obtainMessage方法就會例項化一個Message物件。(這裡也可以傳送實現Runnable介面的物件);
4、呼叫Handler的sendMessage方法把例項化好的Message物件傳送出去。
對每個執行緒過程都是一樣的,只要按照上面的四個步驟來就可以傳送和接收訊息了。
相關推薦
Android的Message機制(簡單小結)
網上以文件形式流傳,不知道原文在哪,感謝原作者了! ================簡單調整了下格式就共享了=============================================== 對於Android的Message機制主要涉及到三個主要的類,分
初識nginx反向代理和緩存機制(簡單實現)
修改 請求轉發 b- nginx bin text pan types con 實現的需求圖: 環境: nginx緩存和反向代理服務器:192.168.0.224 實際存儲數據機器:192.168.0.37 一、實現反向代理 1、安裝nginx,兩臺服務器
java序列化機制(簡單使用)
轉載:孤傲蒼狼 https://www.cnblogs.com/xdp-gacl/p/3777987.html 詳細分析:http://www.importnew.com/24490.html 一、序列化和反序列化的概念 把物件轉換為位元組序列的過程稱為物件的序列化。
Unity實現自己的事件機制(簡單實現)
事件機制廣泛應用於mvc模式中,靈活的事件機制能夠彌補Unity中的一些缺陷,比如協程的執行。因為協程不能返回值,也不能通過out或者ref傳遞。通過事件機制,可以知道協程執行進度並且返回執行結果。當然,這只是個舉例,也只是我習慣用的一種方式。如果有更好的實現方式,希望不吝
RecyclerView複用ViewHolder機制(簡單瞭解)
本文特別low我設定item為200dp,列印20個,發現onCreateViewHolder僅僅執行了9次int i = 0; @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup par
用Linux C的互斥鎖機制解決哲學家就餐問題(簡單實現)
在1971年,著名的電腦科學家艾茲格·迪科斯徹提出了一個同步問題,即假設有五臺計算機都試圖訪問五份共享的磁帶驅動器。稍後,這個問題被託尼·霍爾重新表述為哲學家就餐問題。這個問題可以用來解釋死鎖和資源耗盡。 「哲學家就餐說明」:有五個哲學家共用一張圓桌,分別坐在
uva 10474 Where is the Marble?(簡單題)
content mil stdlib.h std lib [0 數據 main pre 我非常奇怪為什麽要把它歸類到回溯上,明明就是簡單排序,查找就OK了。wa了兩次,我還非常不解的懷疑了為什麽會 wa,原來是我居然把要找的數字也排序了,當時僅僅是想著能快一點查找。所以
POJ 1321 棋盤問題(簡單DFS)
clas mission sample 標記 span ssi algo std spa 棋盤問題 Time Limit: 1000MS
POJ 1979 Red and Black(簡單DFS)
either www enter ont false num present direction roo Red and Black Description There is a rectangular room, covered with square tile
UVa 12716 GCD XOR (簡單證明)
i++ map esp typedef -a type print const max 題意: 問 gcd(i,j) = i ^ j 的對數(j <=i <= N ) N的範圍為30000000,有10000組例子 思路:GCD(a,b) = a^b =
lightoj 1036 - A Refining Company(簡單dp)
esp scan blank 最大值 typedef 轉移 iostream ret for 題目鏈接:http://www.lightoj.com/volume_showproblem.php?problem=1036 題解:設dp[i][j]表示處理到(i,j)
第十一章 springboot + mongodb(簡單查詢)
req all bool pan 可能 set 如果 創建 使用 1、mongodb在mac上的安裝 下載mongodb,https://www.mongodb.org/ 解壓縮到一個指定文件夾,如:/Users/enniu1/Desktop/zjg/mongodb
一種排序(nyoj8)(簡單排序)
scan http -a tdi 輸入 clu truct clr -c 一種排序 時間限制:3000 ms | 內存限制:65535 KB 難度:3 描寫敘述如今有非常多長方形。每個長方形都有一個編號,這個編號能夠反復。還知道
bootstrap modal垂直居中(簡單封裝)
math str class ria extend splay play 觸發 代碼 未封裝前: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"&
Codeforces 456C - Boredom(簡單DP)
eof size com 數值 content -s rom hat 16px Alex doesn‘t like boredom. That‘s why whenever he gets bored, he comes up with game
HDU 2102 A計劃(簡單DFS)
ont inpu clu 通過 csdn input tin 一次 != Description 可憐的公主在一次次被魔王擄走一次次被騎士們救回來之後,而今,不幸的她再一次面臨生命的考驗。魔王已經發出消息說將在T時刻吃掉公主,因為他聽信謠言說吃公主的肉也能長生不老。年邁的國
Java 垃圾回收機制(早期版本)
重新 速度 交互 綜合 技術 -1 遍歷 我們 後臺 Java 垃圾回收機制在我們普通理解來看,應該視為一種低優先級的後臺進程來實現的,其實早期版本的Java虛擬機並非以這種方式實現的。 先從一種很簡單的垃圾回收方式開始。 引用計數 引用計數是一種簡單但是速度很慢
POJ 2229 Sumsets(簡單DP)
nbsp 自己 arc arm 相加 res sum name base Farmer John commanded his cows to search for different sets of numbers that sum to a given number.
POJ 2385 Apple Catching(簡單DP)
app details ostream 鍛煉 six ack can pre using It is a little known fact that cows love apples. Farmer John has two apple trees (which a
大魚吃小魚(簡單模擬)
一個 入棧 nco http spa println code tar pre 題目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1289 從左往右將數字壓入棧裏(想象成一個水平向右的棧),如果