上QQ阅读APP看书,第一时间看更新
1.2.3 取消响应
异步任务如果不加任何约束,就像放出去的小狗,如果它玩够了,就会自己回来。但也有很多情况下我们希望它能提前回来,这种情况就只能出去找了,当然,还不一定找得到。所以异步任务必须要像风筝一样,在需要的时候能够由外部主动收回。
对于前面的例子,最简单的改法就是将thread函数创建的Thread实例返回,在download函数中不断检查线程的中断标志来实现任务的取消响应。如代码清单1-10所示。
代码清单1-10 取消异步调用
fun asyncBitmapCancellable( url: String, onSuccess: (Bitmap) -> Unit, onError: (Throwable) -> Unit ) = thread { try { downloadCancellable(url).also(onSuccess) } catch (e: Exception) { onError(e) } } fun downloadCancellable(url: String): Bitmap { return getAsStream(url).use { inputStream -> val bos = ByteArrayOutputStream() val buffer = ByteArray(1024) while (true) { ... if (Thread.interrupted()) throw InterruptedException("Task is cancelled.") } bos.toByteArray() } }
如果需要取消任务,调用asyncBitmapCancellable返回的线程的interrupt函数即可。
请注意,取消响应中的响应是很关键的一点,需要异步任务主动配合取消,如果它不配合,那么外部也就没有办法,只能听之任之了。这时的异步任务颇有断线风筝的意思,能否回来只能看风筝自己的“心情”了。
注意 JDK最初提供了停止线程的API,但它很快就被废弃了,因为强行停止一个线程会导致该线程中持有的资源无法正常释放,进而出现不安全的程序状态。