天天看點

Android 的消息機制(2)

上一節中,是主線程自己發了一個消息到自己的Message Queue中,并把消息從隊列中提取出來。那麼如何由别的線程發送消息給主線程的Message Queue中呢?

<span style="font-size: 14px">/**  

 * MessageQueue2.java  

 * com.test  

 *  

 * Function: TODO  

 *   ver     date           author  

 * ──────────────────────────────────  

 *           2011-3-20      Leon  

 * Copyright (c) 2011, TNT All Rights Reserved.  

*/  

package com.test;  

/**  

 * ClassName:MessageQueue2  

 * Function: TODO ADD FUNCTION  

 * Reason:   TODO ADD REASON  

 * @author   Leon  

 * @version  

 * @since    Ver 1.1  

 * @Date     2011-3-20  

 */  

import android.app.Activity;  

import android.graphics.Color;  

import android.os.Bundle;  

import android.os.Handler;  

import android.os.Looper;  

import android.os.Message;  

import android.view.View;  

import android.view.View.OnClickListener;  

import android.widget.Button;  

import android.widget.LinearLayout;  

import android.widget.TextView;  

public class MessageQueue2 extends Activity implements OnClickListener {  

    private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;  

    private final int FP = LinearLayout.LayoutParams.FILL_PARENT;  

    public TextView tv;  

    private myThread t;  

    private Button btn, btn2, btn3;  

    public void onCreate(Bundle icicle) {  

                super.onCreate(icicle);  

                LinearLayout layout = new LinearLayout(this);  

                layout.setOrientation(LinearLayout.VERTICAL);  

                btn = new Button(this);  

                btn.setId(101);  

                btn.setText("test looper");  

                btn.setOnClickListener(this);  

                LinearLayout.LayoutParams param =  

                    new LinearLayout.LayoutParams(100,50);  

                param.topMargin = 10;  

                layout.addView(btn, param);   

                btn2 = new Button(this);  

                btn2.setId(102);  

                btn2.setText("exit");  

                btn2.setOnClickListener(this);  

                layout.addView(btn2, param);  

                tv = new TextView(this);  

                tv.setTextColor(Color.WHITE);  

                tv.setText("");  

                LinearLayout.LayoutParams param2 =  

                   new LinearLayout.LayoutParams(FP, WC);  

                param2.topMargin = 10;  

                layout.addView(tv, param2);  

                setContentView(layout);  

               }  

        public void onClick(View v) {  

        switch(v.getId()){  

        case 101:  

             t = new myThread();  

             t.start();  

             break;  

        case 102:  

            finish();  

            break;  

        }  

    }  

//------------------------------------------------------  

class EHandler extends Handler {  

            public EHandler(Looper looper) {  

                super(looper);  

            }  

            @Override  

            public void handleMessage(Message msg) {  

               tv.setText((String)msg.obj);  

class myThread extends Thread{  

     private EHandler mHandler;  

     public void run() {  

         Looper myLooper, mainLooper;  

         //取出本線程中的Looper,當然如果本句話放在主線程中,則會取得主線程的Looper  

                  myLooper = Looper.myLooper();  

                 //取出主線程中的Looper  

         mainLooper = Looper.getMainLooper();  

         String obj;  

         if(myLooper == null){  

             mHandler = new EHandler(mainLooper);  

             obj = "current thread has no looper,this message is from Main thread!";  

         }  

         else {  

              mHandler = new EHandler(myLooper);  

              obj = "This is from new thread.";  

         mHandler.removeMessages(0);  

         Message m = mHandler.obtainMessage(1, 1, 1, obj);  

         mHandler.sendMessage(m);  

      }  

  }  

}  

在本程式中Android仍然會自動替主線程建立Message Queue。在點選按鈕之後,新生成的子線程中并不會建立Message Queue。是以,新線程中的myLooper值為null,而mainLooper則指向主線程裡的Looper對象。于是,執行當到指令:

mHandler = new EHandler(mainLooper); 時這個mHandler是屬于主線程的。

通過指令:mHandler.sendMessage(m); 便将消息m存入到主線程的Message Queue裡。mainLooper看到Message Queue裡有訊息,就會自動處理,主線程會自動回調mHandler的handleMessage()函數來處理消息。

本文轉自 最牛傻蛋 51CTO部落格,原文連結:http://blog.51cto.com/zuiniuwang/718340,如需轉載請自行聯系原作者

繼續閱讀