Compose 生命周期和副作用

文章目录

  • Compose 生命周期和副作用
    • 生命周期
    • 副作用API
      • DisposableEffect
      • SIdeEffect
      • LaunchedEffect
      • rememberCoroutineScope
      • rememberUpdatedState
      • snapshotFlow
      • produceState
      • derivedStateOf

Compose 生命周期和副作用

生命周期

在这里插入图片描述

  • OnActive:添加到视图树。即Composable被首次执行,在视图树上创建对应的节点。
  • OnUpdate:重组。Composable跟随重组不断执行,更新视图树上的对应节点。
  • OnDispose:从视图树移除。Composable不再被执行,对应节点从视图树上移除。

Composable在角色上更加类似于传统视图的View,所以没有Activity或者Fragment那样的前后台切换的概念,生命周期相对简单。

副作用API

副作用(Side-Effects):指在 Composable 函数中执行的可能会产生外部影响或依赖于外部资源的操作。如,访问数据库、网络请求、文件操作、弹出Toast、保存本地文件、访问远程或本地数据等。

重组可能会造成Composable频繁反复执行,副作用不应该跟随重组反复执行的。

为了处理副作用,Android Compose 提供了一系列副作用API。

DisposableEffect

DisposableEffect 可以感知 Composable 的 onActive 和 onDispose,允许通过副作用完成一些预处理和收尾处理。

@Composable
fun LifecyclePage() {var counter by remember { mutableStateOf(0) }Column(horizontalAlignment = Alignment.CenterHorizontally) {Text("Counter: ${counter}")Row {Button(onClick = { counter-- }) {Text("-")}Button(onClick = { counter++ }) {Text("+")}}}DisposableEffect(Unit) {Log.e("TAG", "预处理")counter = 100onDispose {Log.e("TAG", "销毁处理")}}
}

SIdeEffect

SIdeEffect 会在重组成功时执行,不适合处理那些耗时或者异步的副作用逻辑。

@Composable
fun LifecyclePage() {var counter by remember { mutableStateOf(0) }Column(horizontalAlignment = Alignment.CenterHorizontally) {Text("Counter: ${counter}")Row {Button(onClick = { counter-- }) {Text("-")}Button(onClick = { counter++ }) {Text("+")}}}SideEffect {Log.e("TAG", "hello 重组了")}
}

LaunchedEffect

用于异步操作。

当 Composable 进入 OnActive 时,LaunchedEffect 会启动协程执行 block 中的内容,可以在其中启动子协程或者调用挂起函数。当Composable 进入 OnDispose 时,协程会自动取消,因此 LaunchedEffect 不需要实现OnDispose{…}。

@Composable
fun LifecyclePage() {var counter by remember { mutableStateOf(0) }Column(horizontalAlignment = Alignment.CenterHorizontally) {Text("Counter: ${counter}")Row {Button(onClick = { counter-- }) {Text("-")}Button(onClick = { counter++ }) {Text("+")}}}LaunchedEffect(Unit) {async {delay(2000L)Log.e("TAG", "异步处理")counter = 2000}}
}

rememberCoroutineScope

协程操作。

LaunchedEffect 虽然可以启动协程,但是只能在 Composable 中调用。如果想在非 Composable 中使用协程,如点击事件中,可以使用 rememberCoroutineScope。

rememberCoroutineScope 会返回一个 CoroutineScope,并在 OnDispose 时自动取消。

@Composable
fun LifecyclePage() {var counter by remember { mutableStateOf(0) }val scope = rememberCoroutineScope()Column(horizontalAlignment = Alignment.CenterHorizontally) {Text("Counter: ${counter}")      Button(onClick = {scope.launch {Log.e("TAG", "协程操作")counter = 3000}}) {Text("协程操作")}} 
}

rememberUpdatedState

监听状态最新状态。

rememberUpdatedState的实现就明白其中原理了,其实就是remember和mutableStateOf的组合使用

@Composable
fun LifecyclePage() {var counter by remember { mutableStateOf(0) }val updateCounter by rememberUpdatedState(newValue = counter)Column(horizontalAlignment = Alignment.CenterHorizontally) {Text("Counter: ${counter}")Row {Button(onClick = { counter-- }) {Text("-")}Button(onClick = { counter++ }) {Text("+")}} Text("监听最新状态:${updateCounter}")}
}

snapshotFlow

snapshotFlow 可以把 Compose 的 State 状态对象转成协程的 Flow。

