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异常发生。

a1a27619b0ef

FileObserver

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

a1a27619b0ef

过滤掉其他非ANR异常

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

a1a27619b0ef

过滤掉非本应用下的异常

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 CREATOR =

new Creator() {

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

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