请结合示意图说明如何通过 Looper,Handler和HandlerThread 的异步消息处理机制来完成从主线程安排多张图片的下载任务以及图片下载完成后如何实现界面刷新。(8分)
时间: 2024-09-10 12:23:43 浏览: 18
在Android中,使用Looper、Handler和HandlerThread来实现主线程之外的任务异步处理非常常见。这有助于防止UI线程阻塞,提高应用性能。以下是利用这个机制来下载多张图片并更新UI的步骤:
1. **创建HandlerThread**:
- 首先,创建一个新的`HandlerThread`,比如叫它`DownloadThread`。这是因为HandlerThread会包含一个单独的Looper,可以在其中运行独立的消息循环。
```java
HandlerThread downloadThread = new HandlerThread("ImageDownloader");
downloadThread.start();
```
2. **Handler on DownloadThread**:
- 在`DownloadThread`中,创建一个`Handler`实例,它是Looper关联的。这样,当我们发送消息到这个Handler,它会在下载线程中处理。
```java
final Handler downloadHandler = new Handler(downloadThread.getLooper()) {
//...
};
```
3. **下载图片的Task**:
- 在`downloadHandler`的`handleMessage()`方法中,你可以编写一个用于下载图片的Runnable任务,并将它添加到队列中等待处理。
```java
void downloadImage(String imageUrl) {
// 创建一个下载任务
DownloadTask task = new DownloadTask(imageUrl);
// 使用Handler.sendMessageDelayed()发送任务到队列,指定延迟时间避免立即阻塞主线程
downloadHandler.sendMessageDelayed(downloadHandler.obtainMessage(), 0); // 立即执行
}
private class DownloadTask implements Runnable {
//...
}
```
4. **图片下载完成**:
- 当图片下载任务在`DownloadThread`中完成,`DownloadTask`应该回调给`downloadHandler`。
```java
public void onPostExecute(Bitmap bitmap) {
// 将Bitmap放入一个Message对象
Message message = downloadHandler.obtainMessage();
Bundle data = new Bundle();
data.putParcelable("image", bitmap);
message.setData(data);
downloadHandler.sendMessage(message);
}
```
5. **刷新UI**:
- 在主线程的`Handler`中,我们监听`downloadHandler`的消息,当接收到下载完成的消息时更新UI。
```java
Handler mainThreadHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
if (msg.getData().containsKey("image")) {
Bitmap bitmap = msg.getData().getParcelable("image");
// 更新UI显示图片
imageView.setImageBitmap(bitmap);
}
}
};
// 主线程中设置接收下载完成消息
downloadHandler.setCallback(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
return true; // 允许下载Handler处理消息
}
});
```