知識
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏壧峁┍憬莸闹С郑?
Android之Message,MessageQueue,Looper,Handler詳解(
發(fā)表時間:2021-1-4
發(fā)布人:葵宇科技
瀏覽次數(shù):45
一、幾個關(guān)鍵概念
1、MessageQueue:是一種數(shù)據(jù)結(jié)構(gòu),見名知義,就是一個消息隊(duì)列,存放消息的地方。每一個線程最多只可以擁有一個MessageQueue數(shù)據(jù)結(jié)構(gòu)。
創(chuàng)建一個線程的時候,并不會自動創(chuàng)建其MessageQueue。通常使用一個Looper對象對該線程的MessageQueue進(jìn)行管理。主線程創(chuàng)建時,會創(chuàng)建一
個默認(rèn)的Looper對象,而Looper對象的創(chuàng)建,將自動創(chuàng)建一個Message Queue。其他非主線程,不會自動創(chuàng)建Looper,要需要的時候,通過調(diào)
用prepare函數(shù)來實(shí)現(xiàn)。
2、Message:消息對象,Message Queue中的存放的對象。一個Message Queue中包含多個Message。
Message實(shí)例對象的取得,通常使用Message類里的靜態(tài)方法obtain(),該方法有多個重載版本可供選擇;它的創(chuàng)建并不一定是直接創(chuàng)建一個新的實(shí)例,
而是先從Message Pool(消息池)中看有沒有可用的Message實(shí)例,存在則直接取出返回這個實(shí)例。如果Message Pool中沒有可用的Message實(shí)例,
則才用給定的參數(shù)創(chuàng)建一個Message對象。調(diào)用removeMessages()時,將Message從Message Queue中刪除,同時放入到Message Pool中。除了上面這
種方式,也可以通過Handler對象的obtainMessage()獲取一個Message實(shí)例。
3、Looper:
是MessageQueue的管理者。每一個MessageQueue都不能脫離Looper而存在,Looper對象的創(chuàng)建是通過prepare函數(shù)來實(shí)現(xiàn)的。同時每一個Looper對象
和一個線程關(guān)聯(lián)。通過調(diào)用Looper.myLooper()可以獲得當(dāng)前線程的Looper對象
創(chuàng)建一個Looper對象時,會同時創(chuàng)建一個MessageQueue對象。除了主線程有默認(rèn)的Looper,其他線程默認(rèn)是沒有MessageQueue對象的,所以,不能
接受Message。如需要接受,自己定義一個Looper對象(通過prepare函數(shù)),這樣該線程就有了自己的Looper對象和MessageQueue數(shù)據(jù)結(jié)構(gòu)了。
Looper從MessageQueue中取出Message然后,交由Handler的handleMessage進(jìn)行處理。處理完成后,調(diào)用Message.recycle()將其放入Message Pool中。
4、Handler:
消息的處理者,handler負(fù)責(zé)將需要傳遞的信息封裝成Message,通過調(diào)用handler對象的obtainMessage()來實(shí)現(xiàn);
將消息傳遞給Looper,這是通過handler對象的sendMessage()來實(shí)現(xiàn)的。繼而由Looper將Message放入MessageQueue中。
當(dāng)Looper對象看到MessageQueue中含有Message,就將其廣播出去。該handler對象收到該消息后,調(diào)用相應(yīng)的handler對象的handleMessage()方法
對其進(jìn)行處理。
二、線程之間的消息如何進(jìn)行傳遞
1、主線程給自己發(fā)送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(); //主線程的Looper對象 //這里以主線程的Looper對象創(chuàng)建了handler, //所以,這個handler發(fā)送的Message會被傳遞給主線程的MessageQueue。 handler = new MyHandler(looper); handler.removeMessages(0); //構(gòu)建Message對象 //第一個參數(shù):是自己指定的message代號,方便在handler選擇性地接收 //第二三個參數(shù)沒有什么意義 //第四個參數(shù)需要封裝的對象 Message msg = handler.obtainMessage(1,1,1,"主線程發(fā)消息了"); handler.sendMessage(msg); //發(fā)送消息 } }); } class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ super.handleMessage(msg); textView.setText("我是主線程的Handler,收到了消息:"+(String)msg.obj); } } }
2、其他線程給主線程發(fā)送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) { //可以看出這里啟動了一個線程來操作消息的封裝和發(fā)送的工作 //這樣原來主線程的發(fā)送就變成了其他線程的發(fā)送,簡單吧?呵呵 new MyThread().start(); } }); } class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ super.handleMessage(msg); textView.setText("我是主線程的Handler,收到了消息:"+(String)msg.obj); } } //加了一個線程類 class MyThread extends Thread{ public void run(){ Looper looper = Looper.getMainLooper(); //主線程的Looper對象 //這里以主線程的Looper對象創(chuàng)建了handler, //所以,這個handler發(fā)送的Message會被傳遞給主線程的MessageQueue。 handler = new MyHandler(looper); //構(gòu)建Message對象 //第一個參數(shù):是自己指定的message代號,方便在handler選擇性地接收 //第二三個參數(shù)沒有什么意義 //第四個參數(shù)需要封裝的對象 Message msg = handler.obtainMessage(1,1,1,"其他線程發(fā)消息了"); handler.sendMessage(msg); //發(fā)送消息 } } }
3、主線程給其他線程發(fā)送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) { //這里handler的實(shí)例化在線程中 //線程啟動的時候就已經(jīng)實(shí)例化了 Message msg = handler.obtainMessage(1,1,1,"主線程發(fā)送的消息"); handler.sendMessage(msg); } }); } class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ super.handleMessage(msg); textView.setText("我是主線程的Handler,收到了消息:"+(String)msg.obj); } } class MyThread extends Thread{ public void run(){ Looper.prepare(); //創(chuàng)建該線程的Looper對象,用于接收消息 //注意了:這里的handler是定義在主線程中的哦,呵呵, //前面看到直接使用了handler對象,是不是在找,在什么地方實(shí)例化的呢? //現(xiàn)在看到了吧???呵呵,開始的時候?qū)嵗涣耍驗(yàn)樵摼€程的Looper對象 //還不存在呢?,F(xiàn)在可以實(shí)例化了 //這里L(fēng)ooper.myLooper()獲得的就是該線程的Looper對象了 handler = new ThreadHandler(Looper.myLooper()); //這個方法,有疑惑嗎? //其實(shí)就是一個循環(huán),循環(huán)從MessageQueue中取消息。 //不經(jīng)常去看看,你怎么知道你有新消息呢??? Looper.loop(); } //定義線程類中的消息處理類 class ThreadHandler extends Handler{ public ThreadHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ //這里對該線程中的MessageQueue中的Message進(jìn)行處理 //這里我們再返回給主線程一個消息 handler = new MyHandler(Looper.getMainLooper()); Message msg2 = handler.obtainMessage(1,1,1,"子線程收到:"+(String)msg.obj); handler.sendMessage(msg2); } } } }
4、其他線程給自己發(fā)送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();//創(chuàng)建該線程的Looper對象 //這里L(fēng)ooper.myLooper()獲得的就是該線程的Looper對象了 handler =new ThreadHandler(Looper.myLooper()); Message msg = handler.obtainMessage(1,1,1,"我自己"); handler.sendMessage(msg); Looper.loop(); } //定義線程類中的消息處理類 classThreadHandler extendsHandler{ publicThreadHandler(Looper looper){ super(looper); } publicvoid handleMessage(Message msg){ //這里對該線程中的MessageQueue中的Message進(jìn)行處理 //這里我們再返回給主線程一個消息 //加入判斷看看是不是該線程自己發(fā)的信息 if(msg.what ==1 && msg.obj.equals("我自己")){ handler =new MyHandler(Looper.getMainLooper()); Message msg2 = handler.obtainMessage(1,1,1,"稟告主線程:我收到了自己發(fā)給自己的Message"); handler.sendMessage(msg2); } } } } }
相關(guān)案例查看更多
相關(guān)閱讀
- 網(wǎng)站建設(shè)方法
- 網(wǎng)站建設(shè)百度官方
- 智慧農(nóng)貿(mào)市場
- 買小程序被騙
- 制作一個小程序
- 云南網(wǎng)站建設(shè)專家
- 貴州小程序開發(fā)
- 網(wǎng)站建設(shè)
- 網(wǎng)絡(luò)公司排名
- 小程序開發(fā)排名前十名
- 日歷組件
- 云南網(wǎng)絡(luò)營銷顧問
- 汽車報廢管理
- 網(wǎng)站建設(shè)靠譜公司
- 做網(wǎng)站
- 云南網(wǎng)站建設(shè)電話
- 云南網(wǎng)站開發(fā)
- APP
- 怎么做網(wǎng)站
- 小程序制作
- 云南省城鄉(xiāng)建設(shè)廳網(wǎng)站
- 模版信息
- 網(wǎng)站建設(shè)專家
- 百度快速排名
- 云南網(wǎng)站制作
- 麗江小程序開發(fā)
- 網(wǎng)站建設(shè)價格
- 軟件定制公司
- 云南衛(wèi)視小程序
- 汽車拆解管理系統(tǒng)