* 玩安卓轮播图
*/
@GET("banner/json")
suspend fun getBanner(): BaseResult<List<BannerBean>>
和之前我们写的有什么区别呢:
1. 前面多了**suspend**关键字,带有这个关键字的函数,只有在协程中才能调用,在普通函数调用会报错的,编译也过不了
2. 返回结果只直接写对应的Bean就好了,不需要固定类型来包装
下边的用法是在ViewModel中来使用的,如果想在Activity或者Fragment中使用,是一样的,只不过启动协程的时候写法有些不同。 下面在我们的VIewModel中:
private val repository by lazy {
RetrofitClient.getInstance().create(HomeService::class.java)
}
fun getBanner() {
viewModelScope.launch {
val result = repository.getBanner()
if (result.errorCode == 0) {
LogUtils.d(result.data)
}
}
}
这样一个简单的网络请求就完成,**viewModelScope.launch {}** 这个就是在ViewModel中启动一个协程,**他会在ViewModel销毁的时候,自动取消他自己和在他内部启动的所有协程** 相对于RxJava来说,我们每次都要关心生命周期防止内存泄露,是不是加方便些呢,这样我们不用关心内存泄露的问题了。所以我们要启动子协程,都要写在他内部,除非有特殊需求,比如页面销毁了,要做些其他工作。否则都尽量在他内部启动。
好了,我们再看上面的代码,会发现有个问题,\*\*viewModelScope.launch {}\*\*是直接启动在主线程的,所以协程也会运行在主线程中,那我们怎么能让网络请求去影响到UI呢,绝对不能忍。我们可以在启动一个子协程让他运行在IO线程上。修改如下:
viewModelScope.launch {
val result = withContext(Dispatchers.IO) { repository.getBanner() }
if (result.errorCode == 0) {
LogUtils.d(result.data)
}
}
这下就正常了,是不是相当方便,代码也清