7.1 基礎知識Android訊息處理機制

來源:互聯網
上載者:User

標籤:因此   ble   告訴   實現   sync   androi   create   方法   isa   

1. Android訊息處理機制: Handler, MessageQueue, Looper, Thread

線程概念 : 一個應用程式運行時它的主體被稱為進程,
一個進程內部可以有多個線程,
線程共用進程的資源 
線程間通訊

在android系統中是怎麼封裝通訊的,假如存在兩個線程A和B,如果A線程要告訴B線程一些訊息,怎麼實現?

A進程怎麼發發訊息?(1)構造訊息,訊息裡面有資料資訊和處理函數(2)發訊息;這兩個步驟在android源碼中被封裝成Handler

訊息在android中被封裝為Message,A發送Message給B,可能B處理不過來,因此A把訊息放到B進程裡面的訊息佇列MessageQueue類,在B進程的迴圈體中做什麼事?

(1)、從隊列中取出訊息;(2)處理訊息,執行訊息的處理函數;這兩個步驟在android源碼中被封裝成Looper

 

Looper源碼在frameworks/base/core/java/android/os/Looper.java

Handler源碼在frameworks/base/core/java/android/os/Handler.java   //ctrl+shift+n在輸入handler.java來開啟

a. 建立MessageQueue: Looper.prepare()
b. 使用Handler構造、發送Message
b.1 new Handler  //建立handler的時候可以指定Looper即訊息接受者和Callback回呼函數即訊息的處理函數,如果不知道肯定有預設的Looper和訊息處理函數
b.2 Handler.sendMessage, sendEmptyMessageAtTime, sendMessageDelayed

c. 使用Looper迴圈處理訊息:在loop函數中有個for死迴圈
c.1 從MessageQueue中取出Message,//Message msg = queue.next();
c.2 執行它的處理函數: msg.target.dispatchMessage(msg)//target就是Handler,dispatchMessage會調用處理函數

  

應用程式編寫:

功能說明:app中建立一個button,建立子線程,添加訊息處理功能,並且給Button添加處理函數,並且主線程會監測button,當button按下時給子線程發送訊息,子線程收到訊息後列印出來

import android.view.View;

import android.util.Log;//列印匯入的庫

public class MainActivity extends AppCompatActivity{

  private Button mButton;

  private final String TAG = "MessageTest";

  private int ButtonCount = 0;

  private Thread myThread;

  private MyThread myThread2;

  private Handler mHandler;

  private int mMessageCount = 0;

  class MyRunnable:implements Runable{

    int count=0;

    public void run(){

      for(;;){

        Log.d(TAG,"MyThread"+(count++));

        try{  

          Thread.sleep(3000);

        }catch(INterrupteException e){

          e.printStackTrace();

        }

      }

    }

  }

  class Mythread extends Thread{       //android只帶的訊息處理是在HandlerThread.java中,其功能同我們怎麼的Mythread,如果不自己建立Mythread,可以直接使用HandlerThread類

    public void run(){

      super.run();

      Looper.prepare();//建立訊息佇列

      Looper.loop();//從訊息佇列中取出訊息,調用訊息的處理函數

    }

    public Looper getLooper(){

      return Looper.myLooper(); 

    }

  }

  pretected void onCreate(Bundle savedInstanceState){

    ........

    ........

    mButton = (Button)findViewById(R.id.button);//雙擊Button,按下shift+F1,可以查看類的協助文檔

    mButton.setOnClickListener(new View.OnClickListener(){

      public void onClick(View v){

        Log.d(TAG,"SendMessage"+(ButtonCount++) );

        Message msg = new Message();

        mHandler.sendMessage(msg );//發送訊息的會從把訊息放到訊息佇列中,訊息佇列是從handler建立的時候從Looper中獲得

      }

    });

    myThread = new Thread(new MyRunnable,"MessageTestThread");//(runnable介面的方法run是線程的主體函數)

    myThread.start();

    myThread2 = new MyThread();

    myThread2 .start();//功能和myThread一樣,start會導致MyThread的run函數被執行,run函數會執行Looper.prepare()去建立訊息佇列,但這個函數並不一定馬上就執行,如果住進程中建立Handler的時候沒有隊列,會存在風險,所以修改class MyThread extends Thread{}

    ////我們現在的代碼裡面有三個線程了,主線程、myThread和myThread2,,要確定訊息發給誰Looper

    mHandler = new Handler(myThread2.getLooper(),new Handler.Callback(){

      public boolean handleMessage(Message msg){

        Log.d(TAG,"getMessage"+(mMessageCount++))

        return false;

      }

    });

  }

}

針對上面所說的風險修改class MyThread extends Thread{},如下:

class MyThread extends Thread{

  private Looper mLooper;

    public void run(){

      super.run();

      Looper.prepare();//建立訊息佇列

      mLooper = Looper.myLooper();

      notifyAll();//當主線程調用getLooper,在mLooper 為空白的時候會休眠,所以這裡需要喚醒休眠的線程

      Looper.loop();//從訊息佇列中取出訊息,調用訊息的處理函數

    }

    public Looper getLooper(){

      if(!isAlive()){

        return null;

      }

      synchronized(this){

        while(isAlive() && mLooper == null){

          try{

            wait();

          }catch (InterruptedException e){

 

          }

        }

      }

      return mLooper;

    }

}

 

修改代碼使用系統只帶的訊息處理線程:

1、匯入包:import android.os.HandlerThread;

2、在public class MainActivity extends AppCompatActivity中新增

  private HandlerThread myThread3;

  private Handler mHandler3;

  myThread3 = new HandlerThread("MessageTestThread3");

  myThread3 .start();

  mHandler3 = new Handler(myThread3.getLooper());

  在button的onClick函數中添加:

  mHandler3.post(new Runnable(){

    public void run(){

      Log.d(TAG,"getMessage for Thread3"+(mMessageCount++));

    }

  });

  

7.1 基礎知識Android訊息處理機制

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.