Android面试笔记——ANR

1 什么是ANR

Application Not Responding,即应用无响应。

2 ANR类型

  1. InputDispatching Timeout:5秒内无法响应屏幕触摸事件或盘输入事件
  2. BroadcastQueue Timeout:在执行前台广播( BroadcastReceiver)的 onReceive()函数时10秒没有处理完成,后台为60秒。
  3. Service Timeout:前台服务20秒内,后台服务在200秒内没有执行完毕。
  4. ContentProvider Timeout: ContentProvider的 publish在10秒内没进行完

3 造成ANR的主要原因

应用程序的响应性是由ActivityManager和WindowManager系统服务监视的

3.1 线程中存在耗时的操作

Android主线程中的操作:

  1. Activity的所有生命周期都是执行在主线程的.
  2. Service默认是执行在主线程的
  3. BroadcastReceiver的onReceive回调是执行在主线程的.
  4. 没有使用子线程的looper的Handler的handleMessage,post(Runnable)是执行在主线程的
  5. AsyncTask的回调中除了doInBackground,其他都是执行在主线程
  6. View的post(Runnable)是执行在主线程的.

3.2 CPU满负荷

CPU占用100%, 满负荷了。一般来说是方法中有频繁的文件读写或是数据库读写操作放在主线程来做了。

3.3 内存原因

如果由于内存泄露, App可使用内存所剩无几, 我们点击按钮启动一个大图片作为背景的activity, 就可能会产生ANR。

4 如何解决ANR

4.1 主线程阻塞

  1. 避免死锁
  2. 开辟单独的子线程来处理耗时阻塞事务
  3. 尽量避免在主线程query provider、不要滥用SharePreferences

4.2 CPU满负荷, I/O阻塞的

I/O阻塞一般来说就是文件读写或数据库操作执行在主线程了,通过开辟子线程的方式异步执行。

4.3 内存原因

  1. 排查内存泄露
  2. 增大VM内存, 使用largeHeap属性,AndroidManifest.xml文件中,<application>中设置android:largerHeap="true"

4.4 各大组件ANR

  1. 各大组件的生命周期中应避免耗时操作
  2. 注意BroadCastReceiver的onReceive()、后台Service和contentProvider也不要执行太长时间的任务

5 使用子线程的方式有哪些

  1. Thread

    这个也是Java实现多线程的方式。 有两种实现方法, 继承Thread 或 实现Runnable接口。

  2. AsyncTask

  3. HandlerThread

    Android中结合Handler和Thread的一种方式.。 默认情况下Handler的handleMessage是执行在主线程的, 但是如果我给这个Handler传入了子线程的looper, handleMessage就会执行在这个子线程中的. HandlerThread正是这样的一个结合体:

    // 启动一个名为new_thread的子线程
    HandlerThread thread = new HandlerThread("new_thread");
    thread.start();
    
    // 取new_thread赋值给ServiceHandler
    private ServiceHandler mServiceHandler;
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
    
    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
          super(looper);
        }
        
        @Override
        public void handleMessage(Message msg) {
          // 此时handleMessage是运行在new_thread这个子线程中了.
        }
    }
    
  4. IntentService

    Service是运行在主线程的, 然而IntentService是运行在子线程的.
    实际上IntentService就是实现了一个HandlerThread + ServiceHandler的模式.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 最近在准备android面试,整理了下相关的面试题,分为如下三个部分:android部分、Java部分、算法面试题...
    JasmineBen阅读 7,184评论 10 137
  • 一、Activity (1)Activity的生命周期 onCreate() 表示Activity正在被创建做初始...
    kjy_112233阅读 748评论 0 1
  • 概述 什么是ANR?ANR全名为Application Not Reaponding,也就是"应用无响应",当操作...
    小庄bb阅读 366评论 0 0
  • Animation Q:Android中有哪几种类型的动画? 技术点:动画类型参考回答: 常见三类动画View动画...
    厘米姑娘阅读 46,137评论 19 198
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,115评论 0 4