Android launchWhenXXX 和 repeatOnLifecycle

文章目录

  • Android launchWhenXXX 和 repeatOnLifecycle
    • lifecycleScope和viewModelScope
    • launchWhenXXX
    • repeatOnLifecycle
    • flowWithLifecycle
    • 总结

Android launchWhenXXX 和 repeatOnLifecycle

lifecycleScope和viewModelScope

LiveData优点:

  • 避免内存泄露风险:当 Activity/Fragment 进入 DESTROYED 时,会自动删除 Observer 。
  • 节省资源:当 Activity/Fragment 进入活跃状态时才开始接受数据,避免 UI 处于后台时的无效计算。

Flow缺点:

Flow 基于协程实现,具有丰富的操作符,通过这些操作符可以实现线程切换、处理流式数据,相比 LiveData 功能更加强大。 但唯有一点不足,无法像 LiveData 那样感知生命周期。

lifecycleScope:

lifecycle-runtime-ktx 库提供了 lifecycleOwner.lifecycleScope 扩展,可以在当前 Activity 或 Fragment 销毁时结束此协程,防止泄露。

Flow 也是运行在协程中的,lifecycleScope 可以帮助 Flow 解决内存泄露的问题。

添加依赖库:

implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.0"
class MyFragment: Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch {
            val params = TextViewCompat.getTextMetricsParams(textView)
            val precomputedText = withContext(Dispatchers.Default) {
                PrecomputedTextCompat.create(longTextContent, params)
            }
            TextViewCompat.setPrecomputedText(textView, precomputedText)
        }
    }
}
class MyViewModel: ViewModel() {
    init {
        viewModelScope.launch {
            // Coroutine that will be canceled when the ViewModel is cleared.
        }
    }
}

launchWhenXXX

由于 lifecycleScope.launch 会立即启动协程,一直运行到协程销毁,不能监听生命周期。因此lifecycle-runtime-ktx 又为我们提供了 LaunchWhenStarted 和 LaunchWhenResumed 。

优点:

launchWhenXXX 会在 XXX 状态前一直等待,又在离开 XXX 状态后挂起协程,lifecycleScope+launchWhenXX的组合使用让 Flow 拥有了生命周期感知能力。

  • 避免泄露:当 lifecycleOwner 进入 DESTROYED 时, lifecycleScope 结束协程
  • 节省资源:当 lifecycleOwner 进入 STARTED/RESUMED 时 launchWhenX 恢复执行,否则挂起。

缺点:

对于 launchWhenXXX 来说, 当 lifecycleOwner 离开 XXX 状态时,协程只是挂起协程而非销毁,如果用这个协程来订阅 Flow,就意味着虽然 Flow 的收集暂停了,但是上游的处理仍在继续,资源浪费的问题解决地不够彻底。

class MyFragment: Fragment {
    init {
        lifecycleScope.launchWhenStarted {
            try {
                // Call some suspend functions.
            } finally {
                // This line might execute after Lifecycle is DESTROYED.
                if (lifecycle.state >= STARTED) {
                    // Here, since we've checked, it is safe to run any
                    // Fragment transactions.
                }
            }
        }
    }
}

repeatOnLifecycle

lifecycle-runtime-ktx 自 2.4.0-alpha01 起,提供了一个新的协程构造器 lifecyle.repeatOnLifecycle, 它在离开 X 状态时销毁协程,再进入 X 状态时再启动协程。从其命名上也可以直观地认识这一点,即围绕某生命周期的进出反复启动新协程

class MyFragment : Fragment() {

    val viewModel: MyViewModel by viewModel()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // Create a new coroutine in the lifecycleScope
        viewLifecycleOwner.lifecycleScope.launch {
            // repeatOnLifecycle launches the block in a new coroutine every time the
            // lifecycle is in the STARTED state (or above) and cancels it when it's STOPPED.
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                // Trigger the flow and start listening for values.
                // This happens when lifecycle is STARTED and stops
                // collecting when the lifecycle is STOPPED
                viewModel.someDataFlow.collect {
                    // Process item
                }
            }
        }
    }
}

flowWithLifecycle

当我们只有一个 Flow 需要收集时,可以使用 flowWithLifecycle 这样一个 Flow 操作符的形式来简化代码。

viewLifecycleOwner.lifecycleScope.launch {
    exampleProvider.exampleFlow()
        .flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.STARTED)
        .collect {
            // Process the value.
        }
}

flowWithLifecycle源码:

本质仍然是对 repeatOnLifecycle 的封装。

