Android Jetpack Compose基础之State状态

Android Jetpack Compose基础之State状态

Stateless和Stateful

什么是Stateless,让我看下面代码

kotlin 复制代码
@Composable
fun Greeting(name:String){
    Text(text = "Hello $name")
}

Greeting方法中未持有或访问了某些状态,它唯一变化的来自参数,所以他就是一个无状态的纯函数;

Stateless它有什么特点呢

1、当无状态函数的参数没有发生改变时,不会参与调用方的重组,将重组范围局限在无状态函数外部;

Stateless它是如何实现避免无效重组的呢

Compose编译器在@Composable注解的函数体内进行了字节码插桩技术,在Text调用之前对参数进行了判断,如果参数没有变化,则跳过对Text的调用,从而避免无效重组。

什么是Stateful,让我看下面代码

kotlin 复制代码
@Composable
fun GreetingStateful(){
    var name by remember{
        mutableStateOf("World")
    }
    Text(text = "Stateful")
    Text(text = "Hello $name", modifier = Modifier.clickable {
        name ="World ${Random.nextInt(100)}"
    })
}

在代码内部我们创建了状态name来记录最新的值,GreetingStateful中依赖对name的读写,因此它时一个Stateful。

Compose中的State

在Compose中使用State描述一个状态,当Composable对state的值进行读取的同时会与state建立订阅关系,当值发生改变时,Composable会自动重组刷新ui

kotlin 复制代码
@Stable
interface State<out T> {
    val value: T//不可修改
}

State子类之MutableState

如果需要对Sate的value进行修改,则需要使用MutableState来表示可修改状态

kotlin 复制代码
@Stable
interface MutableState<T> : State<T> {
    override var value: T //var可修改类型
    operator fun component1(): T
    operator fun component2(): (T) -> Unit
}

创建方式1:直接赋值

kotlin 复制代码
    val name = mutableStateOf("default")

创建方式2:解构

kotlin 复制代码
	val(name2,setName2) = mutableStateOf("default")

创建方式3:属性代理

kotlin 复制代码
	var name3 by mutableStateOf("default")

状态的恢复与持久化

remember

1、未避免因重组导致状态的丢失,我们常见的是使用remember实现缓存状态

kotlin 复制代码
    var name4 by remember {
        mutableStateOf("default")
    }

rememberSaveable

2、虽然remember能跨越重组,但是不能跨越Acitivity和进程,这时我们需要使用rememberSaveable

kotlin 复制代码
    var name5 by rememberSaveable {
        mutableStateOf("default")
    }

rememberSaveable 中的数据会在onSaveInstanceState中以Bundle形式进行保存,在进程或者activity重建时根据key恢复到对应的Composable中,这个key是Compsable在编译期被确定的唯一表述,其源码如下

kotlin 复制代码
@Composable
fun <T : Any> rememberSaveable(
    vararg inputs: Any?,
    saver: Saver<T, out Any> = autoSaver(),
    key: String? = null,
    init: () -> T
): T {
    val compositeKey = currentCompositeKeyHash
    // key is the one provided by the user or the one generated by the compose runtime
    val finalKey = if (!key.isNullOrEmpty()) {
        key
    } else {
        compositeKey.toString(MaxSupportedRadix)
    }
    @Suppress("UNCHECKED_CAST")
    (saver as Saver<T, Any>)

    val registry = LocalSaveableStateRegistry.current

    val holder = remember {
        // value is restored using the registry or created via [init] lambda
        val restored = registry?.consumeRestored(finalKey)?.let {
            saver.restore(it)
        }
        val finalValue = restored ?: init()
        SaveableHolder(saver, registry, finalKey, finalValue, inputs)
    }

    val value = holder.getValueIfInputsDidntChange(inputs) ?: init()
    SideEffect {
        holder.update(saver, registry, finalKey, value, inputs)
    }

    return value
}

其它方式:

复制代码
如ViewModel等等方式,不再赘述

------note end------

原理有待探索~~

相关推荐
TeleostNaCl5 分钟前
如何安装 Google 通用的驱动以便使用 ADB 和 Fastboot 调试(Bootloader)设备
android·经验分享·adb·android studio·android-studio·android runtime
fatiaozhang95271 小时前
中国移动浪潮云电脑CD1000-系统全分区备份包-可瑞芯微工具刷机-可救砖
android·网络·电脑·电视盒子·刷机固件·机顶盒刷机
2501_915918412 小时前
iOS 开发全流程实战 基于 uni-app 的 iOS 应用开发、打包、测试与上架流程详解
android·ios·小程序·https·uni-app·iphone·webview
lichong9512 小时前
【混合开发】vue+Android、iPhone、鸿蒙、win、macOS、Linux之dist打包发布在Android工程asserts里
android·vue.js·iphone
Android出海2 小时前
Android 15重磅升级:16KB内存页机制详解与适配指南
android·人工智能·新媒体运营·产品运营·内容运营
一只修仙的猿2 小时前
毕业三年后,我离职了
android·面试
编程乐学3 小时前
安卓非原创--基于Android Studio 实现的新闻App
android·ide·android studio·移动端开发·安卓大作业·新闻app
雅雅姐4 小时前
Android14 init.rc中on boot阶段操作4
android
fatiaozhang95274 小时前
中国移动中兴云电脑W132D-RK3528-2+32G-刷机固件包(非原机制作)
android·xml·电脑·电视盒子·刷机固件·机顶盒刷机
Android出海6 小时前
Google Play账户与App突遭封禁?紧急应对与快速重构上架策略
android·网络·重构·新媒体运营·产品运营·内容运营