文章目录

前言`一、基础概念二、举例1.使用原生webview2.DisposableEffect与LifecycleEventObserver3.代码分析

总结

前言`

阅读本文需要一定compose基础,如果没有请移步Jetpack Compose入门详解(实时更新)

本文介绍Compose中DisposableEffect的基本概念。根据官网教程总结,如有不对请在评论区指教

一、基础概念

用官方的话来说 Compose 中的附带效应是指发生在可组合函数作用域之外的应用状态的变化。 基于此,衍生了一系列的附带效应,今天我们介绍的就是DisposableEffect,DisposableEffect可用于初始化或订阅密钥,并在提供不同的密钥时重新初始化,在初始化新操作之前对旧操作执行清理。用通俗易懂的话来解释就是

用户登录/切换用户 的场景下可以使用在使用原生view时需要使原生view与activity生命周期绑定时使用在用了过后需要移除的非compose操作都可以使用

相关依赖

implementation "androidx.compose.ui:ui:$compose_version"

implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'

二、举例

这里用绑定生命周期举例

1.使用原生webview

代码如下(示例):

import android.webkit.WebView

import androidx.compose.foundation.layout.Arrangement

import androidx.compose.foundation.layout.Row

import androidx.compose.foundation.layout.fillMaxSize

import androidx.compose.runtime.Composable

import androidx.compose.ui.Alignment

import androidx.compose.ui.Modifier

import androidx.compose.ui.platform.LocalContext

import androidx.compose.ui.viewinterop.AndroidView

import com.zyf.electronicwoodfish.R

@Composable

fun DisposableEffectView(){

Row (

Modifier.fillMaxSize(),

horizontalArrangement = Arrangement.Center ,

verticalAlignment = Alignment.CenterVertically

) {

val context = LocalContext.current

val webView : WebView = WebView(context).apply {

id = R.id.webView

loadUrl("https://blog.csdn.net/shop_and_sleep?spm=1010.2135.3001.5343")

}

AndroidView(factory = { context ->

webView

},

modifier = Modifier.fillMaxSize()

}

}

运行效果

可以看到运行时是没有异常的,但是我们开发安卓的都知道使用webview要绑定activity的生命周期,不然就容易造成内存泄漏的风险;所以我们需要使用到本文所介绍的附带效应DisposableEffect来添加和移除其生命周期

2.DisposableEffect与LifecycleEventObserver

所以我们将上诉代码修改如下 代码如下(示例):

import android.webkit.WebView

import androidx.compose.foundation.layout.Arrangement

import androidx.compose.foundation.layout.Row

import androidx.compose.foundation.layout.fillMaxSize

import androidx.compose.runtime.Composable

import androidx.compose.ui.Alignment

import androidx.compose.ui.Modifier

import androidx.compose.ui.platform.LocalContext

import androidx.compose.ui.viewinterop.AndroidView

import com.zyf.electronicwoodfish.R

import android.util.Log

import androidx.lifecycle.Lifecycle

import androidx.lifecycle.LifecycleEventObserver

import androidx.compose.ui.platform.LocalLifecycleOwner

import androidx.compose.runtime.DisposableEffect

/**

* @author zengyifeng

* @date createDate:2023-03-21

* @brief description 附带效应 DisposableEffect

*/

@Composable

fun DisposableEffectView(){

Row (

Modifier.fillMaxSize(),

horizontalArrangement = Arrangement.Center ,

verticalAlignment = Alignment.CenterVertically

) {

val context = LocalContext.current

val webView : WebView = WebView(context).apply {

id = R.id.webView

}

AndroidView(factory = { context ->

webView

},

modifier = Modifier.fillMaxSize(),

update = { view ->

})

val lifecycle = LocalLifecycleOwner.current.lifecycle

DisposableEffect(key1 = lifecycle, key2 = webView) {

val lifecycleObserver = getWebViewLifecycleObserver(webView)

lifecycle.addObserver(lifecycleObserver)

onDispose {

lifecycle.removeObserver(lifecycleObserver)

}

}

}

}

fun getWebViewLifecycleObserver(webView: WebView): LifecycleEventObserver =

LifecycleEventObserver { _, event ->

when (event) {

Lifecycle.Event.ON_CREATE ->

{

Log.w("webView", "ON_CREATE ", )

webView.loadUrl("https://blog.csdn.net/shop_and_sleep?spm=1010.2135.3001.5343")

}

Lifecycle.Event.ON_START -> {

Log.w("webView", "ON_START ", )

}

Lifecycle.Event.ON_RESUME ->{

Log.w("webView", "ON_RESUME ", )

webView.onResume()}

Lifecycle.Event.ON_PAUSE ->

{

Log.w("webView", "ON_PAUSE ", )

webView.onPause()

}

Lifecycle.Event.ON_STOP -> {

Log.w("webView", "ON_STOP ", )

}

Lifecycle.Event.ON_DESTROY ->

{

Log.w("webView", "ON_DESTROY ", )

webView.destroy()

}

else -> throw IllegalStateException()

}

}

此时如果启动页面 可以看到日志打印 退出页面可以看到日志打印

运行正常!

3.代码分析

我们查看

LocalLifecycleOwner.current.lifecycle

的源码

可以看到其返回的是一个提供给程序的生命周期

而LifecycleEventObserver,我们查看他的源码 可以看到,此函数的作用是用于在生命周期发生改变是调用相应状态

我们再查看DisposableEffect的源码 其作用在于当key1,或key2发生改变时,系统会移除观察器并再次将其添加到正确的 lifecycle。因此通过这种方法我们使用webview与在xml中声明一个webview的效果并于activity绑定生命周期相同

总结

值得注意的是,因为附带效应是在compose外的一些操作,所以我们必须要有一个或多个key来指定附带效应的范围,如果没有key,则违反其设计规则,因此不带key的DisposableEffect被声明为弃用。

参考:DisposableEffect

推荐阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: