Jetpack 编写 onExit 事件

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)

Age*_*ntP 7

要理解这里的问题,您需要了解compose 中的副作用

什么是一次性效果

组合的副作用,必须针对 key1 的任何新的唯一值运行,并且如果 key1 更改或 DisposableEffect 离开组合,则必须反转或清除。

基本上,它会运行

  1. 当您传递给它的键值发生变化或
  2. 当它离开组合物时。

在这种情况下,发生这种情况的原因是第二个,即它是由于退出组合而引起的

但是为什么当你按回键时它可以工作,为什么当你杀死最近的应用程序时它不起作用?

为了更好地理解这一点,请阅读应用程序被终止时未调用的 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_DESTROYON_STOP作为状态时调用该方法

checkCtx() :注意它不是一个可组合函数,它应该驻留在活动/片段中

private fun checkCtx() {
          Toast.makeText(this, "onExit", Toast.LENGTH_LONG).show()
     }
Run Code Online (Sandbox Code Playgroud)