Android 捕捉app系统中未处理的异常

来源:互联网 发布:c语言也能干大事u 编辑:程序博客网 时间:2024/05/02 10:48

转载请标明出处:http://blog.csdn.net/u011546655/article/details/45566741


一:为什么要处理?


其实我们都知道,在开发过程中,自己的app系统或许有许多隐藏的异常,自己没有捕捉到,那么关于异常的捕捉,这是相当重要的,如果系统发生崩溃,那么至少也可以让系统挂在系统之内,不会发现什么系统直接退了,或者是卡死,这样做,能够使得用户体验效果更加,自己也可以发现用户到底出现什么异常,便于自己以后好处理这个问题,优化处理自己的系统。


二:如何解决

在Android 开发中,自身其实带有一个系统默认的异常处理接口,UncaughtExceptionHandler,该接口呢,能够很好的处理程序中发生的异常,所以,往往开发者都喜欢使用它,而且它也是一个非常简单好用的东西。


三:具体实现


(1)实现UncaughtExceptionHandler接口的类

package com.x1.tools;import java.lang.Thread.UncaughtExceptionHandler;import android.app.ActivityManager;import android.content.ComponentName;import android.content.Context;import android.os.Looper;import android.util.Log;import com.x1.dao.SubmitConfigBugs;import com.x1.ui.R;/** * 未捕获异常捕捉类 *  * @author zengtao 2015年5月6日 * * */public class CrashHandlers implements UncaughtExceptionHandler {public static final String TGA = "CrashHandlers";// 系统默认的UncaughtException处理类private Thread.UncaughtExceptionHandler mDefaultHandler;// CrashHandler实例private static CrashHandlers instance;// 程序的Context对象private Context mContext;private GetPhoneInfo phone;/** 保证只有一个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);phone = new GetPhoneInfo(context);}/** * 当UncaughtException发生时会转入该函数来处理 */@Overridepublic void uncaughtException(Thread thread, Throwable ex) {if (!handleException(thread, ex) && mDefaultHandler != null) {// 如果用户没有处理则让系统默认的异常处理器来处理mDefaultHandler.uncaughtException(thread, ex);} else {try {Thread.sleep(3000);} catch (InterruptedException e) {Log.e(TGA, e.toString());}// 退出程序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) {return false;}// 使用Toast来显示异常信息new Thread() {@Overridepublic void run() {Looper.prepare();ShowToast.show(mContext, "喵,很抱歉,程序出现异常,即将退出!",R.drawable.error_icon);Looper.loop();}}.start();// 把异常信息和设备信息上传到服务器subMitThreadAndDeviceInfo(mContext, thread, ex);return true;}// 提交信息到服务器public void subMitThreadAndDeviceInfo(Context ctx, Thread thread,Throwable ex) {// 当前用户的账号String Account = null;if (Config.getCachedAccount(ctx) != null) {Account = Config.getCachedAccount(ctx);} else {Account = "当前无用户登录";}// 手机设备的信息String PhoneModel = phone.PhoneModel;String PhoneVersion = phone.PhoneVersion;String PhoneResolution = phone.PhoneResolution;String ZcmVersion = phone.ZcmVersion;String AvailableRom = phone.AvailableRom;// 获取当前显示在界面上的Activity的路径加类名ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);ComponentName cn = am.getRunningTasks(1).get(0).topActivity;// 异常信息加异常所在类的绝对路径final String content = "thread: " + thread + " , name: "+ thread.getName() + ", id: " + thread.getId()+ ", exception: " + ex + ", " + cn.getClassName();// 执行接口,把异常信息提交到服务器new SubmitConfigBugs(0, ctx, Account, PhoneModel, PhoneVersion,PhoneResolution, ZcmVersion, AvailableRom, content,new SubmitConfigBugs.SuccessCallback() {@Overridepublic void onSuccess() {Log.e(TGA, content + "\n错误信息提交成功");}}, new SubmitConfigBugs.FailCallback() {@Overridepublic void onFail() {Log.e(TGA, content + "\n错误信息提交失败");}});}}


(2)实体类:手机信息

package com.x1.tools;import android.content.Context;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.os.Environment;import android.os.StatFs;import android.text.TextUtils;import android.view.Display;import android.view.WindowManager;/** * 获取当前手机的设备信息和当前软件的版本 *  * @author zengtao 2015年5月6日 * * */public class GetPhoneInfo {private Context context;public String PhoneModel;public String PhoneVersion;public String PhoneResolution;public String ZcmVersion;public String AvailableRom;public GetPhoneInfo(Context context) {this.context = context;PhoneModel = android.os.Build.MODEL;PhoneVersion = android.os.Build.VERSION.RELEASE;PhoneResolution = getDisplayWAndH();ZcmVersion = getAppVersionName(this.context);AvailableRom = "ROM剩余存储空间: " + getAvailableInternalMemorySize() + "MB"+ ",内置SDCard剩余存储空间: " + getAvailableExternalMemorySize() + "MB";}// 获取当前版本号private String getAppVersionName(Context context) {String versionName = "";try {PackageManager packageManager = context.getPackageManager();PackageInfo packageInfo = packageManager.getPackageInfo("com.x1.ui", 0);versionName = packageInfo.versionName;if (TextUtils.isEmpty(versionName)) {return "";}} catch (Exception e) {e.printStackTrace();}return versionName;}// 获取屏幕分辨率@SuppressWarnings("deprecation")private String getDisplayWAndH() {WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);Display display = wm.getDefaultDisplay();String string = "屏幕分辨率: " + display.getWidth() + "x"+ display.getHeight();return string;}/** *  * @return ROM存储路径 */private String getInternalMemoryPath() {return Environment.getDataDirectory().getPath();}/** *  * @return 内置sd卡路径 */private String getExternalMemoryPath() {return Environment.getExternalStorageDirectory().getPath();}/** *  * @param path *            文件路径 * @return 文件路径的StatFs对象 * @throws Exception *             路径为空或非法异常抛出 */private StatFs getStatFs(String path) {try {return new StatFs(path);} catch (Exception e) {e.printStackTrace();}return null;}/** *  * @param stat *            文件StatFs对象 * @return 剩余存储空间的MB数 *  */@SuppressWarnings("deprecation")private float calculateSizeInMB(StatFs stat) {if (stat != null)return stat.getAvailableBlocks()* (stat.getBlockSize() / (1024f * 1024f));return 0.0f;}/** *  * @return ROM剩余存储空间的MB数 */private float getAvailableInternalMemorySize() {String path = getInternalMemoryPath();// 获取数据目录StatFs stat = getStatFs(path);return calculateSizeInMB(stat);}/** *  * @return 内置SDCard剩余存储空间MB数 */private float getAvailableExternalMemorySize() {String path = getExternalMemoryPath();// 获取数据目录StatFs stat = getStatFs(path);return calculateSizeInMB(stat);}}


四:总结

以上呢,就可以直接抓捕程序中未处理的异常,而且使得用户在系统自身开发崩溃的时候,不至于造成,直接挂了,所以,在程序中,做这样的处理是非常有必要的,在上面CrashHandlers有一个执行接口的处理,提交数据到服务器,这个是自身开发中所定义的接口,这个可以根据自己的想法实现,我在这个当中,是将手机提交的一些信息,和错误信息发送到服务器,而完成的,这样也可以让自己知道,是什么手机出错,有目的去处理,更好的维护自己的系统。


0 0
原创粉丝点击