Android handler学习笔记

  • 调用Message.obtain()从消息池中获得一个message对象,而不是直接new一个message对象,可以节省内存开销。也可以用handler.obtainMessage(),其实是一样的,obtainMessage()就是返回Message.obtain()
  • message.sendToTarget()跟handler.sendMessage()是一样的
  • 下面的方式可以拦截Message。
    private Handler handler=new Handler(new Callback(){
            public boolean handleMessage(Message msg){
                //在Callback中可以拦截掉message
                //这里返回true以后就不会再执行下面的那个handleMessage。
                if(msg.what==1)return true;
                return false;
            }
        }){
            public void handleMessage(Message msg){
                //处理消息
            }
        };

     

  • Handler发送消息,加入MessageQueue队列。Looper接收Handler发过来的消息,轮询MessageQueue队列,然后回传给Handler。
  • Message绑定handler。可以用 
    Message msg=handler.obtainMessage();  msg.sendToTarget();
    Message msg=Message.obtain(handler);  msg.sendToTarget();
    Message msg=Message.obtain();   handler.sendMessage(msg);
    或者手动绑定,使用  msg.setTarget(handler);

     

  • HandlerThread自动包含Looper,不需要手动创建,用起来方便。
  • 因为主线程中默认包含了一个Looper,所以不需要再传入Looper。在子线程中使用Handler则需要传入一个thread的looper进去,而如果thread是handlerThread,可以直接用handlerThread.getLooper()拿到looper。如果是自己写的一个thread,在里面创建一个looper,因为不同线程处理,很可能报空指针错误。
  • 为普通线程创建Looper的方法如下:在线程run()方法当中先调用Looper.prepare()初始化Looper,然后再run()方法最后调用Looper.loop(),这样我们就在该线程当中创建好Looper。(注意:Looper.loop()方法默认是死循环)。用HandlerThread可以省事。
  • Handler会关联一个单独的线程和消息队列。
  • 只有在run中的东西才是运行在子线程中的。

下面做了一个例子,handler例子:

技术分享

 

技术分享
package com.ac.handlertest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {
    private Layout layout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initLayout();
        initValue();
    }

    private void initLayout() {
        layout = new Layout();
        layout.helloText = (TextView) findViewById(R.id.helloText);
        layout.button1 = (Button) findViewById(R.id.button1);
        layout.button2 = (Button) findViewById(R.id.button2);
        layout.button3 = (Button) findViewById(R.id.button3);
        layout.button1.setOnClickListener(this);
        layout.button2.setOnClickListener(this);
        layout.button3.setOnClickListener(this);
    }

    private void initValue() {
        layout.helloText.setText("");
        layout.button1.setText("1.主线程的Handler");
        layout.button2.setText("2.普通子线程的Handler");
        layout.button3.setText("3.使用HandlerThread");
    }

    private class Layout {
        TextView helloText;
        Button button1;
        Button button2;
        Button button3;
    }

    // 1.主线程的Handler
    private void method_1() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.i("msg", "" + Thread.currentThread());//主线程
                layout.helloText.setText("因为主线程中默认包含了一个Looper,所以不需要再传入Looper。");
            }
        }, 1000);
    }

    // 2.普通子线程的Handler
    private void method_2() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                Handler handler = new Handler() {
                    public void handleMessage(Message msg) {
                        Log.i("msg", "" + Thread.currentThread());//子线程myThread1
                        runOnUiThread(new Runnable() {
                            public void run() {
                                layout.helloText
                                        .setText("为普通线程创建Looper的方法如下:在线程run()方法当中先调用Looper.prepare()初始化Looper,然后再run()方法最后调用Looper.loop(),这样我们就在该线程当中创建好Looper。(注意:Looper.loop()方法默认是死循环)。");
                            }
                        });
                    };
                };
                try {
                    Thread.sleep(1000);
                    handler.sendEmptyMessage(0);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Looper.loop();
            }
        });
        thread.setName("myThread1");
        thread.start();
    }

    // 3.使用HandlerThread
    private void method_3() {
        HandlerThread handlerThread = new HandlerThread("myThread2");
        handlerThread.start();
        Handler handler = new Handler(handlerThread.getLooper()) {
            public void handleMessage(Message msg) {
                Log.i("msg", "" + Thread.currentThread());//子线程myThread2
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        layout.helloText
                                .setText("而handlerThread可以直接用handlerThread.getLooper()拿到looper,可以不用管looper,可以省事");
                    }
                });
            }
        };
        handler.sendEmptyMessage(0);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.button1:
            method_1();
            break;
        case R.id.button2:
            method_2();
            break;
        case R.id.button3:
            method_3();
            break;
        default:
            break;
        }
    }
}
MainActivity.java

 

完整demo:http://pan.baidu.com/s/1qWwTs3y

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。