您的位置:首页 > 移动开发 > Android开发

Android Handler

2015-11-23 13:49 417 查看
 1.通常的使用方法

  //handler
case R.id.handler:
printThreadinfo(Thread.currentThread(),"sendMessage");
mHandler.sendEmptyMessage(10);
Logger.i("handler", "===next_start==");
int i=1;
Toast.makeText(this, "test!!", i).show();
Logger.i("handler", "===next_end==");
break;

   private void printThreadinfo(Thread mthread,String tag) {
Logger.i("handler", "=====tag_start====="+tag);
Logger.i("handler", "current_thread_id:"+mthread.getId());
Logger.i("handler", "current_thread_name:"+mthread.getName());
Logger.i("handler", "current_thread_Priority:"+mthread.getPriority());
Logger.i("handler", "=====tag_end====="+tag);
}
//创建一个handler对象
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 10:
printThreadinfo(Thread.currentThread(),"receiveMessage");
break;

default:
break;
}
};
};

Log打印:  

I/handler (14726): =====tag_start=====sendMessage

I/handler (14726): current_thread_id:1

I/handler (14726): current_thread_name:main

I/handler (14726): current_thread_Priority:5

I/handler (14726): =====tag_end=====sendMessage

I/handler (14726): ===next_start==

I/handler (14726): ===next_end==

I/handler (14726): =====tag_start=====receiveMessage

I/handler (14726): current_thread_id:1

I/handler (14726): current_thread_name:main

I/handler (14726): current_thread_Priority:5

I/handler (14726): =====tag_end=====receiveMessage

   

总结:可以看到,发送和接收都是在main线程里处理的。   

   

   

2.handler looper MessageQueue Thread 关系

  2.1在主线程中使用handler并没有看到looper的身影,那是因为主线程已经创建了looper对象,并且该looper对象和主线程

  绑定到一块了,looper内部建立了消息循环机制,然后从消息队列MessageQueue中取出消息Message,然后让发出该Message

  的handler来处理,handler和looper建立的关系是从looper和Thread的绑定后,handler从Thread那获取的looper对象。

  2.2 如果在一个新的线程中new一个handler对象,就要有looper和新线程的绑定了

   class MyThread extends Thread {

                public void run() {                

                        Log.d(Constant.TAG, MessageFormat.format("Thread[{0}]-- run...", Thread

                                        .currentThread().getName()));

                        // 其它线程中新建一个handler

                        Looper.prepare();// 创建该线程的Looper对象,用于接收消息,在非主线程中是没有looper的所以在创建handler前一定要使用prepare()创建一个Looper

                        myThreadHandler = new Handler() {

                                public void handleMessage(android.os.Message msg) {

                                        Log.d(Constant.TAG, MessageFormat.format("Thread[{0}]--myThreadHandler handleMessage run...", Thread

                                                        .currentThread().getName()));

                                }

                        };

                        Looper.myLooper().loop();//建立一个消息循环,该线程不会退出

                }

        }

   

  3.其实2.2中的写法暂时没有发现有什么卵用啊,使用handler的目的是什么呢,不就是为了异步处理吗,那正常的逻辑应该

    主线程里new个handler,然后耗时的操作开一个子线程,等耗时操作在子线程里执行完了,那就通过使用handler发个消息
给主线程,这个时候在handlermessage方法中去更新UI

    class MyThread extends Thread {

        public void run() {                

            Log.i("handler", "==taste_time=="); 

            printThreadinfo(Thread.currentThread(),"sendMessage11");

        mHandler.sendEmptyMessage(11);

        }

}

//创建一个handler对象
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 10:
printThreadinfo(Thread.currentThread(),"receiveMessage");
break;
case 11:   
printThreadinfo(Thread.currentThread(),"receiveMessage11");

                break; 
default:
break;
}
};
};

触发:这里应该考虑New了很多线程的问题
new MyThread().start();

   

   

 3.还有一种使用HanderThread来开子线程的方式

 参考:http://blog.sina.com.cn/s/blog_77c6324101016jp8.html

 //打印了当前线程的ID  
       System.out.println("Activity-->" + Thread.currentThread().getId());  
      //生成一个HandlerThread对象  
      HandlerThread handlerThread = new HandlerThread("handler_thread");  
      //在使用HandlerThread的getLooper()方法之前,必须先调用该类的start(),同时开启一个新线程;  
     handlerThread.start();
     //将由HandlerThread获取的Looper传递给Handler对象,即由处于另外线程的Looper代替handler初始化时默认绑定的消息队列来处理消息。  
   // HandlerThread顾名思义就是可以处理消息循环的线程,它是一个拥有Looper的线程
