返回顶部
首页 > 资讯 > 移动开发 >AndroidCrash与ANR详细介绍
  • 348
分享到

AndroidCrash与ANR详细介绍

AndroidCrashAndroidANR 2022-11-13 19:11:05 348人浏览 安东尼
摘要

目录Crash空指针角标越界集合元素删除操作异步操作后对界面元素的处理Intent传递数据过大在子线程中操作UIANRCrash Crash是指程序闪退,导致APP不能正常使用。Cr

Crash

Crash是指程序闪退,导致APP不能正常使用。Crash产生的原因有很多,下面只是列举了一些常见原因。

空指针

空指针应该是项目中最容易产生crash的情况了,举个例子,我们获取某个对象的属性或方法时,这个对象为Null时,如何没有判空,则会出现空指针异常NullPointException,所以这就要求使用对象的时候进行非空判断,在这点,我觉得Kotlin就做得很好,利用空安全可以很好地避免NullPointException。

角标越界

在使用数组或者集合的时候会出现IndexOutOfBoundsException,在根据index进行取值时,最好先判断该索引值是否存在或者使用try-catch捕捉异常。

集合元素删除操作

比如我们需要将集合中满足条件的元素删除掉

        list.forEach {
            if (it == 3) {
                list.removeAt(it)
            }
        }

这样做会引起Crash,会报ConcurrentModificationException,针对这个问题,我们可以从后面开始遍历

        for (index in list.size - 1 downTo 0) {
            if (list[index] == 3) {
                list.removeAt(index)
            }
        }

也可以使用迭代器进行遍历删除元素

        val iterator = list.iterator()
        while (iterator.hasNext()) {
            val a = iterator.next()
            if (a == 3) {
                iterator.remove()
            }
        }

当多个线程同时操作某个数组时,不要进行数组的增删改查等操作,这样同样也会引起相关的Crash或数据查询不准确等问题。

异步操作后对界面元素的处理

在fragment中使用Context前最好先加上判断isAdded判断,特别是异步操作后使用Context,很有可能出现报错(Fragment not attached to a context)而闪退,所有的异步回调后若要操作View,都要判断view是否为空,否则会出现界面销毁后View为空,空指针闪退问题。

Intent传递数据过大

Intent传512K以下的数据可以正常传递,高于512K则会出错,因为考虑到Intent还要包括要启动的Activity等信息,所以实际可以传的数据应该略小于512K。

        val data = ByteArray(1024 * 1024)
        val intent = Intent(this, ExpActivity::class.java)
        intent.putExtra("test", data)
        startActivity(intent)

这段代码会导致Crash

 Caused by: Android.os.TransactionTooLargeException: data parcel size 1049012 bytes

因为我们在Intent中携带的数据要从APP进程传输到AMS进程,再由AMS进程传输到目标Activity所在进程,普通的由 ZyGote 孵化而来的用户进程,所映射的Binder内存大小是不到1M,但是,在使用Intent传递数据时,1M并不是安全上限,因为Binder可能正在处理其它的传输工作。总而言之,startActivity携带的数据会经过Binder内核再传递到目标Activity中去,因为binder映射内存的限制,所以startActivity也会这个限制。

在子线程中操作UI

子线程中是不能操作UI的,如果在子线程中某个时机想要改变UI,可以使用Handler或者kotlin协程切换,需要注意的是,在子线程中也不可以操作Dialog和Toast。但是,这有个很有意思的点,举个例子,如果你在onCreate中开启一个子线程改变UI,会发现程序运行正常,没报错,像这样

class ExpActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_exp)
        val name = findViewById<TextView>(R.id.name)
        Thread { name.text = "name" }.start()
    }
}

但是,你延迟一秒后再操作UI,又会闪退报错

class ExpActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_exp)
        val name = findViewById<TextView>(R.id.name)
        Thread {
            Thread.sleep(1000)
            name.text = "name"
        }.start()
    }
}

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

这到底是为什么呢?这个的关键是ViewRootImpl类,它会去检查当前线程是不是主线程,如果不是就会抛出异常。像上面的情况,在onCreate中未延时直接操作UI不闪退,是因为此时ViewRootImpl还没有被初始化,这个时候程序没有去检测当前线程是不是主线程,所以没有抛异常。严格地讲,在ViewRootImpl构造的时候赋值的,赋值的就是当前的Thread对象,也就是说,你ViewRootImpl在哪个线程创建的,你后续的UI更新就需要在哪个线程执行,跟是不是UI线程毫无关系。

ANR

ANR是指程序未响应,在Android系统中,AMS和WMS会检测App的响应时间,如果App在特定时间无法响应屏幕触摸或键盘输入事件,或者特定事件没有处理完毕,就会出现ANR。

不同Context规定的上限时间不同:

  • 主线程对输入事件5秒内没有处理完毕。
  • 主线程在执行BroadcastReceiver的onReceive()函数时10秒内没有处理完毕。
  • 主线程在Service的各个生命周期函数时20秒内没有处理完毕。

避免ANR就要尽量避免在主线程中做耗时操作,耗时操作尽量放在子线程中。

我们可以通过/data/anr/traces.txt文件来分析ANR的产生,通过adb命令可以导出该文件,不过traces文件记录的东西可能比较多,分析的时候需要针对性地搜索出相关记录,该文件会记录进程ID,包名,造成ANR的原因和产生ANR的具体行数。

到此这篇关于Android Crash与ANR详细介绍的文章就介绍到这了,更多相关Android Crash与ANR内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: AndroidCrash与ANR详细介绍