@Composable
fun LifecyclePage() {var time by remember { mutableStateOf("${System.currentTimeMillis()}") }val flow = snapshotFlow { time }Column(horizontalAlignment = Alignment.CenterHorizontally) {Button(onClick = {time = "${System.currentTimeMillis()}"}) {Text("更新")}}LaunchedEffect(Unit) {flow.collect {Log.e("TAG", "snapshotFlow: ${it}")}}
}

produceState

SideEffect 常用来将Compose的State暴露给外部使用,而produceState则相反,可以将一个外部的数据源转成State。外部数据源可以是一个LiveData或者RxJava这样的可观察数据,也可以是任意普通的数据类型。

data class Person(val name: String, val age: Int, val time: Long)@Composable
fun MyProduceState() {var name by remember { mutableStateOf("小明") }var age by remember { mutableStateOf(18) }val personState by produceState(initialValue = Person(name, age, System.currentTimeMillis()),name,age) {value = Person(name, age, System.currentTimeMillis())}Column(horizontalAlignment = Alignment.CenterHorizontally) {Button(onClick = { name = "小红" }) {Text("修改name")}Button(onClick = { age = 19 }) {Text("修改age")}Text("produceState: ${personState}")}
}

说明:修改 name 或 age 都会触发 produceState。

derivedStateOf

derivedStateOf用来将一个或多个State转成另一个State。derivedStateOf{…}的block中可以依赖其他State创建并返回一个DerivedState,当block中依赖的State发生变化时,会更新此DerivedState,依赖此DerivedState的所有Composable会因其变化而重组。

@Composable
fun MyDerivedStateOf() {var postList by remember { mutableStateOf(listOf("a", "b", "c", "d", "e")) }var keyword by remember { mutableStateOf("") }val result by remember {derivedStateOf { postList.filter { it.contains(keyword, false) } }}Text("过滤:${result}")Button(onClick = { postList = listOf("1", "2", "3", "4", "5") }) {Text("修改List")}OutlinedTextField(value = keyword, onValueChange = { keyword = it }, label = { Text("请输入") })
}

说明:当 postList 或 keyword 方式变化时,derivedStateOf 都会重新计算,result 也就更新了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/8325.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年教育创新与人文艺术国际学术会议(ICEIHA 2024)

2024年教育创新与人文艺术国际学术会议(ICEIHA 2024) 2024 International Conference on Educational Innovation and Humanities and Arts 一、【会议简介】 2024年教育创新与人文艺术国际学术会议,将探讨教育创新与人文艺术的结合。 本次会议将汇集全球的专家学者…

python基础---面向对象相关知识

面向对象 可以把数据以及功能打包为一个整体 类: 名称属性(数据)方法 class Person:def __init__(self, name, age):self.age ageself.name namedef print_info:print(self.name, self.age)定义 #经典类 class Dog1:pass# 新式类 class Dog2(object):pass在python3里面这…

漏洞伴随App无时不在,该怎么办?

漏洞攻击、加密被破坏以及数据泄露是App面临的三大重要安全风险,无论开发者如何防范,攻击者往往会找到新的方法,并依靠最新的工具来破坏App安全性。 统计数据表明,大约82%的漏洞是在App程序代码中发现的。如果尽快发现…

实测幻方新出的超强AI大模型,中文能力对比GPT4.0不落下风

目前从网上的消息来看,DeepSeek中文综合能力(AlignBench)开源模型中最强,与GPT-4-Turbo,文心4.0等闭源模型在评测中处于同一梯队。 话不多说,我们开测! 1.首先我们来让他直接来一段逻辑推理【并…

Linux学习笔记:信号

信号 在Linux中什么是信号信号的产生方式硬件产生的信号软件产生的信号异常产生的信号 进程对信号的处理信号的保存信号方法更改函数signal信号处理的更改恢复默认信号忽略 信号的管理信号集 sigset_t对信号集的操作 信号的捕捉过程 在Linux中什么是信号 在 Linux 系统中&…

MATLAB添加自编写.m文件或.mat数据并永久全局调用方法

菜单栏选择设置路径,然后“添加并包含子文件夹”,在弹出窗口中找到目标文件夹即可。此方案可以永久地将文件夹加入MATLAB路径。 添加包含自编写.m文件的文件夹: 即可实现永久全局调用。

【Elasticsearch运维系列】Elasticsearch7.12.1启动指定版本JDK:你学废了吗?

