社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
Android 引入协程
//Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1'
直接使用GlobalScope,启动一个协程,并模拟延迟返回数据。
此方法会存在一个问题,Activity退出后,依然会获取到数据和弹出Toast。
mTvShow.setOnClickListener {
GlobalScope.launch(Dispatchers.Main) {
val deferred = async(Dispatchers.IO) {
delay(3000)
"数据返回了"
}
mTvShow.text = deferred.await()
Toast.makeText(applicationContext, "数据返回", Toast.LENGTH_SHORT).show()
}
}
MainScope是官方定义的适合的协程作用域。官方是这样定义的。
public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main)
我们可以这样使用MainScope
首先实现接口
class MainActivity : AppCompatActivity(), CoroutineScope by MainScope()
然后使用MainScope请求数据
launch {
val deferred = async(Dispatchers.IO) {
delay(3000)
"数据返回了"
}
mBtn1.text = deferred.await()
Toast.makeText(applicationContext, "MainScope", Toast.LENGTH_SHORT).show()
}
最后在退出时,取消协程
override fun onDestroy() {
super.onDestroy()
cancel()
}
ViewModel使用愈来愈频繁,所以还应该学习在ViewModel中使用协程。
首先创建协程
private val viewModelJob = SupervisorJob()
private val mainScope = CoroutineScope(Dispatchers.Main + viewModelJob)
获取数据,并将数据返回到LiveData
val message: MutableLiveData<String> = MutableLiveData()
fun getMessage() {
mainScope.launch {
val deferred = async(Dispatchers.IO) {
delay(3000)
Log.e("AppKt","数据返回了")
"数据返回了"
}
message.value = deferred.await()
}
}
在ViewModel退出时,需要结束协程
override fun onCleared() {
super.onCleared()
mainScope.cancel()
}
上一个方法,ViewModel中使用协程,需要每个ViewModel都自己定义,所以可以使用ktx拓展的viewModelScope。
引入ktx拓展
//ViewModel KTX
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-alpha03"
viewModelScope是ViewModel的一扩展属性,关闭时自动取消协程
val ViewModel.viewModelScope: CoroutineScope
get() {
val scope: CoroutineScope? = this.getTag(JOB_KEY)
if (scope != null) {
return scope
}
return setTagIfAbsent(JOB_KEY,
CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main))
}
internal class CloseableCoroutineScope(context: CoroutineContext) : Closeable, CoroutineScope {
override val coroutineContext: CoroutineContext = context
override fun close() {
coroutineContext.cancel()
}
}
使用更为简单
val message: MutableLiveData<String> = MutableLiveData()
fun getMessage(){
viewModelScope.launch {
val deferred = async(Dispatchers.IO){
delay(3000)
Log.e("AppKt","数据返回了")
"数据返回了"
}
message.value = deferred.await()
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!