public fun <T> Flow<T>.flowWithLifecycle(
    lifecycle: Lifecycle,
    minActiveState: Lifecycle.State = Lifecycle.State.STARTED
): Flow<T> = callbackFlow {
    lifecycle.repeatOnLifecycle(minActiveState) {
        this@flowWithLifecycle.collect {
            send(it)
        }
    }
    close()
}

总结

在这里插入图片描述

  • lifecycleScope.launch:可以在当前 Activity 或 Fragment 销毁时结束此协程,防止泄露。
  • launchWhenXXX:可以像 LiveData 那样感知生命周期,但是会挂起协程而非销毁,仍然存储资源浪费问题。
  • repeatOnLifecycle:可以感知生命周期变化,进入指定状态后会销毁协程。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小程序中如何设置多门店/多人/多商品价格库存等复杂场景设置

有些商家希望打造小程序平台&#xff0c;在这个平台上有多个商家入驻&#xff0c;他们分别售卖自己的商品。而有些商家有多个连锁店&#xff0c;连锁店的商品都是一样的&#xff0c;但不同的连锁店有不同的库存和价格。这些业务在采云小程序中是怎么支持的呢&#xff1f;下面具…

2023数字科技生态展,移远通信解锁新成就

11月10日&#xff0c;以“数字科技&#xff0c;焕新启航”为主题的中国电信2023数字科技生态大会暨2023数字科技生态展在广州盛大启幕。作为物联网行业的龙头标杆&#xff0c;同时更与中国电信连续多年维持稳定友好的合作关系&#xff0c;移远通信受邀参加本次展会。 在本次展会…

CSRF和XSS漏洞结合实战案例

文章目录 CSRF和XSS漏洞结合实战案例实验原理实验步骤信息收集构造CSRF和XSS代码xss注入 CSRF和XSS漏洞结合实战案例 实验环境为csm 实验原理 攻击者利用JavaScript可以构造请求的功能在留言面板构造一个存储型xss注入&#xff0c;里面的内容为js请求。请求新添加用户&…

行业寒冬下,给软件测试工程师or功能测试的一些建议

​行业寒冬下&#xff0c;给软件测试工程师的一些建议 【文章末尾给大家留下了大量的福利】 国内的互联网行业发展较快&#xff0c;所以造成了技术研发类员工工作强度比较大&#xff0c;同时技术的快速更新又需要员工不断的学习新的技术。因此淘汰率也比较高&#xff0c;超过…

Oracle 11g安装教程

下载并安装Oracle数据库 首先&#xff0c;需要到Oracle官方网站下载Oracle数据库&#xff0c;在这里我们将下载Oracle 11g第2版的Microsoft Windows(x64)版本。由于安装文件过大&#xff0c;可以分两个文件下载或一次性下载&#xff0c;如下图所示 下载完成后&#xff0c;将下…

你知道调试一个 Web 的 Android 应用有多麻烦吗 AndroidStudio uniapp Capacitor

你知道调试一个 Web 的 Android 应用有多麻烦吗 AndroidStudio uniapp Capacitor 用的 uniapp 写的页面&#xff0c;全是坑&#xff0c;各种坑&#xff0c;生命周期不触发等。但由于已经做完大部分内容了&#xff0c;也不好换了。 我用的是 capacitor h5 > Android 的方式…

paypal第三方支付==沙盒,js

学习地址 https://developer.paypal.com/dashboard/ 创建沙盒已经得到商户和用户账号 得到clientid和client secret 得到买家账户和密码 查看沙盒内的所有账号&#xff0c;我这有一个卖家&#xff0c;两个买家账号 DEMO代码 GitHub - paypaldev/PayPal-Standard-Checkout-Tu…

基于51单片机的出租车计价器设计【程序+proteus仿真+参考论文+AD原理图】

一、项目功能简介 整个设计系统由STC89C52单片机DS1302时钟模块LCD1602显示模块DS18B20温度模块24C02存储模块L298电机驱动模块里按键模块蜂鸣器模块组成。 具体功能&#xff1a; 1、LCD1602显示日期时间、温度&#xff0c;计费开始显示起步价、里程价、总路程和总费用。 2、…

【无标题】通用工作站设计方案:ORI-D3R600服务器-多路PCIe3.0的双CPU通用工作站

ORI-D3R600服务器-多路PCIe3.0的双CPU通用工作站 一、机箱功能和技术指标&#xff1a; 系统 系统型号 ORI-SR630 主板支持 EEB(12*13)/CEB(12*10.5)/ATX(12*9.6)/Micro ATX 前置硬盘 最大支持8个3.5寸(兼容25寸)SATA硬盘 2*2.5(后置) 电源类型 CRPS元余电源&#xff0…

