在activity中使用协程很方便。
在添加依赖implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
后,可以直接调用lifecycleScope.launch
,无需考虑协程的管理。
https://developer.android.com/topic/libraries/architecture/coroutines?hl=zh-cn#lifecyclescope
LifecycleScope
为每个 Lifecycle
对象定义了 LifecycleScope
。在此范围内启动的协程会在 Lifecycle
被销毁时取消。您可以通过 lifecycle.coroutineScope
或 lifecycleOwner.lifecycleScope
属性访问 Lifecycle
的 CoroutineScope
。
如下所示。
// MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
lifecycleScope.launch{
repeatOnLifecycle(Lifecycle.State.STARTED) {
repeat(Int.MAX_VALUE){
Log.d(TAG,"inner repeat")
delay(3000L)
}
}
}
}
因为AppCompatActivity继承自ComponentActivity,而ComponentActivity实现了LifecycleOwner接口,并且在适当的时机修改了Lifecycle.State。
只要自定义View实现了LifecycleOwner接口,并且修改Lifecycle.State,就可以使得View变成生命周期感知型组件。
class MyViewPager2 @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
) : FrameLayout(context, attrs, defStyle) , LifecycleOwner {
private var binding: LayoutMyViewpager2Binding
private lateinit var lifecycleRegistry: LifecycleRegistry
init {
Log.d(TAG,"inner init")
binding = LayoutMyViewpager2Binding.inflate(LayoutInflater.from(context),this,true)
addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
// View onDetached 的时候调用 onDestroy()
override fun onViewDetachedFromWindow(v: View?) {
Log.d(TAG,"inner onViewDetachedFromWindow")
// 在Lifecycle被销毁之后,协程会跟着取消
onDestroy()
}
// View onAttached 的时候调用 onStart()
override fun onViewAttachedToWindow(v: View?) {
Log.d(TAG,"inner onViewAttachedToWindow")
onStart()
}
})
}
fun onStart() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED
Log.d(TAG,"inner onStart currentState = ${lifecycleRegistry.currentState}")
}
fun onDestroy() {
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
}
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
// 开启自动滚动
fun autoScroll(){
Log.d(TAG,"inner autoScroll")
lifecycleScope.launch(exceptionHandler) {
repeatOnLifecycle(Lifecycle.State.STARTED) {
repeat(Int.MAX_VALUE){
Log.d(TAG,"inner repeat")
delay(3000L)
}
}
}
}
private val exceptionHandler = CoroutineExceptionHandler { _, exception ->
Log.d(TAG, "CoroutineExceptionHandler exception : ${exception.message}")
}
// 注册
fun register(){
lifecycleRegistry = LifecycleRegistry(this)
Log.d(TAG,"after lifecycleRegistry")
}
}
不过我后来想想,这种写法没有必要。
其实应该写个自定义View中写个回调,在ViewModel中开启协程。还是编程思想的转变问题。
https://developer.android.com/topic/libraries/architecture/lifecycle?hl=zh-cn#use-cases
生命周期感知型组件的最佳做法
- 设法编写数据驱动型界面,对于此类界面,界面控制器的责任是随着数据更改而更新视图,或者将用户操作通知给
ViewModel
。
参考链接:
使用生命周期感知型组件处理生命周期
将 Kotlin 协程与生命周期感知型组件一起使用
How to make custom view Lifecycle Aware in Android
自定义生命周期以及实现生命周期感知能力
再谈协程之Lifecycle潜行者
每日一问:浅谈 onAttachedToWindow 和 onDetachedFromWindow
RecyclerView、View的onAttachedToWindow和onDetachedFromWindow调用时机
网友评论