// ,可以处理消息循环;  其实与其说Handler和一个线程绑定,倒不如说Handler和Looper是
 // 一一对应的。
      MyHandler myHandler = new MyHandler(handlerThread.getLooper());  
      Message msg = myHandler.obtainMessage();  
     //将msg发送到目标对象,所谓的目标对象,就是生成该msg对象的handler对象  
     Bundle b = new Bundle();  
   b.putInt("age", 20);  
      b.putString("name", "Jhon");  
    msg.setData(b);  
      msg.sendToTarget();  //将msg发送到myHandler
  

 //定义类

       class MyHandler extends Handler{  

        public MyHandler(){  

                  

       }  

        

      public MyHandler(Looper looper){  

           super(looper);  

        }  

         @Override 

      public void handleMessage(Message msg) {  

            Bundle b = msg.getData();  

             int age = b.getInt("age");  

            String name = b.getString("name");  

           System.out.println("age is " + age + ", name is" + name);  

            System.out.println("Handler--->" + Thread.currentThread().getId());  

           System.out.println("handlerMessage");  

            }  

        }
  

log输出:   

I/System.out( 2395): Activity-->1

I/System.out( 2395): age is 20, name isJhon

I/System.out( 2395): Handler--->2983

I/System.out( 2395): handlerMessage 

总结:这种方式是把handler和子线程(HandlerThread开的)中的Looper绑定的,那handleMessage方法是在子线程

中执行的,这种模式使用就是主线程需要把耗时的操作给子线程做,这种模式估计也没有什么卵用。

4.线程之间的消息如何进行传递的

参考:http://blog.csdn.net/yhb5566/article/details/7342786 

1、主线程给自己发送Message 

package test.message; 

import android.app.Activity; 

import android.os.Bundle; 

import android.os.Handler; 

import android.os.Looper; 

import android.os.Message; 

import android.view.View; 

import android.widget.Button; 

import android.widget.TextView; 

public class MainActivity extends Activity { 

    private Button btnTest; 

    private TextView textView; 

    private Handler handler; 

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        setContentView(R.layout.main); 

        btnTest = (Button)this.findViewById(R.id.btn_01); 

        textView = (TextView)this.findViewById(R.id.view_01); 

        btnTest.setOnClickListener(new View.OnClickListener() { 

            @Override 

            public void onClick(View arg0) { 

                Looper looper = Looper.getMainLooper(); //主线程的Looper对象 

                //这里以主线程的Looper对象创建了handler, 

                //所以,这个handler发送的Message会被传递给主线程的MessageQueue。 

                handler = new MyHandler(looper); 

                handler.removeMessages(0); 

                //构建Message对象 

                //第一个参数:是自己指定的message代号,方便在handler选择性地接收 

                //第二三个参数没有什么意义 

                //第四个参数需要封装的对象 

                Message msg = handler.obtainMessage(1,1,1,"主线程发消息了"); 

                handler.sendMessage(msg); //发送消息 

            } 

        }); 

    } 

    class MyHandler extends Handler{ 

        public MyHandler(Looper looper){ 

            super(looper); 

        } 

        public void handleMessage(Message msg){ 

            super.handleMessage(msg); 

            textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj); 

        } 

    } 



2、其他线程给主线程发送Message 

package test.message; 

import android.app.Activity; 

import android.os.Bundle; 

import android.os.Handler; 

import android.os.Looper; 

import android.os.Message; 

import android.view.View; 

import android.widget.Button; 

import android.widget.TextView; 

public class MainActivity extends Activity { 

    private Button btnTest; 

    private TextView textView; 

    private Handler handler; 

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        setContentView(R.layout.main); 

        btnTest = (Button)this.findViewById(R.id.btn_01); 

        textView = (TextView)this.findViewById(R.id.view_01); 

        btnTest.setOnClickListener(new View.OnClickListener() { 

            @Override 

            public void onClick(View arg0) { 

                //可以看出这里启动了一个线程来操作消息的封装和发送的工作 

                //这样原来主线程的发送就变成了其他线程的发送,简单吧?呵呵 

                new MyThread().start();     

            } 

        }); 

    } 

    class MyHandler extends Handler{ 

        public MyHandler(Looper looper){ 

            super(looper); 

        } 

        public void handleMessage(Message msg){ 

            super.handleMessage(msg); 

            textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj); 

        } 

    } 

    //加了一个线程类 

    class MyThread extends Thread{ 

        public void run(){ 

            Looper looper = Looper.getMainLooper(); //主线程的Looper对象 

            //这里以主线程的Looper对象创建了handler, 

            //所以,这个handler发送的Message会被传递给主线程的MessageQueue。 

            handler = new MyHandler(looper); 

            //构建Message对象 

            //第一个参数:是自己指定的message代号,方便在handler选择性地接收 

            //第二三个参数没有什么意义 

            //第四个参数需要封装的对象 

            Message msg = handler.obtainMessage(1,1,1,"其他线程发消息了"); 

            handler.sendMessage(msg); //发送消息             

        } 

    } 



3、主线程给其他线程发送Message 