一、背景 一套生ES集群,版本为7.12.1,近期频繁告警,频繁出现索引分片异常,索引状态异常,导致应用无法正常写入ES,另外,也经常出现节点掉问题。通过分析相关ES日志,显示和当前JAVA G…

vue 开发环境的搭建

一、整个流程: 安装nodejs >> 安装vue >> 安装vue-cli >> 初始化 webpack(生成代码) >> 安装依赖 >> 运行vue程序 二、详细安装流程: 1.安装nodejs 下载:https://nodejs.org/dist/v12.18.3/node-v12.18.3-x…

电商核心内容揭秘50:个性化广告与投放策略

相关系列文章 电商技术揭秘相关系列文章合集(1) 电商技术揭秘相关系列文章合集(2) 电商技术揭秘相关系列文章合集(3) 电商技术揭秘四十一:电商平台的营销系统浅析 电商技术揭秘四十二&#…

基于卷积神经网络的高光谱分类 CNN(上)

基于卷积神经网络的高光谱分类 CNN 混合光谱HybridSN传统的2-D CNN混合光谱3-D CNN 操作步骤前言(准备)获取数据以及引入基本的库函数导入相关的包 创建模型模型网络结构代码测试 混合光谱HybridSN 传统的2-D CNN 传统的2-D CNN方法在处理HSI时往往只考…

密码口令初步

一,弱口令(ctfhub) 1.打开环境,发送到bp的instruder板块,一般id默认为admin,也可以用bp找出来,这里就是 2.先clear ,再把password等号后面添加进来(add)&am…

通过 Java 操作 redis -- list 列表基本命令

目录 使用命令 lpush,lrange,rpush 使用命令 lpop 和 rpop 使用命令 blpop,brpop 使用命令 llen 关于 redis list 列表类型的相关命令推荐看Redis - list 列表 要想通过 Java 操作 redis,首先要连接上 redis 服务器&#xff…

记一次java进程频繁挂掉问题排查修复

前言 最近业务部门有个java服务进程会突然无缘无故的挂掉,然后这个服务会产生一堆类似hs_err_pid19287.log这样的日志。业务部门负责人就把hs_err_pidxxx的日志发给我,让我帮忙看下问题。本文就来回顾一下,我是如何帮业务部门进行问题排查 …

一篇文章fpmarkets澳福盘点摇摆交易优缺点

通过之前的文章,我们各位投资者想必都已经明白了什么是摇摆交易,以及摇摆交易的特点和使用方法,今天fpmarkets澳福就一篇文章盘点摇摆交易优缺点: 摇摆交易策略优势: 更有利可图 与趋势策略不同,投资者可能会在摇摆交易…

Beego 使用教程 5:页面视图

beego 是一个用于Go编程语言的开源、高性能的 web 框架 beego 被用于在Go语言中企业应用程序的快速开发,包括RESTful API、web应用程序和后端服务。它的灵感来源于Tornado, Sinatra 和 Flask beego 官网:http://beego.gocn.vip/ 上面的 bee…

Could not resolve placeholder ‘xx.xxx.host’ in value “xxx“问题解决

Could not resolve placeholder ‘xx.xxx.host’ in value "xxx"问题解决 众多原因其中之一 springboot 项目,idea 配置apollo 时,运行指定了配置文件 uat 所以使用本地配置文件启动 时,一直去找uat 配置文件,结果自…

rust使用serde_json转换Value为rust中的数据类型

为了方便转换未知json数据,我们可以使用serde提供的value类型来进行转换,将json字符串转化为Value值,然后可以快速使用get方法来获取值: let json_str r#"{"name": "John","age": 30,"c…

Satellite Communications Symposium(WCSP2022)

1.Power Allocation for NOMA-Assisted Integrated Satellite-Aerial-Terrestrial Networks with Practical Constraints(具有实际约束的 NOMA 辅助天地一体化网络的功率分配) 摘要:天地一体化网络和非正交多址接入被认为是下一代网络的关键组成部分,为…

Git === Git概述 Git安装

第1章 Git概述 Git是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目。 Git易于学习,占地面积小,性能极快。 它具有廉价的本地库,方便的暂存区域和多个工作流分支等特性。其性能优于Subversion…

Webshell绕过技巧分析之-base64/HEX/Reverse/Html/Inflate/Rot13

在网络安全运营,护网HVV,重保等活动的过程中,webshell是一个无法绕过的话题。通常出现的webshell都不是以明文的形式出现,而是针对webshell关键的内容进行混淆,编码来绕过网络安全产品(IDS,WAF&…