最近开发时应用出现崩溃,但是看不到当时的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");