Android之(zhī)Message,MessageQueue,Looper,Handler詳解(
發表時(shí)間:2021-1-4
發布人(rén):融晨科技
浏覽次數:45
一、幾個(gè)關鍵概念
1、MessageQueue:是(shì)一種數據結構,見名知義,就(jiù)是(shì)一個(gè)消息隊列,存放消息的(de)地(dì / de)方。每一個(gè)線程最多隻可以(yǐ)擁有一個(gè)MessageQueue數據結構。
創建一個(gè)線程的(de)時(shí)候,并不(bù)會自動創建其MessageQueue。通常使用一個(gè)Looper對象對該線程的(de)MessageQueue進行管理。主線程創建時(shí),會創建一
個(gè)默認的(de)Looper對象,而(ér)Looper對象的(de)創建,将自動創建一個(gè)Message Queue。其他(tā)非主線程,不(bù)會自動創建Looper,要(yào / yāo)需要(yào / yāo)的(de)時(shí)候,通過調
用prepare函數來(lái)實現。
2、Message:消息對象,Message Queue中的(de)存放的(de)對象。一個(gè)Message Queue中包含多個(gè)Message。
Message實例對象的(de)取得,通常使用Message類裏的(de)靜态方法obtain(),該方法有多個(gè)重載版本可供選擇;它的(de)創建并不(bù)一定是(shì)直接創建一個(gè)新的(de)實例,
而(ér)是(shì)先從Message Pool(消息池)中看有沒有可用的(de)Message實例,存在(zài)則直接取出(chū)返回這(zhè)個(gè)實例。如果Message Pool中沒有可用的(de)Message實例,
則才用給定的(de)參數創建一個(gè)Message對象。調用removeMessages()時(shí),将Message從Message Queue中删除,同時(shí)放入到(dào)Message Pool中。除了(le/liǎo)上(shàng)面這(zhè)
種方式,也(yě)可以(yǐ)通過Handler對象的(de)obtainMessage()獲取一個(gè)Message實例。
3、Looper:
是(shì)MessageQueue的(de)管理者。每一個(gè)MessageQueue都不(bù)能脫離Looper而(ér)存在(zài),Looper對象的(de)創建是(shì)通過prepare函數來(lái)實現的(de)。同時(shí)每一個(gè)Looper對象
和(hé / huò)一個(gè)線程關聯。通過調用Looper.myLooper()可以(yǐ)獲得當前線程的(de)Looper對象
創建一個(gè)Looper對象時(shí),會同時(shí)創建一個(gè)MessageQueue對象。除了(le/liǎo)主線程有默認的(de)Looper,其他(tā)線程默認是(shì)沒有MessageQueue對象的(de),所以(yǐ),不(bù)能
接受Message。如需要(yào / yāo)接受,自己定義一個(gè)Looper對象(通過prepare函數),這(zhè)樣該線程就(jiù)有了(le/liǎo)自己的(de)Looper對象和(hé / huò)MessageQueue數據結構了(le/liǎo)。
Looper從MessageQueue中取出(chū)Message然後,交由Handler的(de)handleMessage進行處理。處理完成後,調用Message.recycle()将其放入Message Pool中。
4、Handler:
消息的(de)處理者,handler負責将需要(yào / yāo)傳遞的(de)信息封裝成Message,通過調用handler對象的(de)obtainMessage()來(lái)實現;
将消息傳遞給Looper,這(zhè)是(shì)通過handler對象的(de)sendMessage()來(lái)實現的(de)。繼而(ér)由Looper将Message放入MessageQueue中。
當Looper對象看到(dào)MessageQueue中含有Message,就(jiù)将其廣播出(chū)去。該handler對象收到(dào)該消息後,調用相應的(de)handler對象的(de)handleMessage()方法
對其進行處理。
二、線程之(zhī)間的(de)消息如何進行傳遞
1、主線程給自己發送Message
package test.message; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { private Button btnTest; private TextView textView; private Handler handler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnTest = (Button)this.findViewById(R.id.btn_01); textView = (TextView)this.findViewById(R.id.view_01); btnTest.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Looper looper = Looper.getMainLooper(); //主線程的(de)Looper對象 //這(zhè)裏以(yǐ)主線程的(de)Looper對象創建了(le/liǎo)handler, //所以(yǐ),這(zhè)個(gè)handler發送的(de)Message會被傳遞給主線程的(de)MessageQueue。 handler = new MyHandler(looper); handler.removeMessages(0); //構建Message對象 //第一個(gè)參數:是(shì)自己指定的(de)message代号,方便在(zài)handler選擇性地(dì / de)接收 //第二三個(gè)參數沒有什麽意義 //第四個(gè)參數需要(yào / yāo)封裝的(de)對象 Message msg = handler.obtainMessage(1,1,1,"主線程發消息了(le/liǎo)"); handler.sendMessage(msg); //發送消息 } }); } class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ super.handleMessage(msg); textView.setText("我是(shì)主線程的(de)Handler,收到(dào)了(le/liǎo)消息:"+(String)msg.obj); } } }
2、其他(tā)線程給主線程發送Message
package test.message; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { private Button btnTest; private TextView textView; private Handler handler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnTest = (Button)this.findViewById(R.id.btn_01); textView = (TextView)this.findViewById(R.id.view_01); btnTest.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { //可以(yǐ)看出(chū)這(zhè)裏啓動了(le/liǎo)一個(gè)線程來(lái)操作消息的(de)封裝和(hé / huò)發送的(de)工作 //這(zhè)樣原來(lái)主線程的(de)發送就(jiù)變成了(le/liǎo)其他(tā)線程的(de)發送,簡單吧?呵呵 new MyThread().start(); } }); } class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ super.handleMessage(msg); textView.setText("我是(shì)主線程的(de)Handler,收到(dào)了(le/liǎo)消息:"+(String)msg.obj); } } //加了(le/liǎo)一個(gè)線程類 class MyThread extends Thread{ public void run(){ Looper looper = Looper.getMainLooper(); //主線程的(de)Looper對象 //這(zhè)裏以(yǐ)主線程的(de)Looper對象創建了(le/liǎo)handler, //所以(yǐ),這(zhè)個(gè)handler發送的(de)Message會被傳遞給主線程的(de)MessageQueue。 handler = new MyHandler(looper); //構建Message對象 //第一個(gè)參數:是(shì)自己指定的(de)message代号,方便在(zài)handler選擇性地(dì / de)接收 //第二三個(gè)參數沒有什麽意義 //第四個(gè)參數需要(yào / yāo)封裝的(de)對象 Message msg = handler.obtainMessage(1,1,1,"其他(tā)線程發消息了(le/liǎo)"); handler.sendMessage(msg); //發送消息 } } }
3、主線程給其他(tā)線程發送Message
package test.message; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { private Button btnTest; private TextView textView; private Handler handler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnTest = (Button)this.findViewById(R.id.btn_01); textView = (TextView)this.findViewById(R.id.view_01); //啓動線程 new MyThread().start(); btnTest.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { //這(zhè)裏handler的(de)實例化在(zài)線程中 //線程啓動的(de)時(shí)候就(jiù)已經實例化了(le/liǎo) Message msg = handler.obtainMessage(1,1,1,"主線程發送的(de)消息"); handler.sendMessage(msg); } }); } class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ super.handleMessage(msg); textView.setText("我是(shì)主線程的(de)Handler,收到(dào)了(le/liǎo)消息:"+(String)msg.obj); } } class MyThread extends Thread{ public void run(){ Looper.prepare(); //創建該線程的(de)Looper對象,用于(yú)接收消息 //注意了(le/liǎo):這(zhè)裏的(de)handler是(shì)定義在(zài)主線程中的(de)哦,呵呵, //前面看到(dào)直接使用了(le/liǎo)handler對象,是(shì)不(bù)是(shì)在(zài)找,在(zài)什麽地(dì / de)方實例化的(de)呢? //現在(zài)看到(dào)了(le/liǎo)吧???呵呵,開始的(de)時(shí)候實例化不(bù)了(le/liǎo),因爲(wéi / wèi)該線程的(de)Looper對象 //還不(bù)存在(zài)呢。現在(zài)可以(yǐ)實例化了(le/liǎo) //這(zhè)裏Looper.myLooper()獲得的(de)就(jiù)是(shì)該線程的(de)Looper對象了(le/liǎo) handler = new ThreadHandler(Looper.myLooper()); //這(zhè)個(gè)方法,有疑惑嗎? //其實就(jiù)是(shì)一個(gè)循環,循環從MessageQueue中取消息。 //不(bù)經常去看看,你怎麽知道(dào)你有新消息呢??? Looper.loop(); } //定義線程類中的(de)消息處理類 class ThreadHandler extends Handler{ public ThreadHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ //這(zhè)裏對該線程中的(de)MessageQueue中的(de)Message進行處理 //這(zhè)裏我們再返回給主線程一個(gè)消息 handler = new MyHandler(Looper.getMainLooper()); Message msg2 = handler.obtainMessage(1,1,1,"子(zǐ)線程收到(dào):"+(String)msg.obj); handler.sendMessage(msg2); } } } }
4、其他(tā)線程給自己發送Message
packagetest.message; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extendsActivity { privateButton btnTest; privateTextView textView; privateHandler handler; @Override publicvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnTest = (Button)this.findViewById(R.id.btn_01); textView = (TextView)this.findViewById(R.id.view_01); btnTest.setOnClickListener(newView.OnClickListener() { @Override publicvoid onClick(View arg0) { //啓動線程 newMyThread().start(); } }); } classMyHandler extendsHandler{ publicMyHandler(Looper looper){ super(looper); } publicvoid handleMessage(Message msg){ super.handleMessage(msg); textView.setText((String)msg.obj); } } classMyThread extendsThread{ publicvoid run(){ Looper.prepare();//創建該線程的(de)Looper對象 //這(zhè)裏Looper.myLooper()獲得的(de)就(jiù)是(shì)該線程的(de)Looper對象了(le/liǎo) handler =new ThreadHandler(Looper.myLooper()); Message msg = handler.obtainMessage(1,1,1,"我自己"); handler.sendMessage(msg); Looper.loop(); } //定義線程類中的(de)消息處理類 classThreadHandler extendsHandler{ publicThreadHandler(Looper looper){ super(looper); } publicvoid handleMessage(Message msg){ //這(zhè)裏對該線程中的(de)MessageQueue中的(de)Message進行處理 //這(zhè)裏我們再返回給主線程一個(gè)消息 //加入判斷看看是(shì)不(bù)是(shì)該線程自己發的(de)信息 if(msg.what ==1 && msg.obj.equals("我自己")){ handler =new MyHandler(Looper.getMainLooper()); Message msg2 = handler.obtainMessage(1,1,1,"禀告主線程:我收到(dào)了(le/liǎo)自己發給自己的(de)Message"); handler.sendMessage(msg2); } } } } }