Ali*_*Ali 5 android-jetpack-compose
举一个简单的例子,如何在不使用 ViewModel 或 Hilt 等的情况下访问我们应用程序的 Exit 事件?
例如,当我们退出应用程序时显示简单的 Toast 消息。
下面的代码,当我们按后退按钮退出时,可以正常工作,并显示 toast:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var ctx = applicationContext
setContent {
checkExit(ctx)
}
}
}
@Composable
fun checkExit(ctx: Context) {
DisposableEffect(""){
onDispose {
Toast.makeText(ctx, "onExit", Toast.LENGTH_LONG).show()
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是如果我们最小化应用程序,然后在后台向上滑动屏幕退出,这个toast将不再显示
**Working Code, thanks to AgentP**
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var ctx = applicationContext
setContent {
val lifecycle: LifecycleOwner = LocalLifecycleOwner.current
checkExit(ctx, lifecycle)
}
}
}
@Composable
fun checkExit(ctx: Context, lifecycle: LifecycleOwner) {
DisposableEffect(Unit) {
val observer = LifecycleEventObserver { _, event ->
when(event){
Lifecycle.Event.ON_STOP -> {
Toast.makeText(ctx, "onExit", Toast.LENGTH_SHORT).show()
}
}
}
lifecycle.lifecycle.addObserver(observer)
onDispose {
lifecycle.lifecycle.removeObserver(observer)
}
}
}
Run Code Online (Sandbox Code Playgroud)
要理解这里的问题,您需要了解compose 中的副作用
什么是一次性效果?
组合的副作用,必须针对 key1 的任何新的唯一值运行,并且如果 key1 更改或 DisposableEffect 离开组合,则必须反转或清除。
基本上,它会运行
在这种情况下,发生这种情况的原因是第二个,即它是由于退出组合而引起的
但是为什么当你按回键时它可以工作,为什么当你杀死最近的应用程序时它不起作用?
为了更好地理解这一点,请阅读应用程序被终止时未调用的 onDispose 回调
引用上述问题的答案
Composer 处于什么
disposed状态。如果 没有发送,作曲者不会处理viewLifecycleON_DESTROYON_DESTROY
ON_DESTORY所以基本上发生的情况是,如果组合无法从生命周期接收到,则组合将不会进行处置
除非您要删除一些观察者和所有观察者,否则在 onDispose 中调用任何内容都是不安全的。
如何解决这个问题?
您可以使用下面的代码
DisposableEffect(Unit) {
val observer = LifecycleEventObserver { lifecycleOwner, event ->
when(event){
Lifecycle.Event.ON_STOP,Lifecycle.Event.ON_DESTROY -> {
checkCtx()
}
}
}
lifecycle.addObserver(observer)
onDispose {
lifecycle.removeObserver(observer)
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码为生命周期事件设置了一个观察者,并checkCtx()在生命周期获取ON_DESTROY或ON_STOP作为状态时调用该方法
checkCtx() :注意它不是一个可组合函数,它应该驻留在活动/片段中
private fun checkCtx() {
Toast.makeText(this, "onExit", Toast.LENGTH_LONG).show()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3194 次 |
| 最近记录: |