程序崩溃是最让人头疼的事情。当用户使用时,如果是第一次运行就崩溃,那此程序一定没戏了。即使是偶尔崩溃也会让用户心里很不爽。其实这不能全怪我们程序员。有些问题,我们也无法预知啊。但,作为一名优秀的程序员,我们还是拦过责任来,就是我们的问题。我处理就是了。
处理思路:捕捉崩溃异常,重启并报告异常。
那么现在就面临三个问题。一个是怎样捕捉Uncaught Exception,一个是重启并报告异常。
问题一,捕捉Uncaught Exception
对于此问题,其实Java早就为我们做好了。Android系统沿用了Java的处理机制。既然如此,我们拿来用就成了。Java里有一个UncaughtExceptionHandler的接口,接口里有一个uncaughtException()的方法。还有一个类叫ThreadGroup extends UncaughtExceptionHandler。所以我们有两种方法去捕捉Uncaught Exception了。一种是extends ThreadGroup类并Override uncaughtException()方法;一种是implements UncaughtExceptionHandler接口并Override uncaughtException()方法。代码请往下看。
问题二,重启并报告异常
重启程序呢,有很多种方法,但归根结底就是两种,一种是通过Intent直接打开,一种是通过AlarmManager来定时启动。 代码请往下看。
报告异常其实也就是得到String信息进行处理。代码往下看。
不要忘记要退出程序,怎么退出呢:System.exit(0);android.os.Process.killProcess(android.os.Process.myPid());还有通过ActivityManager来实现。其实在高版本android系统中这些方法都没用了,google把这些都给废弃限制了。不过对本文要讲的问题没有什么影响。本文中要加入System.exit(0);或android.os.Process.killProcess(android.os.Process.myPid);。ActivityManager这种是不可行的。已测试。
实例代码
AppContext.java
package com.study.exceptionhandler; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; import java.lang.Thread.UncaughtExceptionHandler; import android.app.AlarmManager; import android.app.Application; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; /** * @time 2015-09-19 * @author Leo * @describe 应用管理和异常处理 * */ public class AppContext extends Application { @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Thread.setDefaultUncaughtExceptionHandler(mExceptionHandler);// 设置默认异常处理类 } @Override public void onLowMemory() { // TODO Auto-generated method stub super.onLowMemory(); // insert handle code here } /** * 自定义崩溃异常处理对象 */ private UncaughtExceptionHandler mExceptionHandler = new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread arg0, Throwable arg1) { // TODO Auto-generated method stub restartApplication1(); System.exit(0);// 退出上次的程序 可以不加 android.os.Process.killProcess(android.os.Process.myPid()); } }; /** * 重启程序 程序不退出 但会闪屏 */ private void restartApplication1() { Intent intent = getPackageManager().getLaunchIntentForPackage( getPackageName()); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); } /** * 重启程序 程序不退出 但会闪屏 */ private void restartApplication2() { Intent intent = new Intent(getApplicationContext(), MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } /** * 通过定时器重启程序 程序会退出再打开 */ private void restartApplication3() { Intent intent = getPackageManager().getLaunchIntentForPackage( getPackageName()); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent operation = PendingIntent.getActivity( getApplicationContext(), 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK); AlarmManager mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis(), operation); } /** * 错误信息 你可以保存到文件里 也可上传到服务器 想怎么处理就怎么处理 * @param ex * @return */ private String getErrorInfo(Throwable ex) { String info = null; ByteArrayOutputStream baos = null; PrintStream err = null; try { baos = new ByteArrayOutputStream(); err = new PrintStream(baos); ex.printStackTrace(err); byte[] bytes = baos.toByteArray(); info = new String(bytes); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (err != null) err.close(); try { if (baos != null) baos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return info; } }
总结
Bug是解决不完的,但还是要解决的。不要问为什么,努力解决就是了。这样技术慢慢就提高了,离大神越来越进了。加油。