Handler 异步消息处理机制的简单使用
Android 提供了一套异步消息处理机制,主要由 4 个部分组成:Message、Handler、MessageQueue 和 Looper。
在 播放音视频 篇章中用来控制进度条 UI 变化所使用的 runOnUiThread()
方法就是一个异步消息处理机制的接口封装,可以在子线程中切换到 UI 线程进行操作。下面就简单介绍下 Handler 异步消息处理机制的各个组成部分。
- Message 是在线程之间传递的消息,它可以在内部携带少量信息,用于在不同的线程之间传递数据。其中 what,arg1 和 arg2 属性字段可以携带整型数据,obj 属性字段可以携带一个 Object 对象。
- Handler 主要用于发送和处理消息。发送消息可以使用 Handler 的
sendMessage()
方法或post()
方法,发出的消息最终会传递到 Handler 的handleMessage()
方法中进行处理。 - MessageQueue 是消息队列,主要用于存放所有通过 Handler 发送的消息。每个线程中只会有一个 MessageQueue 对象。
- Looper 是每个线程中 MessageQueue 的管家,调用 Looper 的
loop()
方法后就会进入一个循环中,只有 MessageQueue 中存在消息就将消息取出,并传递到 Handler 的handleMessage()
方法中进行处理。每个线程只有一个 Looper 对象。
使用步骤:
-
在主线程中创建一个 Handler 对象并指定构造参数 Looper 为
Looper.getMainLooper()
,然后重写handleMessage()
方法。public class MainActivity extends AppCompatActivity { private Handler handler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(@NonNull Message msg) { switch (msg.what) { case 1: // TODO 执行 UI 操作等 break; } } }; // ...
-
当子线程需要进行 UI 操作时,创建一个 Message 对象,通过 Handler 发送出去。
public class MainActivity extends AppCompatActivity {
// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ...
new Thread(new Runnable() {
@Override
public void run() {
// TODO 一系列操作
Message message = new Message();
message.what = 1;
message.obj = "Amie";
handler.sendMessage(message);
}
}).start();
}
}
AsyncTask
Android 官方提供了一个 AsyncTask 抽象类帮助我们从子线程切换到主线程,背后原理也是基于 Hanlder 异步消息处理机制的。API 30 开始,AsyncTask 被标记为 Deprecated,这里就不再对其进行介绍,以后可能也许应该大概估计也不会。
官方文档给出了两种替代方案:
- Java 代码:Executor 或 ThreadPoolExecutor 或 FutureTask
- Kotlin 代码:Kotlin 协程