Android Handler Message多线程实例

什么是Handler 

handler通俗讲就是在各个进程之间发送数据的处理对象。在任何进程中,只要获得了另一个进程的handler则可以通过 handler.sendMessage(message)方法向那个进程发送数据。基于这个机制,我们在处理多线程的时候可以新建一个thread,这 个thread拥有UI线程中的一个handler。当thread处理完一些耗时的操作后通过传递过来的handler向UI线程发送数据,由UI线程去更新界面。

Handler类简介

Android平台中,新启动的线程是无法访问Activity里的Widget的,当然也不能将运行状态外送出来,这就需要有Handler机 制进行消息的传递了,Handler类位于android.os包下,主要的功能是完成Activity的Widget与应用程序中线程之间的交互。接下 来对该类中常用的方法进行介绍,如下表所示。

Handler类的常用方法

方法签名

 

描     述

 

public void handleMessage (Message msg)

 

子类对象通过该方法接收信息

 

public final boolean sendEmptyMessage (int what)

 

发送一个只含有 what 值的消息

 

public final boolean sendMessage (Message msg)

 

发送消息到 Handler ,

通过 handleMessage 方法接收

 

public final boolean hasMessages (int what)

 

监测消息队列中是否还

有 what 值的消息

 

public final boolean post (Runnable r)

 

将一个线程添加到消息队列

 

开发带有Handler类的程序步骤如下。

在Activity或Activity的Widget中开发Handler类的对象,并重写handleMessage方法。

在新启动的线程中调用sendEmptyMessage或者sendMessage方法向Handler发送消息。

Handler类的对象用handleMessage方法接收消息,然后根据消息的不同执行不同的操作。

    在Android 中Handler和Message、Thread有着很密切的关系。Handler 主要是负责Message的分发和处理。但是这个Message从哪里来的呢?Message 由一个消息队列进行管理,而消息队列却由一个Looper进行管理。Android系统中Looper负责管理线程的消息队列和消息循环,具体实现请参考Looper的源码。 可以通过Loop.myLooper()得到当前线程的Looper对象,通过Loop.getMainLooper()可以获得当前进程的主线程的 Looper对象。Android系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列和一个消 息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该 线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。

虽说 特定线程的消息只能分发给本线程,不能进行跨线程通讯,但是由于可以通过获得线程的Looper对象来进行曲线的实现不同线程间消息的传递,代码如下

package com.mytest.handlertest; 
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.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup.LayoutParams; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
public class HandlerTest extends Activity implements OnClickListener{ 
     
    private String TAG = "HandlerTest"; 
    private boolean bpostRunnable = false; 
     
    private NoLooperThread noLooperThread = null;   
    private OwnLooperThread ownLooperThread = null;   
    private ReceiveMessageThread receiveMessageThread =null; 
     
    private Handler  mOtherThreadHandler=null; 
    private EventHandler mHandler = null;  
     
    private Button btn1 = null; 
    private Button btn2 = null; 
    private Button btn3 = null; 
    private Button btn4 = null; 
    private Button btn5 = null; 
    private Button btn6 = null; 
    private TextView tv = null; 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        
        LinearLayout layout = new LinearLayout(this); 
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(250, 50); 
        layout.setOrientation(LinearLayout.VERTICAL); 
         
        btn1 = new Button(this); 
        btn1.setId(101); 
        btn1.setText("message from main thread self"); 
        btn1.setOnClickListener(this); 
        layout.addView(btn1, params); 
         
        btn2 = new Button(this); 
        btn2.setId(102); 
        btn2.setText("message from other thread to main thread"); 
        btn2.setOnClickListener(this); 
        layout.addView(btn2,params); 
         
        btn3 = new Button(this); 
        btn3.setId(103); 
        btn3.setText("message to other thread from itself"); 
        btn3.setOnClickListener(this); 
        layout.addView(btn3, params); 
         
        btn4 = new Button(this); 
        btn4.setId(104); 
        btn4.setText("message with Runnable as callback from other thread to main thread"); 
        btn4.setOnClickListener(this); 
        layout.addView(btn4, params); 
         
        btn5 = new Button(this); 
        btn5.setId(105); 
        btn5.setText("main thread's message to other thread"); 
        btn5.setOnClickListener(this); 
        layout.addView(btn5, params); 
         
        btn6 = new Button(this); 
        btn6.setId(106); 
        btn6.setText("exit"); 
        btn6.setOnClickListener(this); 
        layout.addView(btn6, params); 
         
