Android之(zhī)Message,MessageQueue,Looper,Handler詳解( - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 技術分享 >

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);               
                }
 
            }
        }
    }
}

相關案例查看更多