最近开发时应用出现崩溃,但是看不到当时的crash信息,没办法快速找到问题所在。后来在书中找到获取应用crash信息的方法,以此记录。
crash发生时,系统会kill掉正在执行的程序,出现闪退或者提示用户程序已停止运行。开发人员也无法直接得知程序为何crash。Android提供了处理未捕获异常的方法。可以通过UncaughtExceptionHandler来监视应用的crash信息,给程序设置一个UncaughtExceptionHandler,当crash发生时,就会调用UncaughtExceptionHandler的uncaughtException方法,在uncaughtException方法里可以获取到异常信息,可以选择把异常信息存储。
import android.content.Context;
import android.os.Environment;
import android.os.Process;
import android.util.Log;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by Rewufu on 2016/2/17.
*/
public class CrachHandler implements Thread.UncaughtExceptionHandler {
private static CrachHandler crachHandler = new CrachHandler();
private Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
private Context mContext;
private static final String PATH = Environment.getExternalStorageDirectory().getPath()+"/UncaughtException/";
private static final String FILE_NAME = "crash";
private static final String FILE_NAME_SUFFIX = ".trace";
public static CrachHandler getInstance() {
return crachHandler;
}
public void init(Context context) {
uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
mContext = context;
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
try {
dumpExceptionToSDcard(ex);
} catch (IOException e) {
e.printStackTrace();
}
if(uncaughtExceptionHandler != null){
uncaughtExceptionHandler.uncaughtException(thread, ex);
}else {
Process.killProcess(Process.myPid());
}
}
private void dumpExceptionToSDcard(Throwable ex) throws IOException{
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
Log.w("CrachHandler", "sdcard unmounted,skip dump exception");
return;
}
File dir = new File(PATH);
if(!dir.exists()){
dir.mkdir();
}
long current = System.currentTimeMillis();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(current));
File file = new File(PATH + FILE_NAME + time + FILE_NAME_SUFFIX);
PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter(file)));
printWriter.print(time);
printWriter.println();
ex.printStackTrace(printWriter);
printWriter.close();
}
}
上面就是代码实现,首先实现一个UncaughtExceptionHandler对象,在它的uncaughtException方法获取异常信息并存储,调用Thread的setDefaultUncaughtExceptionHandler将它设置为线程默认的异常处理器。
可以选择在Application初始化时为线程设置CrashHandler。
import android.app.Application;
/**
* Created by Rewufu on 2016/2/17.
*/
public class Myapplication extends Application {
@Override
public void onCreate() {
super.onCreate();
CrachHandler crachHandler = CrachHandler.getInstance();
crachHandler.init(getApplicationContext());
}
}
手动模拟发生crash,抛出一个RuntimeException测试一下,crash就会保存下来。
throw new RuntimeException("自己抛出RuntimeException");