android学习11——Handler,Looper,MessageQueue工作原理

Message是Handler接收和处理的消息对象. 每个线程只能拥有一个Looper.它的loop方法读取MessageQueue中的消息,读到消息之后就把消息交给发送该消息的Handler进行处理.MessageQueue是消息队列,它采用先进先出的方式来管理Message.程序创建Looper对象时会在它的构造器中创建MessageQueue对象.
下面用一个例子说明.不能在主线程中执行耗时的工作,否则会报ANP错误.常用的方法是在主线程中向子线程中发消息,交给子线程处理.看下面的例子.

public class SumThread extends Thread {
    private Handler handler;
    private Context context;
    public SumThread(Context context) {
        this.context = context;
    }
    @Override
    public void run() {
        Log.i("Logzy", "Loop prepare");
        Looper.prepare();
        handler = new SumHandler(context);
        Looper.loop();
        Log.i("Logzy", "Loop end");
    }

    public Handler getHandler() {
        return handler;
    }
}

在子线程中创建一个Handler.注意在子线程中创建Handler的时候,要先创建Looper对象,并通过prepaer启动它. Looper.loop()是一个死循环,不断从MessageQueue中取出消息交给Handler处理.所以除非显式退出Looper,Log.i("Logzy", "Loop end")这行代码不会被执行.另外需要注意的一点是在主线程中,系统已经初始化一个Looper对象,因此程序直接创建Handler即可,然后就可通过Handler来发送,处理消息.主线程中创建Handler的方法见这个例子http://www.cnblogs.com/zhouyang209117/p/5108048.html
例子的源代码:https://github.com/zhouyang209117/AndroidTutorial/tree/master/Crazy/ch3/Loop
再说HandlerThread的用法.上面已经提到子线程中创建Handler的时候,要先创建Looper对象,并通过prepaer启动.HandlerThread可以将这些操作简化.看下面代码:

public class MyActivity extends Activity {
    static final String UPPER_NUM = "upper";
    EditText etNum;
    private Handler handler;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        etNum = (EditText)findViewById(R.id.etNum);
        HandlerThread handlerThread = new HandlerThread("aaa");
        handlerThread.start();
        handler = new SumHandler(this, handlerThread.getLooper());
    }
    
    public void cal(View source) {
        Message msg = new Message();
        msg.what = 0x123;
        Bundle bundle = new Bundle();
        bundle.putInt(UPPER_NUM,
                Integer.parseInt(etNum.getText().toString()));
        msg.setData(bundle);
        handler.sendMessage(msg);
    }
}

最重要的是这3行代码:

HandlerThread handlerThread = new HandlerThread("aaa");
handlerThread.start();
handler = new SumHandler(this, handlerThread.getLooper());

HandlerThread也是一个线程.通过start()启动,里面的Looper就已经初始化好了再调用handler = new SumHandler(this, handlerThread.getLooper()),可以启动Looper,不用再显式启动.这样简化了代码.
源代地址:https://github.com/zhouyang209117/AndroidTutorial/tree/master/Crazy/ch3/HandlerThread

原文地址:https://www.cnblogs.com/zhouyang209117/p/5323170.html