Android 中Message,MessageQueue,Looper,Handler詳解+實例

1、幾個關鍵概念
一、MessageQueue:是一種數據結構,見名知義,就是一個消息隊列,存放消息的地方。每個線程最多隻能夠擁有一個MessageQueue數據結構。
建立一個線程的時候,並不會自動建立其MessageQueue。一般使用一個Looper對象對該線程的MessageQueue進行管理。主線程建立時,會建立一
個默認的Looper對象,而Looper對象的建立,將自動建立一個Message Queue。其餘非主線程,不會自動建立Looper,要須要的時候,經過調
用prepare函數來實現。
二、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實例。
三、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中。
四、Handler:
消息的處理者,handler負責將須要傳遞的信息封裝成Message,經過調用handler對象的obtainMessage()來實現;
將消息傳遞給Looper,這是經過handler對象的sendMessage()來實現的。繼而由Looper將Message放入MessageQueue中。
當Looper對象看到MessageQueue中含有Message,就將其廣播出去。該handler對象收到該消息後,調用相應的handler對象的handleMessage()方法
對其進行處理。
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) {
                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);
        }
    }
}
二、其餘線程給主線程發送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); //發送消息            
        }
    }
}
三、主線程給其餘線程發送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);
            }
        }
    }
}
四、其餘線程給本身發送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"
    android:rientation="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>android

相關文章
相關標籤/搜索