之前说过了,Android不允许主线程(MainThread)外的线程(WorkerThread)去修改UI组件,但是又不能把所有的更新UI的操作都放在主线程中去(会造成ANR),那么只能单独启动一个子线程(WorkerThread)去处理,处理完成之后,将结果通知给UI主线程,子线程和主线程的通信就用到了Handler。
Handler、Looper和MessageQueue的基本原理
先看一下他们的职责:
Handler——处理者,负责发送以及处理Message。
MessageQueue——消息队列,用来存放Handler发送过来的消息,采用FIFO(first in first out)规则将Message以链表的方式串联起来的,等待Looper的抽取。
Looper——消息泵,不断的从消息队列中取出消息并回传给Handler
1. Handler对象调用obtainMessage()方法获取Message对象
2. 调用sendMessage(Message msg)方法将消息发送到消息队列(MessageQueue)中
3. Looper循环这从消息队列中取出msg
4. 调用Handler对象的handleMessage(Message msg)方法,将取出的msg传给Handler
Handler将消息传到队列,Looper从队列中拿到消息,然后又传给了Handler,这似乎是一个无用功,我们通过代码来看一下。
package cn.lixyz.handlertest; import android.app.Activity; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; /** * 实现点击按钮,开始播放幻灯片,每张幻灯片间隔2s。 */ public class MainActivity extends Activity { private Button button; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); handler = new MyHandler(); button.setOnClickListener(new ButtonOnClickListener()); } class ButtonOnClickListener implements View.OnClickListener { @Override public void onClick(View v) { Thread t = new ChangePicThread(); t.start(); } } class ChangePicThread extends Thread { @Override public void run() { super.run(); try { Thread.sleep(1 * 1000); Log.d("TTTTT", "---->" + Thread.currentThread().getName()); Message msg = handler.obtainMessage(); msg.what = 100; handler.sendMessage(msg); } catch (InterruptedException e) { e.printStackTrace(); } } } //创建内部类,继承Handler,用来创建Handle对象 class MyHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d("TTTTT", "====>" + Thread.currentThread().getName()); int i = msg.what; Log.d("TTTTT", "message=" + i); } } }