为什么使用Handler
在Java里面线程间通信的方式有好些方式,在Android里我们常用的方式之一是通过Handler,做过点Android开发的都知道,在Android里对界面上的一些操作都需要放在主线程或者说UI线程中,其实不在主线程中也能操作,当然有特殊要求,具体请自行百度。总之,通过Handler我们能比较方便的在子线程和主线程间通信。
相关类
android.os.Handler
发送消息和处理消息都需要通过它。它会与一个Looper相关联。
android.os.Looper
通常我们叫轮询器,负责消息分发的。一个Looper只能和一个线程关联。
android.os.MessageQueue
消息队列,放消息的,每个Looper和线程最多只会有一个消息队列。
android.os.Message
它可以存放一些数据并传递给相应消费线程。
Handler的简单示例
public class MainActivity extends AppCompatActivity {
private TextView mTvTip;
private Button mBtnDownLoad;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
// what为0表示下载完成
case 0:
mTvTip.setText("苍老师的电影下载好啦,还不快去鉴赏。");
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTvTip = (TextView) findViewById(R.id.tv_tip);
mBtnDownLoad = (Button) findViewById(R.id.btn_download);
mBtnDownLoad.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// 睡眠5秒钟模拟下载过程
SystemClock.sleep(1000 * 5);
Message msg = mHandler.obtainMessage();
// 下载完成,将msg的what值设定为0
msg.what = 0;
msg.sendToTarget();
}
}).start();
}
});
}
}
代码很简单,界面就一个TextView
和一个Button
,给按钮设定了点击监听,点击的时候起了个线程去下载老师的艺术片儿,下载完后在界面上用文字通知咱们去鉴赏。
Handler的模式
从上面我们的示例代码可以看出,子线程将一个msg传递到主线程去处理,就相当于一个生产者消费者模式,子线程生产,主线程消费。如下图所示:
1、插入,生产者线程(对于我们上面的示例就是子线程)通过消费者线程(对于我们上面的示例就是UI线程)上的Handler将msg插入到消息队列里。
2、检索,运行在消费者线程的Looper会按顺序检索MessageQueue里的消息。
3、分发,消费者线程上的Handler负责处理msg,一个线程可以有多个Handler来处理msg,Looper会将相应的msg分发给对应的Handler来处理。
子线程使用Handler
之前我们的例子是在UI线程里实例化Handler的,所以UI线程可以接收到消息,那如何发送消息到子线程呢?我们试试在子线程里实例化Handler:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstan