Android Compose 《编程思想》解读

文章目录

官方文档

Compose 编程思想

声明性编程范式

  • widget的实现是,修改view的属性,继而影响 UI,刷新/重绘界面

在传统的 Android UI 开发中,界面和数据是分离的,你需要手动去"命令" UI 进行修改。这很容易导致状态不同步的 Bug。

痛点:随着界面越来越复杂,你要记住 "这个数据的变化,引起的每一处需要更新的 View,一旦漏写了一句,界面就会显示错误"

  • 声明性界面模型中,不能直接获取到某个ui组件,再修改它的属性。而是通过声明 不同 State (状态) 的 UI,在 修改 State 后,发生 可组合项的重组,并刷新界面。会智能重组,某些可组合项会跳过重组。原文:Compose 会智能地选择在任何给定时间需要重新绘制界面的哪些部分

核心公式:UI = f(State)

声明性 UI 的核心可以用一个数学公式表示:UI = f(State)

State (状态):应用的数据。

f (函数):你的 Compose UI 代码。

UI (界面):最终屏幕上显示的内容。

这意味着:

界面只是当前状态在某一时刻的视觉快照。

你不能直接去修改 UI(比如 tv.text = "新文字" 这种做法在 Compose 里是不存在的)。

你要做的仅仅是修改状态(State)。一旦状态改变,Compose 就会带着新的状态重新运行那个函数 f(即重组 Recomposition),从而画出新的 UI。


可组合项,重组是智能的

可能会频繁、并行、无序地 进行重组,也可能会智能跳过某些可组合项的重组。

不应在 可组合函数 展示 UI 元素的地方,利用重组的附带效应(Side Effect),执行文件读写、网络访问等操作。

附带效应:可组合项被框架,智能重组调用的时机、次数 及是否会调用都是不受人为控制的,那在重组过程中 频繁执行 io密集/cpu密集操作 都是不可取的

若一定要执行 这些耗时操作,也行的。可以在 LaunchedEffect(key) { } 这个协程作用域中执行。它会执行多少次呢?

LaunchedEffect 的执行次数完全取决于你传给它的 key(键值)。

它的核心运行规则是:

  • 第一次进入界面时(进入组合区),必定执行 1 次。
  • 在随后的 UI 重组中,只有当 key 发生变化时,才会先取消上一次正在执行的任务,然后重新执行 1 次。
  • 当它所在的 UI 节点从屏幕上消失时(离开组合区),它内部的协程会被自动取消。

根据你传入的 key 的不同,通常有以下两种典型场景:
场景 1 :只执行 1 次(常用于初始化)

如果你希望某个操作在整个 UI 生命周期内只执行一次,无论界面重组多少次都不再执行,你可以传入一个常量(通常是 Unit 或 true)。

kotlin 复制代码
@Composable
fun MyScreen() {
    // 传入 Unit 作为 key
    LaunchedEffect(Unit) {
        // 这里的代码只会在 MyScreen 第一次显示时执行 1 次
        // 即使 MyScreen 因为其他状态变化重组了 100 次,这里也不会再执行
        fetchDataFromNetwork() 
    }
    // UI 代码...
}

场景 2 :根据变量变化执行 N 次(常用于参数变化时的重新加载)

如果你希望当某个特定的状态或参数改变时,重新触发操作,你就把那个变量作为 key 传进去。

kotlin 复制代码
@Composable
fun UserProfile(userId: String) {
    // 将 userId 作为 key
    LaunchedEffect(userId) {
        // 1. 第一次进入界面时,执行 1 次获取用户信息
        // 2. 如果重组时,userId 的值变了(比如从 "001" 变成了 "002"),
        //    Compose 会自动取消之前未完成的 "001" 请求,并重新执行 1 次获取 "002" 的请求。
        // 3. 如果重组时,userId 没变,这里绝不会执行。
        val user = api.getUser(userId) 
    }
}
相关推荐
千里马学框架1 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077001 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼1 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui