0
点赞
收藏
分享

微信扫一扫

安装 AWS Load Balancer Controller 附加组件

程序员知识圈 03-16 08:00 阅读 4

runBlocking简介

runBlocking导致App应用出现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">

    <Button
        android: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" />

    <Button
        android: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" />

    <TextView
        android: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.activity

import 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.runBlocking


class TestANRByRunBlockingActivity : Activity() {
    private lateinit var tv_detail: TextView
    private var psersonBean: PsersonBean

    init {
        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 延时初始化,这里安全起见,判断是否 isInitialized
        if (::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){//切换到主线程更新UI
                showData()
            }
        }
        LogUtil.i("调用了 refreshByGlobalScopeLaunch 方法,没有阻塞当前线程")
    }

    fun detail() {
        LogUtil.i("执行了查看详情事件")
        psersonBean.moblie = "12345678901"
        showData()
    }
}

使用GlobalScope.launch解决ANR问题

总结

推荐

Kotlin:协程基础

举报

相关推荐

0 条评论