結合原始碼詳解android訊息模型

來源:互聯網
上載者:User

標籤:

Handler是整個訊息系統的核心,是Handler向MessageQueue發送的Message,最後Looper也是把訊息通知給Handler,所以就從Handler講起。

一、Handler

Handler的建構函式有很多,但本質差不多:

public Handler() {          this(null, false);      }  

  

public Handler(Callback callback, boolean async) {          //自動綁定當前線程的looper          mLooper = Looper.myLooper();          if (mLooper == null) {              throw new RuntimeException(                  "Can‘t create handler inside thread that has not called Looper.prepare()");//從這可以看出,建立Handler必須有Looper          }          mQueue = mLooper.mQueue;  //Looper的MessageQueue          mCallback = callback;     //一個回掉介面          mAsynchronous = async;        }  

這個是建立給定Looper的Handler  :

public Handler(Looper looper, Callback callback, boolean async) {           mLooper = looper;         mQueue = looper.mQueue;         mCallback = callback;         mAsynchronous = async;     }

二、Looper的原始碼:

public static Looper myLooper() {         return sThreadLocal.get();     }  

  在一個子線程中建立Looper的一般步驟:(這是我自己寫的,不是原始碼)

class MyThread extends Thread{          public Handler handler;          public Looper looper;          public void run() {              Looper.prepare();//建立一個looper              looper = Looper.myLooper();              handler = new Handler(){                 @Override              public void handleMessage(Message msg) {                    System.out.println("currentThread->"+Thread.currentThread());                 }             };             Looper.loop();//讓訊息迴圈起來          }      } 

  下面就看看Looper.prepare,Looper.loop方法:

public static void prepare() {          prepare(true);      }        private static void prepare(boolean quitAllowed) {          if (sThreadLocal.get() != null) {//sThreadLocal使得線程能夠保持各自獨立的一個對象。              throw new RuntimeException("Only one Looper may be created per thread");          }          sThreadLocal.set(new Looper(quitAllowed));      }  

  Looper.prepare():

public static void loop() {          final Looper me = myLooper();          if (me == null) {    //如果Looper為空白              throw new RuntimeException("No Looper; Looper.prepare() wasn‘t called on this thread.");          }          final MessageQueue queue = me.mQueue;            。。。。          for (;;) {              Message msg = queue.next(); // 迴圈下一個              if (msg == null) {                  // No message indicates that the message queue is quitting.                  return;              }               。。。。                msg.target.dispatchMessage(msg);  //分發訊息,msg.target就是Handler                if (logging != null) {                  logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);              }              。。。。                msg.recycle();  //回收msg到msgPool          }      }  

  從這些代碼可以看出Looper不斷檢查MessagePool是否有《==Message,有的話就通過Handler的dispatchMessage(msg)發送出去,利用Handler與外界互動。

3.Message的原始碼:

public static Message obtain() {   //得到Message對象         synchronized (sPoolSync) {             if (sPool != null) {                 Message m = sPool;                 sPool = m.next;                 m.next = null;                 sPoolSize--;                 return m;             }         }         return new Message();  //沒有就建立     } 

  handler.obtainMessage()方法:

public final Message obtainMessage()     {         return Message.obtain(this);  //通過Message的obtain方法     }  

  

public static Message obtain(Handler h) {  //就是這個方法        Message m = obtain();  //最終調用的還是obtain方法        m.target = h;      //target是handler          return m;    } 

  看了上邊的原始碼,相信你一定對Handler,message,Looper有了一定瞭解,對編程中常遇到的方法,知道是怎麼用的啦。其實學android一定要常看源碼,源碼很有用。

4.下邊就是上代碼,執行個體分析:

<pre name="code" class="java">package com.example.handler_01;    import android.Manifest.permission;  import android.app.Activity;  import android.os.Bundle;  import android.os.Handler;  import android.os.Handler.Callback;  import android.os.Message;  import android.view.Menu;  import android.view.MenuItem;  import android.view.View;  import android.view.View.OnClickListener;  import android.widget.Button;  import android.widget.ImageView;  import android.widget.TextView;  import android.widget.Toast;    public class MainActivity extends Activity implements OnClickListener{        private TextView textView;      private Button button;                  private Handler handler = new Handler(new Callback() {//攔截訊息                    public boolean handleMessage(Message msg) {  //截獲handler的發送的訊息                        Toast.makeText(getApplicationContext(), ""+1, 1).show();              //return false;              return false;//若返回true,則證明截獲,下面的handleMessage就不會執行!          }      }){          public void handleMessage(Message msg) {              Toast.makeText(getApplicationContext(), ""+2, 1).show();              Person person = (Person)msg.obj;              System.out.println(person.toString());          }      };            private MyRunnable myRunnable=new MyRunnable();            private ImageView imageView;            private int images[]={R.drawable.a1,R.drawable.a2,R.drawable.a3};      private int index;            class MyRunnable implements Runnable{  //不斷的更新圖片,3張輪換            @Override          public void run() {            index++;            index=index%3;  //不斷迴圈            imageView.setImageResource(images[index]);            handler.postDelayed(myRunnable, 1000);  //每隔一段時間執行myRunnable            System.out.println("MyRunnable中的線程:"+Thread.currentThread());//運行在當前主線程!          }                }      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          textView = (TextView) findViewById(R.id.textview);          imageView = (ImageView) findViewById(R.id.imageView1);          button = (Button) findViewById(R.id.button1);          button.setOnClickListener(this);          new Thread(){              @Override              public void run() {                  try {                      Thread.sleep(2000);                      /*Message message = new Message();                    message.arg1=88;*/                     Message message = handler.obtainMessage();                                           Person person = new Person();                     person.age=20;                     person.name="chaochao";                     message.obj=person;                     handler.sendMessage(message);//在子線程中向主線程發訊息。                  } catch (InterruptedException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  }                                }          }.start();          handler.postDelayed(myRunnable, 1000);      }      @Override      public void onClick(View v) {          switch (v.getId()) {          case R.id.button1:              handler.removeCallbacks(myRunnable);              //handler.sendEmptyMessage(1);              break;            default:              break;          }                }        class Person{          public int age;          public String name;                    public String toString() {            return "name="+name+" age="+age;          }      }  }  

  布局很簡單,就不上代碼啦。

運行結果:

圖片自己可以隨便能一個。。。。

在後邊再詳細解析Handler的用法。。

轉寄請註明出處:http://www.cnblogs.com/jycboy/p/handlerjx.html

結合原始碼詳解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.