Android UncaughtExceptionHandler 解决未捕获异常,防止软件报”停止运行“

来源:互联网 发布:淘宝美瞳店铺哪个好 编辑:程序博客网 时间:2024/05/16 14:46

UncaughtExceptionHandler接口

这个接口就是处理程序中没有处理的异常,而且是在系统抛出异常导致程序异常终止之前!无论是空值针,参数异常等各种异常出现后,若代码中未进行处理,均会调用该接口。

具体处理步骤,如下:

1. 创建一个UncaughtExceptionHandler的具体实现类

/** * 未捕获异常捕捉类 */public class CrashHandlers implements Thread.UncaughtExceptionHandler {    public static final String TAG = "CrashHandlers";    // 系统默认的UncaughtException处理类    private Thread.UncaughtExceptionHandler mDefaultHandler;    // CrashHandler实例    private static CrashHandlers instance;    // 程序的Context对象    private Context mContext;    /**     * 保证只有一个CrashHandler实例     */    private CrashHandlers() {    }    /**     * 获取CrashHandler实例 ,单例模式     */    public synchronized static CrashHandlers getInstance() {        if (instance == null) {            instance = new CrashHandlers();        }        return instance;    }    /**     * 初始化     *     * @param context     */    public void init(Context context) {        mContext = context;        // 获取系统默认的UncaughtException处理器        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();        // 设置该CrashHandler为程序的默认处理器        Thread.setDefaultUncaughtExceptionHandler(this);    }    /**     * 当UncaughtException发生时会转入该函数来处理     */    @Override    public void uncaughtException(Thread thread, Throwable ex) {        if (!handleException(thread, ex) && mDefaultHandler != null) {            // 如果用户没有处理则让系统默认的异常处理器来处理            mDefaultHandler.uncaughtException(thread, ex);        } else {            try {                //3秒后执行重启                Thread.sleep(3000);            } catch (InterruptedException e) {                Log.e(TAG, e.toString());            }            //发送广播重新启动APP            mContext.sendBroadcast(new Intent("com.xin.crash"));            //退出程序,否则无法重新启动            android.os.Process.killProcess(android.os.Process.myPid());            System.exit(1);        }    }    /**     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.     *     * @param ex     * @return true-->处理了该异常信息     *          false-->未处理异常.     */    private boolean handleException(Thread thread, Throwable ex) {        if (ex == null) {            //未处理异常,返回false            return false;        }        // 使用Toast来显示异常信息        new Thread() {            @Override            public void run() {                Looper.prepare();                //捕获到异常,弹出提示                Toast.makeText(APP.getInstance(), "即将重启", Toast.LENGTH_SHORT).show();                Looper.loop();            }        }.start();        return true;    }}

2. 自定义Application类

public class APP extends Application {    @override    public void onCreate() {        super.onCreate();        CrashHandler handler = CrashHandler.getInstance();        handler.init(getApplicationContext()); //在Appliction里面设置我们的异常处理器为UncaughtExceptionHandler处理器    }}

3. Application类注册到AndroidManifest文件中

    <application        android:name=".APP"        ...        >    </application>

4. 在代码中抛出异常,查看结果

附一:

在步骤一中,捕获异常后发送了广播,需通过另一个程序接收该广播,并进行启动的操作

public class Rece extends BroadcastReceiver {    public static String TAG = "MyCrash";    public static String PKGNAME= "com.test.crash";    @Override    public void onReceive(Context context, Intent intent) {        Log.i(TAG,"收到广播");        //执行启动        Intent LaunchIntent = context.getPackageManager().getLaunchIntentForPackage(PKGNAME);        LaunchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        context.startActivity(LaunchIntent);    }}

附二:

若需当异常出现时,通过Dialog提示用户,部分代码如下:

   /**     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.     *     * @param ex     * @return true-->处理了该异常信息     * false-->未处理异常.     */    private boolean handleException(Thread thread, Throwable ex) {        if (ex == null) {            //未处理异常,返回false            return false;        }        // 使用Dialog来显示异常信息        new Thread() {            @Override            public void run() {                Looper.prepare();                //捕获到异常,弹出提示                new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false)                        .setMessage("程序崩溃了...").setNeutralButton("我知道了", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        //发送广播重新启动APP                        mContext.sendBroadcast(new Intent("com.xin.crash"));                        android.os.Process.killProcess(android.os.Process.myPid());                        System.exit(1);                    }                }).create().show();                Looper.loop();            }        }.start();        return true;    }
  • 说明:Dialog必须依附于Activity之上,Application作为参数时无法弹出Dialog。因此,若需如此,UncaughtExceptionHandler这个类必须在Activity中的onCreate()中实现。Sample如下:
public class BaseActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        CrashHandler crashHandler = CrashHandler.getInstance();        crashHandler.init(this);  //传入参数必须为Activity,否则AlertDialog将不显示。    }}
0 0
原创粉丝点击