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例子:

Android 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

你可能感兴趣的:(android)