Android处理异步消息

Android处理异步消息

一、目标

处理异步任务,并提供用户进度反馈。

二、体验地址

神马笔记最新版本下载:【神马笔记 版本2.1.0——软件更新功能.apk

三、功能设计

软件更新过程中遇到的异步任务。

异步任务 说明
请求新版本 进入软件更新界面时,自动请求新版本信息。
以及自动版本检测。
下载安装包 用户在软件更新界面,下载安装包文件。
以及用户打开自动下载时,自动下载安装包。
验证完整性 启动安装时,需要验证安装包完整性。
虽然安装包文件小,在1秒内即可完成校验,但为保证用户体验,依然实现为异步任务。

因为这个任务都是耗时的任务,为了不阻塞用户操作,必须在新的线程完成。

四、实现方案

1. 基础方案

Java中实现异步的基础是线程Thread,通过重载Thread或实现Runnable接口可以实现子线程。

Android的用户操作是在主线程UI Thread中完成的,并且限制只有主线程才能更新控件,子线程不允许更新控件状态。必须使用Handler将消息从子线程发送到主线程。

核心类 说明
Thread/Runnable 实现异步任务的核心类,所有的异步任务均在子线程中实现。
Handler 将子线程消息转到主线程,从而更新UI状态。

必须注意的是Handler是Android异步的核心所在,凡是设计到更新UI状态的异步任务,必然会使用Handler将消息发送到主线程。如果异步任务不涉及UI操作,则不需要使用Handler

2. 进阶方案

如果每个异步任务都从ThreadHandler开始开发,则重复的工作有一大堆。Don't Repeat Yourself!我们来看看系统提高了哪些高级方案可供使用。

方案 说明
Java java.util.concurrent 使用Java的并发包可以大大简化异步开发工作量。
Android AsyncTask Android提供的异步任务。
HandlerThread/HandlerExecutor 支持Handler的Thread及Executor。

3. 高级方案

使用java.util.concurrent并发包已经大大降低了异步开发的难度及工作量。但如果涉及到UI操作,还需要编写代码使用Handler来传递消息。Don't Repeat Yourself!看看有哪些开源项目可用。

开源项目 说明
RxJava 优雅地实现了响应式及异步编程
RxAndroid 结合了Android的Handler,使RxJava能够在Android进行UI操作。

4. 取消异步任务

无论使用基础、进阶或者高级方案实现异步任务,都会面临一个问题——

如果异步任务还没有结束,用户已经离开所属的界面,应该怎么处理?

用户离开界面,或者说关闭了Activity,那么Activity便处于无效状态,此时调用Activity的任何接口都会导致出错。因此如果涉及到Activity包括UI操作,必须在关闭前取消异步任务。

  • 如何取消异步任务?
取消方式 说明
中断异步任务 在关闭Activity前,中断相关的任务。
中断的方式有很多中,比如调用线中断线程接口,设置标识位,抛出异常,……
取消消息传递 异步任务依然继续执行,只是不再接收异步任务的消息。
  • 何时取消异步任务?
取消时机 说明
用户触发 由用户决定何时取消异步任务,如弹出对话框,通知栏操作,……
onDestroy Activity销毁时,同时取消异步任务
onPause onDestroy相同,只是根据特定需要选择不同的触发事件。
  • 使用LifecycleObserver

与在Activity/Fragment的时间接口中取消异步任务,使用LifecycleObserver可以更加便利地取消异步任务。

五、举个例子

神马笔记实现软件更新功能使用的一些处理方案。

  • 软件更新界面
异步任务 实现方案 说明
请求新版本 网络请求:Retrofit + OkHttp
异步处理:RxJava + RxAndroid
使用Retrofit + OkHttp实现网络请求,OkHttp网络处理为异步操作,
使用RxJava + RxAndroid来处理请求结果,
同时onDestroy时,调用dispose接口,不再处理后续消息。
下载安装包 文件下载:OkHttp
异步处理:Handler
使用OkHttp下载文件,OkHttp已经实现异步任务。
使用Handler将消息传到主线程,以更新界面。
onDestroy时,取消消息传递,文件依然继续下载。
验证完整性 异步处理:RxJava + RxAndroid 使用RxJava异步编程计算文件校验码。同时在主线程中通知用户比较结果。
onDestroy时,调用dispose接口,不再处理后续消息。
  • 应用主界面
异步任务 实现方案 说明
请求新版本 onPause时,调用dispose。
下载安装包 不关心异步任务消息。

六、Finally

~料得年年肠断处~明月夜~短松冈~