package test.message; 

import android.app.Activity; 

import android.os.Bundle; 

import android.os.Handler; 

import android.os.Looper; 

import android.os.Message; 

import android.view.View; 

import android.widget.Button; 

import android.widget.TextView; 

public class MainActivity extends Activity { 

    private Button btnTest; 

    private TextView textView; 

    private Handler handler; 

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        setContentView(R.layout.main); 

        btnTest = (Button)this.findViewById(R.id.btn_01); 

        textView = (TextView)this.findViewById(R.id.view_01); 

        //启动线程 

        new MyThread().start();     

        btnTest.setOnClickListener(new View.OnClickListener() { 

            @Override 

            public void onClick(View arg0) { 

                //这里handler的实例化在线程中 

                //线程启动的时候就已经实例化了 

                Message msg = handler.obtainMessage(1,1,1,"主线程发送的消息"); 

                handler.sendMessage(msg); 

            } 

        }); 

    } 

    class MyHandler extends Handler{ 

        public MyHandler(Looper looper){ 

            super(looper); 

        } 

        public void handleMessage(Message msg){ 

            super.handleMessage(msg); 

            textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj); 

        } 

    } 

    class MyThread extends Thread{ 

        public void run(){ 

            Looper.prepare(); //创建该线程的Looper对象,用于接收消息 

            //注意了:这里的handler是定义在主线程中的哦,呵呵, 

            //前面看到直接使用了handler对象,是不是在找,在什么地方实例化的呢? 

            //现在看到了吧???呵呵,开始的时候实例化不了,因为该线程的Looper对象 

            //还不存在呢。现在可以实例化了 

            //这里Looper.myLooper()获得的就是该线程的Looper对象了 

            handler = new ThreadHandler(Looper.myLooper()); 

            //这个方法,有疑惑吗? 

            //其实就是一个循环,循环从MessageQueue中取消息。 

            //不经常去看看,你怎么知道你有新消息呢??? 

            Looper.loop();  

        } 

        //定义线程类中的消息处理类 

        class ThreadHandler extends Handler{ 

            public ThreadHandler(Looper looper){ 

                super(looper); 

            } 

            public void handleMessage(Message msg){ 

                //这里对该线程中的MessageQueue中的Message进行处理 

                //这里我们再返回给主线程一个消息 

                handler = new MyHandler(Looper.getMainLooper()); 

                Message msg2 = handler.obtainMessage(1,1,1,"子线程收到:"+(String)msg.obj); 

                handler.sendMessage(msg2); 

            } 

        } 

    } 



4、其他线程给自己发送Message  

package test.message; 

import android.app.Activity; 

import android.os.Bundle; 

import android.os.Handler; 

import android.os.Looper; 

import android.os.Message; 

import android.view.View; 

import android.widget.Button; 

import android.widget.TextView; 

public class MainActivity extends Activity { 

    private Button btnTest; 

    private TextView textView; 

    private Handler handler; 

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        setContentView(R.layout.main); 

        btnTest = (Button)this.findViewById(R.id.btn_01); 

        textView = (TextView)this.findViewById(R.id.view_01); 

        btnTest.setOnClickListener(new View.OnClickListener() { 

            @Override 

            public void onClick(View arg0) { 

                //启动线程 

                new MyThread().start();     

            } 

        }); 

    } 

    class MyHandler extends Handler{ 

        public MyHandler(Looper looper){ 

            super(looper); 

        } 

        public void handleMessage(Message msg){ 

            super.handleMessage(msg); 

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

        } 

    }     

    class MyThread extends Thread{ 

        public void run(){ 

            Looper.prepare(); //创建该线程的Looper对象 

            //这里Looper.myLooper()获得的就是该线程的Looper对象了 

            handler = new ThreadHandler(Looper.myLooper()); 

            Message msg = handler.obtainMessage(1,1,1,"我自己"); 

            handler.sendMessage(msg); 

            Looper.loop();  

        } 

        //定义线程类中的消息处理类 

        class ThreadHandler extends Handler{ 

            public ThreadHandler(Looper looper){ 

                super(looper); 

            } 

            public void handleMessage(Message msg){ 

                //这里对该线程中的MessageQueue中的Message进行处理 

                //这里我们再返回给主线程一个消息 

                //加入判断看看是不是该线程自己发的信息 

                if(msg.what == 1 && msg.obj.equals("我自己")){ 

                    handler = new MyHandler(Looper.getMainLooper()); 

                    Message msg2 = handler.obtainMessage(1,1,1,"禀告主线程:我收到了自己发给自己的Message"); 

                    handler.sendMessage(msg2);                 

                } 

            } 

        } 

    } 



  
总结:就是主线程和子线程之间或自身间的消息发送,对应自身间的传递也没有什么卵用。

其实android中有封装好的handler+thread的工具,那就是AsyncTask
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android handler