Kotlin:runBlocking导致App应用出现ANR问题实例

runBlocking简介

runBlocking 是常规函数;
runBlocking 方法会阻塞当前线程来等待;
runBlocking 的主线程会一直 阻塞 直到 runBlocking 内部的协程执行完毕。

runBlocking导致App应用出现ANR问题实例的效果

点击页面上的 刷新按钮 调用 refreshByrunBlocking方法,此方法里模拟了等待30秒耗时操作,当点击 刷新按钮 等待3秒左右,点击 详情按钮,页面出现ANR弹框如下图所示
在这里插入图片描述

页面布局activity_test_anr_by_runblocking.xml代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/btn_refresh"android:layout_width="match_parent"android:layout_height="50dp"android:layout_marginLeft="20dp"android:layout_marginTop="60dp"android:layout_marginRight="20dp"android:gravity="center"android:onClick="onClick"android:text="刷新"android:textColor="@color/black"android:textSize="20sp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/btn_detail"android:layout_width="0dp"android:layout_height="50dp"android:layout_marginTop="60dp"android:gravity="center"android:onClick="onClick"android:text="详情"android:textColor="@color/black"android:textSize="20sp"app:layout_constraintLeft_toLeftOf="@+id/btn_refresh"app:layout_constraintRight_toRightOf="@+id/btn_refresh"app:layout_constraintTop_toBottomOf="@+id/btn_refresh" /><TextViewandroid:id="@+id/tv_detail"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginTop="60dp"android:onClick="onClick"android:textColor="@color/black"android:textSize="16sp"app:layout_constraintLeft_toLeftOf="@+id/btn_detail"app:layout_constraintRight_toRightOf="@+id/btn_detail"app:layout_constraintTop_toBottomOf="@+id/btn_detail"tools:text="用户信息" /></androidx.constraintlayout.widget.ConstraintLayout>

实体类:PsersonBean.kt代码

data class PsersonBean(val name: String, var moblie: String? = null)//至少有一个构造函数

TestANRByRunBlockingActivity.kt代码

package example.demo.kotlin.activityimport android.app.Activity
import android.os.Bundle
import android.view.View
import android.widget.TextView
import example.demo.kotlin.R
import example.demo.kotlin.bean.PsersonBean
import example.demo.kotlin.utils.LogUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlockingclass TestANRByRunBlockingActivity : Activity() {private lateinit var tv_detail: TextViewprivate var psersonBean: PsersonBeaninit {psersonBean = PsersonBean("测试用户01")}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_test_anr_by_runblocking)initView()}override fun onStart() {super.onStart()showData()}fun initView() {tv_detail = findViewById(R.id.tv_detail)}fun showData() {//使用lateinit var 延时初始化,这里安全起见,判断是否 isInitializedif (::tv_detail.isInitialized) {tv_detail.setText("$psersonBean")//注意,因为PsersonBean是 data class 类型 不需要重新toString 函数}}fun onClick(view: View) {when (view.id) {R.id.btn_refresh -> refreshByrunBlocking2()R.id.btn_detail -> detail()}}/*** 出现了ANR问题*/fun refreshByrunBlocking() {runBlocking(context = Dispatchers.IO) {LogUtil.i("开始执行 刷新 耗时操作了")delay(30000)//假设30秒,可以假设真实网络请求出现超时了,方便演示出现ANR问题psersonBean = PsersonBean("测试用户02")LogUtil.i("刷新 耗时操作结束")}LogUtil.i("刷新 耗时操作 事件执行完毕")showData()}/*** runBlocking里即使使用 async 也会出现ANR问题*/fun refreshByrunBlocking2() {runBlocking(context = Dispatchers.IO) {LogUtil.i("开始执行 刷新 耗时操作了")val psersonBean = async {delay(30000)//假设30秒,可以假设真实网络请求出现超时了,方便演示出现ANR问题PsersonBean("测试用户02")}LogUtil.i("刷新 耗时操作结束")}LogUtil.i("刷新 耗时操作 事件执行完毕")showData()}/*** 使用GlobalScope.launch ,没有出现ANR问题*/fun refreshByGlobalScopeLaunch() {GlobalScope.launch(context = Dispatchers.IO) {LogUtil.i("开始执行 刷新 耗时操作了")delay(30000)//假设30秒,可以假设真实网络请求出现超时了,方便演示出现ANR问题psersonBean = PsersonBean("测试用户02")LogUtil.i("刷新 耗时操作结束")withContext(Dispatchers.Main){//切换到主线程更新UIshowData()}}LogUtil.i("调用了 refreshByGlobalScopeLaunch 方法,没有阻塞当前线程")}fun detail() {LogUtil.i("执行了查看详情事件")psersonBean.moblie = "12345678901"showData()}
}

使用GlobalScope.launch解决ANR问题

点击页面上的 刷新按钮 调用 refreshByGlobalScopeLaunch方法,此方法里模拟了等待30秒耗时操作,当点击 刷新按钮 等待3秒左右,点击 详情按钮,页面数据正常显示如下图所示
在这里插入图片描述

刷新耗时操作结束,主线程更新UI
在这里插入图片描述

