Android中捕獲運行時異常饵较,可以通過繼承UncaughtExceptionHandler來重寫uncaughtException方法。
可以捕獲ANR異常的開源庫目前比較好的是
ANR-WatchDog遭赂。
其他的開源庫例如:
BlockCanary循诉,SafeLooper
ANR-WatchDog是參考Android WatchDog機制(com.android.server.WatchDog.java)起個單獨線程向主線程發(fā)送一個變量+1操作,自我休眠自定義ANR的閾值嵌牺,休眠過后判斷變量是否+1完成打洼,如果未完成則告警。
但是無法保證能捕捉所有ANR逆粹,對閾值的設置直接影響捕獲概率。
后來項目中使用Bugly到監(jiān)控ANR異常炫惩,通過反編譯jar包僻弹,發(fā)現(xiàn)ANR異常捕獲是通過FileObserver實現(xiàn)的。
當ANR發(fā)生的時候他嚷,通過監(jiān)聽文件文件夾“data/anr/”的寫入情況,來判斷是否發(fā)生了ANR蹋绽,如果監(jiān)聽到data/anr/traces.txt文件寫入。說明有此時有ANR異常發(fā)生筋蓖。
通過ActivityManager.getProcessesInErrorState();獲取當前進程的所有異常信息List.遍歷此列表卸耘,從中找到ActivityManager.ProcessErrorStateInfo對象的condition == 2 的Error。過濾掉其他非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低權限應用不能監(jiān)聽變化“、data/anr/traces.txt”瓮下,只能在root之后才可以翰铡。
詳細實現(xiàn)源碼:CrashHandler