本文链接: https://lsjlt.com/news/170662.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • AndroidCrash与ANR详细介绍
    目录Crash空指针角标越界集合元素删除操作异步操作后对界面元素的处理Intent传递数据过大在子线程中操作UIANRCrash Crash是指程序闪退,导致APP不能正常使用。Cr...
    99+
    2022-11-13
    Android Crash Android ANR
  • token与JWT详细介绍
    token介绍 Token 的中文意思是"令牌"。主要用来身份验证。比传统的身份验证方法,Token 有扩展性强,安全性高的特点,非常适合用在 Web 应用或者移动应用上。 它是服务端生成的字符串,作为客户端进行请求的一个标识。 token...
    99+
    2023-08-31
    java
  • springMVC详细介绍
    目录springMVC简介SpringMVC框架的优点第一个SpringMVC程序第一步:创建maven-web项目第二步:在pom.xml中添加依赖和插件第三步注册中央调度器第四步...
    99+
    2024-04-02
  • OAuth2 详细介绍!
    目录 一、文章介绍 二、OAth2 2.1 简介 2.2 OAuth2  授权总体流程 2.3 四种授权模式 1.授权码模式 2.简化模式 3.密码模式 4. 客户端模式 2.4 OAuth2 标准接口 2.5 GitHub 授权登录 1...
    99+
    2023-09-15
    github java
  • DockerCompose详细介绍
    目录一、Docker Compose的安装二、Docker Compose的基本使用三、Docker Compose的高级功能四、总结一、Docker Compose的安装 Dock...
    99+
    2023-05-16
    Docker Compose详解 Docker Compose
  • JSON基础介绍与详细用法
    一、什么是JSON 1、JSON指的是JavaScript对象表示法(JavaScript Object Notation)。2、JSON是轻量级的文本数据交换格式,比XML更小、更...
    99+
    2024-04-02
  • PythonCountingBloomFilter原理与实现详细介绍
    目录前言原理一、BF 为什么不支持删除二、什么是 Counting Bloom Filter三、Counter 大小的选择简单的实现总结前言 标准的 Bloom Filter 是一种...
    99+
    2024-04-02
  • SpringMVC配置与使用详细介绍
    目录一、SpringMVC的使用1、MVC模式2、具体的坐标如下3、配置DispatcheServlet4、编写springmvc.xml的配置文件二、SpringMVC原理1、Sp...
    99+
    2024-04-02
  • JDK与Dubbo中的SPI详细介绍
    目录1、SPI简介2、JDK中的SPI3、Dubbo中的SPI4、Dubbo中扩展点使用方式5、DubboSPI中的Adaptive功能1、SPI简介 SPI 全称为 (Servic...
    99+
    2024-04-02
  • JavaScript可视化与Echarts详细介绍
    目录一、可视化介绍二、可视化库介绍三、EchartsEcharts引入和使用了解基础配置一、可视化介绍 可视化:将数据用图表展示出来,让数据更加直观、让数据特点更加突出应用场景:营销...
    99+
    2024-04-02
  • ReactState与生命周期详细介绍
    目录一、State1.1 类组件中的State1.2 函数组件中的State二、React生命周期2.1 挂载2.2 更新2.3 卸载2.4 函数式组件useEffect三、总结一、...
    99+
    2024-04-02
  • 详细介绍Linux IO
    1.IO概述 分析一下写操作: char *buf = malloc(MAX_BUF_SIZE); strncpy(buf, src, , MAX_BUF_SIZE); fwrite(buf, MAX_BUF_SIZ...
    99+
    2022-06-03
    Linux IO
  • linux cgroups详细介绍
    Cgroups是什么? cgroups(Control Groups) 是 linux 内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供...
    99+
    2022-06-04
    linux cgroups
  • Android Bitmap详细介绍
    代码如下: package com.testbitmapscale; import java.io.File; import java.io.FileInputStream;...
    99+
    2022-06-06
    bitmap Android
  • android AsyncTask详细介绍
    AsyncTask和Handler对比 1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncT...
    99+
    2022-06-06
    asynctask Android
  • Java maven详细介绍
    目录maven什么是maven仓库的种类仓库的配置本地仓库配置私服配置中央仓库配置maven标准目录结构常用命令maven项目的生命周期pom.xml依赖适用域总结maven 什么是...
    99+
    2024-04-02
  • Flink的详细介绍
    这篇文章主要介绍“Flink的详细介绍”,在日常操作中,相信很多人在Flink的详细介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Flink的详细介绍”的疑惑有所帮助!接...
    99+
    2024-04-02
  • rabbitMQ的详细介绍
    1.概述 RabbitMQ是一个消息中间件:它接受并转发消息。你可以把它当做一个快递站点,当你要发送一个包裹时,你把你的包裹放到快递站,快递员最终会把你的快递送到收件人那里,按照这种逻辑RabbitMQ是一个快递站,一个快递员帮你传递快件。...
    99+
    2023-09-05
    rabbitmq npm linux java 分布式
  • javascript this详细介绍
    this的值是在运行时确定的  JS中的this究竟代表什么,这是在程序运行时根据上下文环境确定,可以分为以下几种情况。  1. 全局作用域中的this  在全局作用域中,this指向window对象。    1  2  3  4  5  ...
    99+
    2023-06-03
  • 【JAVA IO 详细介绍】
    JAVA IO 详细介绍 目录一、什么是IO?1.1 IO的介绍1.2 流的介绍1.2.1 流的特征1.2.2 数据流的特征1.2.3 输入流的特征1.2.4 输出流的特征 二、...
    99+
    2023-10-26
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作