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) 
    }
}
相关推荐
进击的cc3 小时前
Activity 生命周期是如何被调度的?(从源码到实战全链路拆解)
android
sp42a3 小时前
将 NativeScript 项目升级到 Android API 35 级别
android·nativescript
tangweiguo030519873 小时前
iOS vs Android 开发对照手册
android·ios
用户69371750013843 小时前
跟你唠唠!A2A协议来了,谁能拿下下一代手机系统的主动权?
android·前端·人工智能
用户69371750013843 小时前
微信悄悄搞大事!原生智能助手秘密研发,2026年改变亿人使用习惯
android·后端·微信小程序
轩情吖3 小时前
MySQL之表的增删查改
android·开发语言·c++·后端·mysql·adb·
robotx3 小时前
安卓15开机动画结束流程简单分析
android
XiaoLeisj4 小时前
Android 模块化与组件化工程实战:从子模块库化、Gradle 配置统一到 ARouter 解耦跨模块页面通信与 Fragment 解耦集成
android·gradle·模块化·arouter
JMchen1234 小时前
高级渲染技术:OpenGL ES在自定义View中的应用
android·性能优化·3d渲染·opengl es·自定义view·glsurfaceview·shader编程