一、目标
处理异步任务,并提供用户进度反馈。
二、体验地址
神马笔记最新版本下载:【神马笔记 版本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. 进阶方案
如果每个异步任务都从Thread
和Handler
开始开发,则重复的工作有一大堆。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
~料得年年肠断处~明月夜~短松冈~