這裡是分析的vlc的異常處理。
1,設定目前線程的異常處理函數
Thread.setDefaultUncaughtExceptionHandler(new VLCCrashHandler());
2,在 VLCCrashHandler 中處理異常
public class VLCCrashHandler implements UncaughtExceptionHandler {
private static final String TAG = "VLC/VlcCrashHandler";
private UncaughtExceptionHandler defaultUEH;
public VLCCrashHandler() {
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
// Inject some info about android version and the device, since google can't provide them in the developer console
StackTraceElement[] trace = ex.getStackTrace();
StackTraceElement[] trace2 = new StackTraceElement[trace.length+3];
System.arraycopy(trace, 0, trace2, 0, trace.length);
trace2[trace.length+0] = new StackTraceElement("Android", "MODEL", android.os.Build.MODEL, -1);
trace2[trace.length+1] = new StackTraceElement("Android", "VERSION", android.os.Build.VERSION.RELEASE, -1);
trace2[trace.length+2] = new StackTraceElement("Android", "FINGERPRINT", android.os.Build.FINGERPRINT, -1);
ex.setStackTrace(trace2);
ex.printStackTrace(printWriter);
String stacktrace = result.toString();
printWriter.close();
Log.e(TAG, stacktrace);
// Save the log on SD card if available
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String sdcardPath = Environment.getExternalStorageDirectory().getPath();
writeLog(stacktrace, sdcardPath + "/vlc_crash");//記錄日志
writeLogcat(sdcardPath + "/vlc_logcat");//記錄日志
}
defaultUEH.uncaughtException(thread, ex);
}
private void writeLog(String log, String name) {
CharSequence timestamp = DateFormat.format("yyyyMMdd_kkmmss", System.currentTimeMillis());
String filename = name + "_" + timestamp + ".log";
FileOutputStream stream;
try {
stream = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}
OutputStreamWriter output = new OutputStreamWriter(stream);
BufferedWriter bw = new BufferedWriter(output);
try {
bw.write(log);
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
bw.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void writeLogcat(String name) {
CharSequence timestamp = DateFormat.format("yyyyMMdd_kkmmss", System.currentTimeMillis());
String filename = name + "_" + timestamp + ".log";
try {
Logcat.writeLogcat(filename);
} catch (IOException e) {
Log.e(TAG, "Cannot write logcat to disk");
}
}
}
一個記錄的是崩潰的堆棧資訊,一個記錄的是崩潰時的logcat,結合使用,還是比較友善的。
下面是用到的Logcat類:
public class Logcat {
public final static String TAG = "VLC/Util/Logcat";
/**
* Writes the current app logcat to a file.
*
* @param filename The filename to save it as
* @throws IOException
*/
public static void writeLogcat(String filename) throws IOException {
String[] args = { "logcat", "-v", "time", "-d" };
Process process = Runtime.getRuntime().exec(args);
InputStreamReader input = new InputStreamReader(process.getInputStream());
FileOutputStream fileStream;
try {
fileStream = new FileOutputStream(filename);
} catch( FileNotFoundException e) {
return;
}
OutputStreamWriter output = new OutputStreamWriter(fileStream);
BufferedReader br = new BufferedReader(input);
BufferedWriter bw = new BufferedWriter(output);
try {
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
}
}catch(Exception e) {}
finally {
bw.close();
output.close();
br.close();
input.close();
}
}
/**
* Get the last 500 lines of the application logcat.
*
* @return the log string.
* @throws IOException
*/
public static String getLogcat() throws IOException {
String[] args = { "logcat", "-v", "time", "-d", "-t", "500" };
Process process = Runtime.getRuntime().exec(args);
InputStreamReader input = new InputStreamReader(
process.getInputStream());
BufferedReader br = new BufferedReader(input);
StringBuilder log = new StringBuilder();
String line;
while ((line = br.readLine()) != null)
log.append(line + "\n");
br.close();
input.close();
return log.toString();
}
}