总结

  1. runBlocking主线程会一直 阻塞 直到 runBlocking 内部的协程执行完毕,执行长时间耗时操作会导致App应用出现ANR问题。
  2. runBlocking里即使使用 async 也会导致App应用出现ANR问题。
  3. GlobalScope.launch可以解决耗时操作App应用出现ANR问题,注意需要配合withContext(Dispatchers.Main)进行更新UI操作

推荐

Kotlin:协程基础

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

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

相关文章

kubernetes-服务-ipvs-调度算法

kubernetes-服务-ipvs-调度算法 kubernetes-61、kubernetes中的网络通信插件1.1、calico1.2、flannel 2、service服务2.1、服务暴露/发现2.2、体验操作2.3、这个体验的流程图和解释 3、ipvs3.1、理解3.2、负载均衡的软件&#xff1a;LVS3.2.1、LVS的nat模式3.2.2、DR模式3.2.3、…

19113133262(微信同号)【征稿进行时|见刊、检索快速稳定】2024年区块链、物联网与复合材料与国际学术会议 (ICBITC 2024)

【征稿进行时|见刊、检索快速稳定】2024年区块链、物联网与复合材料与国际学术会议 (ICBITC 2024) 大会主题: (主题包括但不限于, 更多主题请咨询会务组苏老师) 区块链&#xff1a; 区块链技术和系统 分布式一致性算法和协议 块链性能 信息储存系统 区块链可扩展性 区块…

一场“猜成绩”大赛:ArrayList vs. LinkedList

今天我们将带来一场精彩绝伦的较量——ArrayList对阵LinkedList。 ArrayList它就像是一张大桌子&#xff0c;可以容纳各种各样的物品。 ArrayList是一个动态数组&#xff0c;具有随机访问的能力&#xff0c;这意味着我们可以在O(1)的时间复杂度内访问任意位置的元素。 它还具…

学点Java打小工_Day4_Homework

1 统计数字 1 int[] scores{0,0,1,2,3,5,4,5,2,8,7,6,9,5,4,8,3,1,0,2,4,8,7,9,5,2,1,2,3,9}; 求出上面数组中0-9分别出现的次数 &#xff08;双重for循环&#xff09; Testpublic void solveProblem1() {int[] scores {0,0,1,2,3,5,4,5,2,8,7,6,9,5,4,8,3,1,0,2,4,8,7,9,5,2,…

JMeter 并发测试和持续性压测详解

并发测试和持续性压测都是评估系统性能的常用方法&#xff0c;它们可以帮助开发人员发现并解决系统中的性能问题。本文来详细介绍下。 概念 并发测试&#xff1a; 旨在评估系统在同时处理多个用户请求时的性能。在这种 测试 中&#xff0c;系统会暴露于一定数量的用户负载下&…

MYSQL 索引 结构 以及常见优化

Mysql索引 索引概述 索引是帮助Mysql高效获取数据的排好序的数据结构 比如我们做查询的时候需要查询col289的数据 首先我们的数据在磁盘上的表不一定是挨着的&#xff0c;第一条数据插入后&#xff0c;可能其它程序在磁盘上写入了数据&#xff0c;然后再插入第二条&#xf…

【保姆级】GPT的Oops问题快速解决方案

GPT的"Oops"问题通常指的是GPT在处理请求时突然遇到错误或无法提供预期输出的情况。要快速解决这个问题&#xff0c;可以尝试以下分步策略&#xff1a; 确认问题范围&#xff1a; 首先&#xff0c;确认问题是偶发的还是持续存在的。如果是偶发的&#xff0c;可能是临…

Html提高——HTML5 新增的语义化标签

引入&#xff1a; 以前布局&#xff0c;我们基本用 div 来做。div 对于搜索引擎来说&#xff0c;是没有语义的。 但是在html5里增加了语义化标签&#xff0c;如 <header>&#xff1a;头部标签 <nav>&#xff1a;导航标签 <article>&#xff1a;内容标签 &…

phpcms头像上传漏洞引发的故事

目录 关键代码 第一次防御 第一次绕过 第二次防御 第二次绕过 第三次防御 第三次绕过 如何构造一个出错的压缩包 第四次防御 第四次绕过 本篇文章是参考某位大佬与开发人员对于文件包含漏洞的较量记录下的故事&#xff0c;因为要学习文件包含漏洞&#xff0c;就将大佬…

Dense Distinct Query for End-to-End Object Detection

摘要 对象检测中的一对一标签分配成功地消除了作为后处理的非极大值抑制&#xff08; NMS &#xff09;的需要&#xff0c;并使流水线端到端。然而&#xff0c;这引发了一个新的困境&#xff0c;因为广泛使用的稀疏查询无法保证高召回率&#xff0c;而密集查询不可避免地带来更…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:ListItemGroup)

该组件用来展示列表item分组&#xff0c;宽度默认充满List组件&#xff0c;必须配合List组件来使用。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。该组件的父组件只能是List。 使用说明 当List…

uni app 钓鱼小游戏

最近姑娘喜欢玩那个餐厅游戏里的钓鱼 &#xff0c;经常让看广告&#xff0c;然后就点点点... 自己写个吧。小鱼的图片自己搞。 有问题自己改&#xff0c;不要私信我 <template><view class"page_main"><view class"top_linear"><v…