Message,MessageQueue,Looper,Handler详解+实例
Message,MessageQueue,Looper,Handler詳解+實例
原文地址
Android的Handler使用(這篇簡單介紹Handler的使用)
一、幾個關鍵概念
1、MessageQueue:是一種數據結構,見名知義,就是一個消息隊列,存放消息的地方。每一個線程最多只可以擁有一個MessageQueue數據結構。
創建一個線程的時候,并不會自動創建其MessageQueue。通常使用一個Looper對象對該線程的MessageQueue進行管理。主線程創建時,會創建一
個默認的Looper對象,而Looper對象的創建,將自動創建一個Message Queue。其他非主線程,不會自動創建Looper,要需要的時候,通過調
用prepare函數來實現。
2、Message:消息對象,Message Queue中的存放的對象。一個Message Queue中包含多個Message。
Message實例對象的取得,通常使用Message類里的靜態方法obtain(),該方法有多個重載版本可供選擇;它的創建并不一定是直接創建一個新的實例,
而是先從Message Pool(消息池)中看有沒有可用的Message實例,存在則直接取出返回這個實例。如果Message Pool中沒有可用的Message實例,
則才用給定的參數創建一個Message對象。調用removeMessages()時,將Message從Message Queue中刪除,同時放入到Message Pool中。除了上面這
種方式,也可以通過Handler對象的obtainMessage()獲取一個Message實例。
3、Looper:
是MessageQueue的管理者。每一個MessageQueue都不能脫離Looper而存在,Looper對象的創建是通過prepare函數來實現的。同時每一個Looper對象
和一個線程關聯。通過調用Looper.myLooper()可以獲得當前線程的Looper對象
創建一個Looper對象時,會同時創建一個MessageQueue對象。除了主線程有默認的Looper,其他線程默認是沒有MessageQueue對象的,所以,不能
接受Message。如需要接受,自己定義一個Looper對象(通過prepare函數),這樣該線程就有了自己的Looper對象和MessageQueue數據結構了。
Looper從MessageQueue中取出Message然后,交由Handler的handleMessage進行處理。處理完成后,調用Message.recycle()將其放入Message Pool中。
4、Handler:
消息的處理者,handler負責將需要傳遞的信息封裝成Message,通過調用handler對象的obtainMessage()來實現;
將消息傳遞給Looper,這是通過handler對象的sendMessage()來實現的。繼而由Looper將Message放入MessageQueue中。
當Looper對象看到MessageQueue中含有Message,就將其廣播出去。該handler對象收到該消息后,調用相應的handler對象的handleMessage()方法
對其進行處理。
二、線程之間的消息如何進行傳遞
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(); //主線程的Looper對象
??????????????? //這里以主線程的Looper對象創建了handler,
??????????????? //所以,這個handler發送的Message會被傳遞給主線程的MessageQueue。
??????????????? handler = new MyHandler(looper);
??????????????? handler.removeMessages(0);
??????????????? //構建Message對象
??????????????? //第一個參數:是自己指定的message代號,方便在handler選擇性地接收
??????????????? //第二三個參數沒有什么意義
??????????????? //第四個參數需要封裝的對象
??????????????? Message msg = handler.obtainMessage(1,1,1,"主線程發消息了");
????????????????
??????????????? 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);
??????? }
??? }
}
2、其他線程給主線程發送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) {
????????????????
??????????????? //可以看出這里啟動了一個線程來操作消息的封裝和發送的工作
??????????????? //這樣原來主線程的發送就變成了其他線程的發送,簡單吧?呵呵
??????????????? 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對象創建了handler,
??????????? //所以,這個handler發送的Message會被傳遞給主線程的MessageQueue。
??????????? handler = new MyHandler(looper);
??????????? //構建Message對象
??????????? //第一個參數:是自己指定的message代號,方便在handler選擇性地接收
??????????? //第二三個參數沒有什么意義
??????????? //第四個參數需要封裝的對象
??????????? Message msg = handler.obtainMessage(1,1,1,"其他線程發消息了");
????????????
??????????? handler.sendMessage(msg); //發送消息????????????
??????? }
??? }
}
3、主線程給其他線程發送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的實例化在線程中
??????????????? //線程啟動的時候就已經實例化了
??????????????? Message msg = handler.obtainMessage(1,1,1,"主線程發送的消息");
??????????????? 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(); //創建該線程的Looper對象,用于接收消息
????????????
??????????? //注意了:這里的handler是定義在主線程中的哦,呵呵,
??????????? //前面看到直接使用了handler對象,是不是在找,在什么地方實例化的呢?
??????????? //現在看到了吧???呵呵,開始的時候實例化不了,因為該線程的Looper對象
??????????? //還不存在呢。現在可以實例化了
??????????? //這里Looper.myLooper()獲得的就是該線程的Looper對象了
??????????? handler = new ThreadHandler(Looper.myLooper());
????????????
??????????? //這個方法,有疑惑嗎?
??????????? //其實就是一個循環,循環從MessageQueue中取消息。
??????????? //不經常去看看,你怎么知道你有新消息呢???
??????????? Looper.loop();?
??????? }
????????
??????? //定義線程類中的消息處理類
??????? class ThreadHandler extends Handler{
????????????
??????????? public ThreadHandler(Looper looper){
??????????????? super(looper);
??????????? }
????????????
??????????? public void handleMessage(Message msg){
??????????????? //這里對該線程中的MessageQueue中的Message進行處理
??????????????? //這里我們再返回給主線程一個消息
??????????????? handler = new MyHandler(Looper.getMainLooper());
????????????????
??????????????? Message msg2 = handler.obtainMessage(1,1,1,"子線程收到:"+(String)msg.obj);
????????????????
??????????????? handler.sendMessage(msg2);
??????????? }
??????? }
??? }
}
4、其他線程給自己發送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) {
??????????????? //啟動線程
??????????????? new MyThread().start();????
??????????? }
??????? });
??? }
????
??? class MyHandler extends Handler{
????????
??????? public MyHandler(Looper looper){
??????????? super(looper);
??????? }
????????
??????? public void handleMessage(Message msg){
??????????? super.handleMessage(msg);
??????????? textView.setText((String)msg.obj);
??????? }
??? }????
????
??? class MyThread extends Thread{
????????
??????? public void run(){
??????????? Looper.prepare(); //創建該線程的Looper對象
??????????? //這里Looper.myLooper()獲得的就是該線程的Looper對象了
??????????? handler = new ThreadHandler(Looper.myLooper());
??????????? Message msg = handler.obtainMessage(1,1,1,"我自己");
??????????? handler.sendMessage(msg);
????????????
??????????? Looper.loop();?
??????? }
????????
??????? //定義線程類中的消息處理類
??????? class ThreadHandler extends Handler{
????????????
??????????? public ThreadHandler(Looper looper){
??????????????? super(looper);
??????????? }
????????????
??????????? public void handleMessage(Message msg){
??????????????? //這里對該線程中的MessageQueue中的Message進行處理
??????????????? //這里我們再返回給主線程一個消息
??????????????? //加入判斷看看是不是該線程自己發的信息
??????????????? if(msg.what == 1 && msg.obj.equals("我自己")){
????????????????????
??????????????????? handler = new MyHandler(Looper.getMainLooper());
????????????????????
??????????????????? Message msg2 = handler.obtainMessage(1,1,1,"稟告主線程:我收到了自己發給自己的Message");
????????????????????
??????????????????? handler.sendMessage(msg2);????????????????
??????????????? }
??????????? }
??????? }
??? }
}
附注:
上面四個例子的布局文件是同一個文件main.xml
< ?xml version="1.0" encoding="utf-8"?>
< LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
??? androidrientation="vertical"
??? android:layout_width="fill_parent"
??? android:layout_height="fill_parent"
??? >
< TextView? android:id="@+id/view_01"
??? android:layout_width="fill_parent"?
??? android:layout_height="wrap_content"?
??? android:text="@string/hello"
??? />
????
< Button android:id="@+id/btn_01"?
??? android:layout_width="fill_parent"?
??? android:layout_height="wrap_content"?
??? android:text="測試消息" />
< /LinearLayout>
本文轉自Work Hard Work Smart博客園博客,原文鏈接:http://www.cnblogs.com/linlf03/p/3431227.html,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的Message,MessageQueue,Looper,Handler详解+实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Luy 1.0 :一个React-lik
- 下一篇: Python-练习7