Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / 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;   
        } 
    }