        tv = new TextView(this); 
        tv.setTextColor(Color.WHITE); 
        tv.setText(""); 
        params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT); 
        params.topMargin=10; 
        layout.addView(tv, params); 
         
        setContentView(layout); 
         
        receiveMessageThread = new ReceiveMessageThread(); 
        receiveMessageThread.start(); 
         
    } 
     
    class EventHandler extends Handler{ 
         
        public EventHandler(Looper looper){ 
            super(looper); 
        } 
         
        public EventHandler(){ 
            super(); 
        } 
        @Override 
        public void handleMessage(Message msg) { 
            // TODO Auto-generated method stub 
            super.handleMessage(msg); 
            Log.e(TAG, "CurrentThread id:----------+>" + Thread.currentThread().getId()); 
            switch(msg.what){ 
            case 1: 
                tv.setText((String)msg.obj); 
                break; 
                 
            case 2: 
                tv.setText((String)msg.obj); 
                noLooperThread.stop(); 
                break; 
                 
            case 3: 
                //不能在非主线程的线程里面更新UI,所以这里通过log打印信息 
                Log.e(TAG,(String)msg.obj); 
                ownLooperThread.stop(); 
                break; 
            default: 
                Log.e(TAG,(String)msg.obj); 
                break; 
            } 
        } 
         
    } 
     
      //ReceiveMessageThread has his own message queue by execute Looper.prepare();  
    class ReceiveMessageThread extends Thread { 
         
        @Override 
        public void run(){ 
            Looper.prepare(); 
            mOtherThreadHandler= new Handler(){ 
                @Override 
                public void handleMessage(Message msg) { 
                    // TODO Auto-generated method stub 
                    super.handleMessage(msg); 
                     
                    Log.e(TAG,"-------+>"+(String)msg.obj); 
                    Log.e(TAG, "CurrentThread id:----------+>" + Thread.currentThread().getId()); 
                     
                } 
                  
             }; 
             Log.e(TAG, "ReceiveMessageThread id:--------+>" + this.getId());  
             Looper.loop(); 
        } 
    } 
     
    class NoLooperThread extends Thread { 
        private EventHandler mNoLooperThreadHandler; 
        @Override 
        public void run() { 
             
            Looper myLooper = Looper.myLooper(); 
            Looper mainLooper= Looper.getMainLooper(); 
             
            String msgobj; 
            if(null == myLooper){ 
                //这里获得的是主线程的Looper,由于NoLooperThread没有自己的looper所以这里肯定会被执行 
                mNoLooperThreadHandler = new EventHandler(mainLooper); 
                msgobj = "NoLooperThread has no looper and handleMessage function executed in main thread!";  
            } else{ 
                mNoLooperThreadHandler = new EventHandler(myLooper); 
                msgobj = "This is from NoLooperThread self and handleMessage function executed in NoLooperThread!";  
            } 
             
            mNoLooperThreadHandler.removeMessages(0); 
             
            if(bpostRunnable == false){ 
            //send message to main thread 
                Message msg = mNoLooperThreadHandler.obtainMessage(2, 1, 1, msgobj); 
                mNoLooperThreadHandler.sendMessage(msg); 
                Log.e(TAG, "NoLooperThread id:--------+>" + this.getId());  
            }else{ 
                //下面new出来的实现了Runnable接口的对象中run函数是在Main Thread中执行,不是在NoLooperThread中执行 记得 null == myLooper么 
                //注意Runnable是一个接口,它里面的run函数被执行时不会再新建一个线程   
                //您可以在run上加断点然后在eclipse调试中看它在哪个线程中执行   
                 
                mNoLooperThreadHandler.post(new Runnable(){ 
                    public void run() { 
                        // TODO Auto-generated method stub 
                        tv.setText("update UI through handler post runnalbe mechanism!");   
                        Log.e(TAG, "update UI id:--------+>" + Thread.currentThread().getId());  
                        noLooperThread.stop();   
                    } 
                     
                }); 
            } 
        } 
         
    } 
     
    class OwnLooperThread extends Thread{ 
        private EventHandler mOwnLooperThreadHandler = null; 
         
        @Override 
        public void run() { 
            Looper.prepare(); 
            Looper myLooper = Looper.myLooper(); 
            Looper mainLooper= Looper.getMainLooper(); 
             
            String msgobj; 
             
            if(null == myLooper){ 
                mOwnLooperThreadHandler = new EventHandler(mainLooper); 
                msgobj = "OwnLooperThread has no looper and handleMessage function executed in main thread!";  
            }else{ 
                mOwnLooperThreadHandler = new EventHandler(myLooper); 
                msgobj = "This is from OwnLooperThread self and handleMessage function executed in NoLooperThread!"; 
            } 
             
            mOwnLooperThreadHandler.removeMessages(0); 
             
            //给自己发送消息 
            Message msg = mOwnLooperThreadHandler.obtainMessage(3,1,1,msgobj); 
            mOwnLooperThreadHandler.sendMessage(msg); 
            Looper.loop(); 
        } 
    } 
     
    public void onClick(View v) { 
        // TODO Auto-generated method stub 
        switch(v.getId()){ 
        case 101: 
            //主线程发送消息给自己 
            Looper looper = Looper.myLooper();//get the Main looper related with the main thread  
            //如果不给任何参数的话会用当前线程对应的Looper(这里就是Main Looper)为Handler里面的成员mLooper赋值 
            mHandler = new EventHandler(looper); 
            // 清除整个MessageQueue里的消息   
            mHandler.removeMessages(0); 
            String obj = "This main thread's message and received by itself!"; 
             
            Message msg = mHandler.obtainMessage(1,1,1,obj); 
            // 将Message对象送入到main thread的MessageQueue里面  
            mHandler.sendMessage(msg); 
            break; 
        case 102: 
            //other线程发送消息给主线程 
            bpostRunnable = false; 
            noLooperThread = new NoLooperThread();   
            noLooperThread.start();   
            break; 
        case 103: 
             //other thread获取它自己发送的消息   
            tv.setText("please look at the error level log for other thread received message");   
            ownLooperThread = new OwnLooperThread();   
            ownLooperThread.start();   
            break;   
        case 104:       
            //other thread通过Post Runnable方式发送消息给主线程   
            bpostRunnable = true;   
            noLooperThread = new NoLooperThread();   
            noLooperThread.start();   
            break; 
        case 105: 
            //主线程发送消息给other thread   
            if(null!=mOtherThreadHandler){   
            tv.setText("please look at the error level log for other thread received message from main thread");   
            String msgObj = "message from mainThread";   
            Message mainThreadMsg = mOtherThreadHandler.obtainMessage(1, 1, 1, msgObj);   
            mOtherThreadHandler.sendMessage(mainThreadMsg);   
            }   
            break;   
        case 106:   
            finish();   
            break;   
        } 
    } 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/073eb977d147b8d4fd7e260714274a24.html