FileObserver捕获ANR异常

作者: Calllanna | 来源:发表于2018-04-24 01:00 被阅读150次

    Android中捕获运行时异常,可以通过继承UncaughtExceptionHandler来重写uncaughtException方法。
    可以捕获ANR异常的开源库目前比较好的是
    ANR-WatchDog
    其他的开源库例如:
    BlockCanary,SafeLooper
    ANR-WatchDog是参考Android WatchDog机制(com.android.server.WatchDog.java)起个单独线程向主线程发送一个变量+1操作,自我休眠自定义ANR的阈值,休眠过后判断变量是否+1完成,如果未完成则告警。
    但是无法保证能捕捉所有ANR,对阈值的设置直接影响捕获概率。
    后来项目中使用Bugly到监控ANR异常,通过反编译jar包,发现ANR异常捕获是通过FileObserver实现的。
    当ANR发生的时候,通过监听文件文件夹“data/anr/”的写入情况,来判断是否发生了ANR,如果监听到data/anr/traces.txt文件写入。说明有此时有ANR异常发生。

    FileObserver

    通过ActivityManager.getProcessesInErrorState();获取当前进程的所有异常信息List.遍历此列表,从中找到ActivityManager.ProcessErrorStateInfo对象的condition == 2 的Error。过滤掉其他非ANR异常。

    过滤掉其他非ANR异常

    然后过滤掉非本应用下的异常。


    过滤掉非本应用下的异常

    ProcessErrorStateInfo源码:

    /**
     * Information you can retrieve about any processes that are in an error condition.
     */
    public static class ProcessErrorStateInfo implements Parcelable {
        /**
         * Condition codes
         */
        public static final int NO_ERROR = 0;
        public static final int CRASHED = 1;
        public static final int NOT_RESPONDING = 2;
    
        /**
         * The condition that the process is in.
         */
        public int condition;
    
        /**
         * The process name in which the crash or error occurred.
         */
        public String processName;
    
        /**
         * The pid of this process; 0 if none
         */
        public int pid;
    
        /**
         * The kernel user-ID that has been assigned to this process;
         * currently this is not a unique ID (multiple applications can have
         * the same uid).
         */
        public int uid;
    
        /**
         * The activity name associated with the error, if known.  May be null.
         */
        public String tag;
    
        /**
         * A short message describing the error condition.
         */
        public String shortMsg;
    
        /**
         * A long message describing the error condition.
         */
        public String longMsg;
    
        /**
         * The stack trace where the error originated.  May be null.
         */
        public String stackTrace;
    
        /**
         * to be deprecated: This value will always be null.
         */
        public byte[] crashData = null;
    
        public ProcessErrorStateInfo() {
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(condition);
            dest.writeString(processName);
            dest.writeInt(pid);
            dest.writeInt(uid);
            dest.writeString(tag);
            dest.writeString(shortMsg);
            dest.writeString(longMsg);
            dest.writeString(stackTrace);
        }
    
        public void readFromParcel(Parcel source) {
            condition = source.readInt();
            processName = source.readString();
            pid = source.readInt();
            uid = source.readInt();
            tag = source.readString();
            shortMsg = source.readString();
            longMsg = source.readString();
            stackTrace = source.readString();
        }
    
        public static final Creator<ProcessErrorStateInfo> CREATOR =
                new Creator<ProcessErrorStateInfo>() {
            public ProcessErrorStateInfo createFromParcel(Parcel source) {
                return new ProcessErrorStateInfo(source);
            }
            public ProcessErrorStateInfo[] newArray(int size) {
                return new ProcessErrorStateInfo[size];
            }
        };
    
        private ProcessErrorStateInfo(Parcel source) {
            readFromParcel(source);
        }
    }
    

    FileObserver捕获ANR异常,缺点是Android5.0低权限应用不能监听变化“、data/anr/traces.txt”,只能在root之后才可以。
    详细实现源码:CrashHandler

    相关文章

      网友评论

      • 天才木木:额,“缺点是Android5.0低权限应用不能监听变化,只能在root之后才可以。”

        这缺点也太致命了吧,等于市面上90%以上的手机都不能用,该方案已经没有实用意义了吧。
      • DreamArea:你demo里面的写法没啥效果
        DreamArea:@Calllanna 我用的是6.0以上的手机。。用来存ANR信息的文件是空的
        Calllanna:亲!文中有提示:FileObserver捕获ANR异常,缺点是Android5.0低权限应用不能监听变化“、data/anr/traces.txt”,只能在root之后才可以。此外还得添加文件读写权限。这种方式只是提供一种方式,不能完美适用所有手机,所有情况。:smile:

      本文标题:FileObserver捕获ANR异常

      本文链接:https://www.haomeiwen.com/subject/tiqdlftx.html