我的编程空间,编程开发者的网络收藏夹
学习永远不晚

AndroidCrash与ANR详细介绍

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

AndroidCrash与ANR详细介绍

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内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

AndroidCrash与ANR详细介绍

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

AndroidCrash与ANR详细介绍

对于Android开发的人来说,想必对Crash和ANR这俩都不陌生,并且都对其恨之入骨,因为它俩的产生会大大影响用户体验。所以,在此,结合本人的开发经验,对其做个总结
2022-11-13

详细介绍Coroutine

首先,讨论了并行执行的“执行主体”,它是一个抽象的概念,在操作系统层次上,有多种概念与之对应,如操作系统负责的进程、进程中的线程和进程中的协程,也称为轻量线程。许多语言在语法水平上不直接支持合作程序,而通过库支持的合作程序也没有完成,只提供合作程序的创建、销毁、切换等功能。若在这种协程中,如网络通信、本地文件读写等同步IO操作将阻塞其他并发执行协程,因此不能真正实现协程本身所期望的目标。
详细介绍Coroutine
2024-04-23

DockerCompose详细介绍

DockerCompose是一个用于定义和运行多个Docker容器的工具。它可以让用户轻松地定义和管理多个容器的配置,并且可以通过简单的命令来启动、停止和重启这些容器。在本文中,我们将详细介绍DockerCompose的使用和功能
2023-05-16

android AsyncTask详细介绍

AsyncTask和Handler对比 1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可
2022-06-06

Android Bitmap详细介绍

代码如下: package com.testbitmapscale; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream;
2022-06-06

详细介绍Linux IO

1.IO概述 分析一下写操作: char *buf = malloc(MAX_BUF_SIZE); strncpy(buf, src, , MAX_BUF_SIZE); fwrite(buf, MAX_BUF_SIZE, 1, fp); f
2022-06-03

javascript this详细介绍

this的值是在运行时确定的  JS中的this究竟代表什么,这是在程序运行时根据上下文环境确定,可以分为以下几种情况。  1. 全局作用域中的this  在全局作用域中,this指向window对象。  ?  1  2  3  4  5 
2023-06-03

linux cgroups详细介绍

Cgroups是什么?cgroups(Control Groups) 是 linux 内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。简单说,
2022-06-04

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录