Article directory
I. Introduction
Kotlin's coroutines are sometimes very convenient. Jetpack provides enough compatibility, and some of it is recorded here
2. Introducing dependencies
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.fragment:fragment-ktx:1.5.0'
implementation 'androidx.activity:activity-ktx:1.5.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
3. Code example
1. Basic Usage
Any class that implements LifecycleOwner
the interface can use the following methods to start the coroutine, for example Fragment
, ComponentActivity
and its subclasses
//可以使用以下方式开启协程度,优势在于自己不要处理页面结束后的关闭问题
lifecycleScope.launch {
}
ViewModel
viewModelScope.launch {
}
2、repeatOnLifecycle
If there is a requirement that needs to be processed according to the life cycle of the page, for example, onStart
when the coroutine is started and onStop
when the coroutine is stopped, the following methods can be used. This lifecycle is called a restartable lifecycle-aware coroutine
override fun onCreate(savedInstanceState: Bundle?) {
lifecycleListener()
}
private fun lifecycleListener(){
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED){
while (isActive){
delay(1000)
Log.e("YM---->","线程运行中....")
}
}
}
}
It should be noted that the official once mentioned a function addRepeatingJob
similar to this function, but addRepeatingJob
it already lifecycle-runtime-ktx:2.4.0-alpha01
existed in , and lifecycle-runtime-ktx:2.4.0-alpha02
it was removed at that time. The reference link is as follows:
repeatOnLifecycle API design story
3、flowWithLifecycle
If you are just Flow
monitoring a data stream, you can use the following method
private fun lifecycleListener(){
lifecycleScope.launch {
(1..9).asFlow().flowWithLifecycle(lifecycle,Lifecycle.State.STARTED).collect{
println("YM---->value:$it")
}
}
}
Since flowWithLifecycle
it is Flow
a function, it can be hung on the thermal flow StateFlow
or ShareFlow
above. If you have multiple streams, you can only use the above repeatOnLifecycle
method
4、lifecycle.whenCreated、lifecycle.whenStarted 和 lifecycle.whenResumed
repeatOnLifecycle
Activities can be limited to a certain range, but this will be repeated as the life cycle repeats, but if it is only used once, it does not need to be so, you can use the following methods,
class MyFragment: Fragment {
init {
lifecycleScope.launch {
whenStarted {
}
}
//或者
lifecycleScope.launchWhenCreated {
}
}
}
However, this way of writing sometimes has the problem of layer-by-layer nesting, and the following way of writing can also be used
val isCreated = lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)
if (!isCreated) return
5. Coroutine and LiveData
When using LiveData
, we sometimes need to get content asynchronously, usually create it LiveData
, and then onCreate()
actively load data in it. The following methods can simplify this operation
private val user: LiveData<Int> = liveData {
// val data = database.loadUser() // loadUser is a suspend function.
//delay(5000)
emit(10)
}
override fun onCreate(savedInstanceState: Bundle?) {
lifecycleListener()
}
private fun lifecycleListener(){
user.observe(this){
Log.e("YM---->"," 参数:$it")
}
}
The following is quoted from the official website
When LiveData becomes active, the code block starts executing; when LiveData
becomes inactive, the code block is automatically canceled after a configurable timeout. If the code block is canceled before completing, it will
restart after LiveData becomes active again; if it completed successfully in the previous run, it will not restart. Note that code blocks will only restart if they are automatically canceled. If the code block is
canceled for any other reason (for example, throwing a CancellationException), it will not be restarted.
When the page enters onStop
, the data will not be sent until the page is restored again. It should be noted that in the actual test, the logic will not be re-executed, but the loaded data will be sent directly when the page is restored next time.