Android&iOS崩溃情况总结

    掌握了崩溃的情况,不至于盲目测试,也能给开发带来有利信息,便于开发排查定位问题。因此,作为测试工程师,很有必要掌握该项技能。

1. Android崩溃

Android&iOS崩溃情况总结_第1张图片

1.1 ANR(Application Not Response)

发生场景:应用发生ANR

崩溃症状:系统弹出窗口询问用户选择“Force Close”或者“Wait”。

“Force Close”将杀掉发生ANR的应用进程。“Wait”将会等待系统择机恢复此应用进程。

发生原因:

(1)应用主线程卡住,对其他请求响应超时。

(2)死锁。

(3)系统反应迟钝。

(4)CPU负载过重。

发生anr时,系统会在/data/anr目录下生成一个traces.txt文件,方便程序员查看系统产生anr异常的堆栈和线程信息。

1.2 java崩溃

发生场景:应用进程崩溃。

崩溃症状:系统弹窗提示程序意外停止。

发生原因:空指针异常或者其他未捕捉的异常。

1.2.1主要异常

  • NullPPointerException

出现场景:

(1)父窗口+子窗口同时出现的,父窗口因为某种原因消掉了,子窗口还在,操作子窗口找不到父窗口的pid,就会出现该问题。

(2)加载过程中进行刷新或者其他点击操作,可能某种资源还没有初始化成功,就会出现该问题。

(3)异常情况下,比如断网了,比如需要连接的设备没有连接,则相应资源拿不到,此时点击某些按钮,也会出现该问题。

(4)其他等等情况下,使用一个对象的时候还没有对其进行初始化。

  • OutOfMemoryError

出现场景:

  1. 加载多个大图时,由于Android系统对运行的程序有一定的内存限制,一般是16MB或24MB,不做处理直接加载就会报OOM。

  2. 设备内存小,程序处理视频/图片,数量多,时间长容易出现。

  3. 发生内存泄漏

内存泄漏原因:

1)数据库的cursor没有关闭

Cursor是Android查询数据后得到的一个管理数据集合的类,正常情况下,如果查询得到的数据量较小时不会有内存问题,而且虚拟机能够保证Cusor最终会被释放掉。

    然而如果Cursor的数据量特别大,特别是如果里面有Blob信息时,应该保证Cursor占用的内存被及时的释放掉,而不是等待GC来处理。并且 Android明显是倾向于编程者手动的将Cursor close掉,因为可以在源代码中发现,如果等到垃圾回收器来回收时,会给用户以错误提示(blob指图像中一块连通区域)

2)调用registerReceiver()后未调用unregisterReceiver()

广播接收者(BroadcastReceiver)经常在应用中用到,可以在多线程任务完成后发送广播通知UI更新,也可以接收系统广播实现一些功能。当Activity中使用了registerReceiver()方法注册了BroadcastReceiver,一定要在Activity的生命周期内调用unregisterReceiver()方法取消注册。就是说这两个方法要成对出现。

3)未关闭InputStream/OutputStream

操作完输入输出流,都要关闭。

4)使用Bitmap后未调用recycle()

出现OOM问题的绝大多数人,都是因为Bitmap的问题,由于Bitmap占用内存较大,所以使用后需要及时销毁。

5)Context泄漏

context最主要的功能是加载和访问资源。在android中有两种context,一种是 application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。把activity context传递给view,意味着view拥有一个指向activity的引用,进而引用activity占有的资源:view hierachy, resource等。因此,如果context发生内存泄露的话,就会泄露很多内存。即gc没有办法回收activity的内存。

6)static关键字等

  static是Java中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。用它来修饰成员变量,使得变量的生命周期大大延长,但是用它来引用一些资源耗费过多的实例,稍有不慎,就会发生内存泄漏。

1.3 native崩溃

发生场景:Native层崩溃

崩溃症状:

如果发生崩溃的native层和UI有关联(比如Browser),我们可以在UI上发现这个崩溃。

如果发生崩溃的native层是在后台并且和UI没有直接联系,那么对于用户来说是不可见的。

发生原因:

Name

Reason

Comment

1.空指针

试图对空指针进行操作时(如读取空指针指向的内存),处理器就会产生一个异常

目前app最多的一种引起crash的原因,但是也很容易被发现和修复。

2.野指针

指向的是一个无效的地址,该地址如果是不可读不可写的,那么会马上Crash;如果访问的地址为可写,而且通过野指针修改了该处的内存,那么很有可能会等一段时间(其它的代码使用了该处的内存后)才发生Crash。

3.数组越界

访问无效的地址。如果该地址不可读写,则会马上Crash;如果修改了该处的内存,造成内存破坏,那么有可能会等一段时间才在别处发生Crash。

破坏内存的bug,很难查找。

4.整数除以零

整数除以零默认的处理方式是终止进程

开发环境下很难出现,但庞大的用户量和复杂的用户输入,就很容易导致被除数为0的情况出现。

5.格式化输出参数错误

与野指针类似,但是只会读取无效地址的内存,而不会造成内存破坏。其结果是要么打印出错乱的数据,要么访问了无读写权限的内存而立即宕机。

2. iOS崩溃

iOS的崩溃可以分为两类:信号可捕捉崩溃 和 信号不可捕捉崩溃。

2.1 信号可捕捉的崩溃

  • 数组越界:取数据时候索引越界,APP发生崩溃。给数组添加nil会崩溃。

  • 多线程问题:多个线程进行数据的存取,可能会崩溃。例如有一个线程在置空数据的同时另一个线程在读取数据。

  • 野指针问题:指针指向一个已删除的对象访问内存区域时,会出现野指针崩溃。野指针问题是导致 App 崩溃的最常见,也是最难定位的一种情况。

  • NSNotification线程问题:NSNotification 有很多种线程实现方式,同步、异步、聚合,所以不恰当的线程发送和接收会出现崩溃问题。

  • KVO问题:‘If your app targets iOS 9.0 and later or OS X v10.11 and later, you don't need to unregister an observer in its deallocation method。’ 在9.0之前需要手动remove 观察者,如果没有移除会出现观察者崩溃情况。

2.2 信号不可捕捉的崩溃

  • 后台任务超时

  • App超过系统限制的内存大小被杀死

  • 主线程卡顿被杀死

 

你可能感兴趣的:(客户端测试,android,ios,java)