Android Handler

来源:互联网 发布:二次元 社区 论坛源码 编辑:程序博客网 时间:2024/06/06 23:02
 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

0 0
原创粉丝点击