一.协程用来解决什么问题
在Android开发中协程主要用于解决两个问题:
- 1.处理耗时任务
- 2.保证主线程安全
二.使用协程来处理协程任务
在开发中我们通常可以使用new Thread+Handler,RxJava+Retrofit,ansyTask等等方案处理耗时任务,原理都是通过子线程去处理任务,处理结果再回调主线程的函数。类似如下代码:
private void queryLedqueue(LedQueueVo vo) {
ApiService apiService = RetrofitHelper.getInstance().getApiService(ApiService.class);
apiService.queryLedqueue(HttpUtil.convertVo2Params(vo)).
subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<LedQueueDto>() {
@Override
public void onSubscribe(Subscription s) {
s.request(10);
}
@Override
public void onNext(LedQueueDto ledQueueDto) {
hideLoading();
if (ledQueueDto != null) {
showToast("查询成功");
Log.e(TAG, "onNext: " + ledQueueDto.toString());
} else {
showToast("查询失败");
}
}
@Override
public void onError(Throwable t) {
hideLoading();
showToast("查询失败:" + t);
}
@Override
public void onComplete() {
}
});
}
以上的方法也是可以的,但是使用起来略微麻烦,协程可以通过更加简单的办法实现处理耗时任务。如下
private suspend fun suspandMain() {
//请求网络
val result = suspendingGetImage("你好")
//设置UI
tv_test.setText(result)
}
/**
* 耗时任务,请求网络
*/
suspend fun suspendingGetImage(id: String): String = withContext(Dispatchers.IO) {
Log.e("3 MainActivity", "当前线程: ${Thread.currentThread().name}")
id
}
协程在常规函数之外增加了两个操作,suspend和resume,挂起和恢复,当协程中的代码运行到suepend函数的时候,协程会挂起,supend函数会去执行相应的任务,比如耗时任务,当supend函数执行完之后,协程会恢复。继续执行协程里的代码。并且协程的挂起是不会阻塞主线程的。
三.使用协程保证主线程安全
以上我们知道协程执行到suspend函数的时候,协程会挂起,那么在supend函数里,我们需要使用调度器调度线程,使得supend里的耗时任务执行在其他非主线程中,例如以上例子的Dispatchers.IO,如果没有调度IO线程,那么suspend函数还是运行在主线程中,同样会导致主线程阻塞。
/**
* 耗时任务,请求网络
*/
suspend fun suspendingGetImage(id: String): String = withContext(Dispatchers.IO) {
Log.e("3 MainActivity", "当前线程: ${Thread.currentThread().name}")
id
}
四.小结
在Android开发中,协程用来处理耗时任务,我们可以把耗时任务如请求网络,读写文件,读写数据库放在协程的代码块中,通过suspend挂起函数去处理耗时任务。当耗时任务完成时,在恢复协程。
网友评论