月入8.3k,新传文科生转行5G网络优化工程师,张雪峰:这专业,报考就打晕…

新闻传播专业的就业是什么样子的&#xff1f; 考研名师张雪峰说&#xff1a;如果我是家长的话&#xff0c;孩子非要报新闻学&#xff0c;我一定会干一个事&#xff0c;就是把他打晕&#xff0c;然后给他报个别的。 新闻传播专业似乎已经成了一个备受争议的话题&#xff0c;就业…

优秀智慧园区案例 - 珠海华发智慧园区,万字长文解析先进智慧园区建设方案经验

一、项目背景 珠海华发产业园运营管理有限公司&#xff08;简称“产业园公司”&#xff09;是2016年起连续五年跻身“中国企业500强”、国务院国企改革“双百企业”的珠海华发集团旗下的实体产业发展载体运营平台&#xff0c;依托“四园一基地”&#xff1a;中以国际产业园、信…

Spring中Bean的作用域

2023.11.8 默认情况下&#xff0c;Spring的IoC容器创建的Bean对象是单例的。下面测试一下&#xff1a; 创建一个bean类&#xff1a; package spring6.beans;public class SpringBean { }配置一下xml文件&#xff1a; <?xml version"1.0" encoding"UTF-8&…

软件测试每一个阶段需要掌握的基础知识

以下为大家介绍在每一个阶段需要掌握的基础知识以及对应的实践文档 1 测试方法与理论 名称相关知识点1.1 软件开发生命周期SCRUM/XP、持续集成/持续交付/DevOps1.2 测试流程体系传统测试流程、测试左移、测试右移1.3 测试技术体系分层测试体系、单元测试、UI 测试、接口测试、…

jetsonTX2 nx配置tensorRT加速yolov5推理

环境说明 Ubuntu 18conda环境python3.9cuda10.2&#xff0c;硬件平台是Jetson tx2 nx 前提你已经能运行YOLOV5代码后&#xff0c;再配置tensorRT进行加速。 目前只试了图片检测和C打开USB摄像头进行视频检测&#xff0c;希望是使用python配合D435i深度相机来实现检测&#xff…

前端---CSS的样式汇总

文章目录 CSS的样式元素的属性设置字体设置文字的粗细设置文字的颜色文本对齐文本修饰文本缩进行高设置背景背景的颜色背景的图片图片的属性平铺位置大小 圆角矩形 元素的显示模式行内元素和块级元素的转化弹性布局水平方向排列方式&#xff1a;justify-content垂直方向排序方式…

中断处理机制解析

要处理中断&#xff0c;需要有一个中断处理函数。定义如下&#xff1a; irqreturn_t (*irq_handler_t)(int irq, void * dev_id);/*** enum irqreturn* IRQ_NONE interrupt was not from this device or was not handled* IRQ_HANDLED interrupt was handled by this de…

【PG】PostgreSQL 目录结构

目录 1 软件安装目录 2 数据文件目录 base/&#xff1a;存储每个数据库的基本数据文件 global/&#xff1a;包含了全局性质的系统表空间文件 pg_tblspc/&#xff1a;包含了表空间的符号链接 pg_twophase/&#xff1a;包含了两阶段提交中使用的文件 pg_stat_tmp/&#xff…

短剧软件APP开发方案

一、项目概述 短剧软件APP是一款集创作、拍摄、观看短剧于一体的移动应用。用户可以随时随地创作自己的短剧&#xff0c;也可以观看其他用户创作的短剧。本方案将详细介绍短剧软件APP的开发流程。 二、需求分析 在开发短剧软件APP之前&#xff0c;需要进行详细的需求分析。通…

【外汇天眼】连接金融创新未来:参与2023 Wiki Finance Expo悉尼站,共谋发展新趋势!

你准备好了么&#xff1f; 2023年Wiki Finance Expo将于11月16日举行&#xff01; 地点&#xff1a;澳大利亚悉尼马丁广场1号富丽敦酒店&#xff08;The Fullerton Hotel Sydney, No.1 Martin Place, Sydney NSW 2000, Australia&#xff09; 该金融博览会将会成为澳大利亚今…

【开源】基于Vue和SpringBoot的智能停车场管理系统

项目编号&#xff1a; S 005 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S005&#xff0c;文末获取源码。} 项目编号&#xff1a;S005&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容A. 车主端功能B. 停车工作人员功能C. 系…