注意只能捕获的异常是throwable类型的,首先我们要建立一个异常捕获的类:
public class CrashHandler implements Thread.UncaughtExceptionHandler {
public static final String TAG = "CrashHandler";
private Thread.UncaughtExceptionHandler mDefaultHandler;
private static CrashHandler INSTANCE = new CrashHandler();
private Context mContext;
//文件路径
private static final String PATH = Environment.getExternalStorageDirectory().getPath() +File.separator+ "crash";
private static final String FILE_NAME = "crash";
private static final String FILE_NAME_SUFEIX = ".txt";
private CrashHandler() {
}
public static CrashHandler getInstance() {
return INSTANCE;
}
public void init(Context context) {
mContext = context;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
if (mDefaultHandler != null) {
Thread.setDefaultUncaughtExceptionHandler(this);
}
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (mDefaultHandler != null) {
handleException(ex);
mDefaultHandler.uncaughtException(thread, ex);
}
}
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
if (ex instanceof NullPointerException) {
try {
//将文件写入sd卡
writeToSDcard(ex);
//写入后在这里可以进行上传操作
} catch (IOException e) {
e.printStackTrace();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return true;
}
return false;
}
private void writeToSDcard(Throwable ex) throws IOException, PackageManager.NameNotFoundException {
//如果没有SD卡,直接返回
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
return;
}
File filedir = new File(PATH);
if (!filedir.exists()) {
filedir.mkdirs();
}
long currenttime = System.currentTimeMillis();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(currenttime));
File exfile = new File(PATH +File.separator+FILE_NAME+time + FILE_NAME_SUFEIX);
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(exfile)));
Log.e("错误日志文件路径",""+exfile.getAbsolutePath());
pw.println(time);
PackageManager pm = mContext.getPackageManager();
PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
//当前版本号
pw.println("App Version:" + pi.versionName + "_" + pi.versionCode);
//当前系统
pw.println("OS version:" + Build.VERSION.RELEASE + "_" + Build.VERSION.SDK_INT);
//制造商
pw.println("Vendor:" + Build.MANUFACTURER);
//手机型号
pw.println("Model:" + Build.MODEL);
//CPU架构
pw.println("CPU ABI:" + Build.CPU_ABI);
ex.printStackTrace(pw);
pw.close();
}
}我们建立一个activity来测试一下:
public class RainActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rain_layout);
btnStartRain.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
throw new NullPointerException("aa");
}
});
}然后点击start按钮,程序没有发生crash,我们到sdcard的crash文件夹下,找到这个日志:

打开这个日志:
2019-01-30 08:52:01
App Version:1.0_1
OS version:6.0.1_23
Vendor:OPPO
Model:OPPO R9s Plus
CPU ABI:arm64-v8a
java.lang.NullPointerException: aa
at com.lingan.seeyou.ui.view.raim.RainActivity$1.onClick(RainActivity.java:38)
at android.view.View.performClick(View.java:5231)
at android.view.View$PerformClick.run(View.java:21240)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:179)
at android.app.ActivityThread.main(ActivityThread.java:5769)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:676)
随时随地看视频