Android常用异常及解决方案

1、什么是异常?

      异常是指在程序运行中所出现的错误,这些错误会干扰到指令的正常执行,从而造成程序异常退出,这些异常出现的场景比如有:文件找不到,网络连接失败,非法参数等.

2、异常来源

      就Java语言来说,所有的异常都继承自Throwable

3、Android常见异常分类

1-编译时错误
(eg:ClassNotFoundException/layout中找不到ID等)
2-运行是错误
(eg:数组越界/类型转换异常等)

4、全局异常捕获

public class CrashHandler implements Thread.UncaughtExceptionHandler {    private static CrashHandler mInstance;    private Context mContext;    private Thread.UncaughtExceptionHandler mDefaultHandler;    //存储设备信息和异常信息    private Map mInfo = new HashMap<>();    //文件日期格式    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    private CrashHandler() {    }    /**     * 单例模式     *     * @return     */    public static CrashHandler getmInstance() {        if (mInstance == null) {            synchronized (CrashHandler.class) {                if (mInstance == null) {                    mInstance = new CrashHandler();                }            }        }        return mInstance;    }    /**     * 初始化     *     * @param context     */    public void init(Context context) {        this.mContext = context.getApplicationContext();        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();        Thread.setDefaultUncaughtExceptionHandler(this);    }    @Override    public void uncaughtException(Thread t, Throwable e) {        Log.e("hpc", "错误信息");        //1'收集错误信息        //2'保存错误信息        //3'上传服务器        if (!handleException(e)) {            //未处理,调用系统默认的处理器处理            if (mDefaultHandler != null) {                mDefaultHandler.uncaughtException(t, e);            }        } else {            //已经人为处理            Intent intent = new Intent(mContext.getApplicationContext(), MainActivity.class);            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            PendingIntent restartIntent = PendingIntent.getActivity(                    mContext.getApplicationContext(), 0, intent, 0);            //退出程序            AlarmManager mgr = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);            mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000,                    restartIntent); // 1秒钟后重启应用*/            android.os.Process.killProcess(android.os.Process.myPid());        }    }    /**     * 是否人为处理异常     *     * @return true已经处理 false未处理     */    private boolean handleException(Throwable e) {        if (e == null) {            return false;        } else {            //收集错误信息            collectErrorInfo();            //保存错误信息            saveErrorInfo(e);            return true;        }    }    private void saveErrorInfo(Throwable e) {        StringBuffer stringBuffer = new StringBuffer();        for (Map.Entry entry : mInfo.entrySet()) {            String keyName = entry.getKey();            String value = entry.getValue();            stringBuffer.append(keyName + "=" + value + "\n");        }        StringWriter sw = new StringWriter();        e.printStackTrace(new PrintWriter(sw, true));        String strs = sw.toString();        stringBuffer.append(strs);        long curTime = System.currentTimeMillis();        String time = dateFormat.format(new Date());        String fileName = "crash-" + time + "-" + curTime + ".log";        //判断有没有sd卡        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {            String path = Environment.getExternalStorageDirectory() + File.separator;            File dir = new File(path);            if (!dir.exists()) {                dir.mkdirs();            }            FileOutputStream fos = null;            try {                fos = new FileOutputStream(path + fileName);                fos.write(stringBuffer.toString().getBytes());            } catch (FileNotFoundException e1) {                e1.printStackTrace();            } catch (IOException e1) {                e1.printStackTrace();            } finally {                try {                    fos.close();                    Log.e("hpc", dir.getAbsolutePath());                } catch (IOException e1) {                    e1.printStackTrace();                }            }        }    }    private void collectErrorInfo() {        PackageManager pm = mContext.getPackageManager();        try {            PackageInfo packageInfo = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);            if (packageInfo != null) {                String versionName = TextUtils.isEmpty(packageInfo.versionName) ? "未设置版本名称" : packageInfo.versionName;                String versionCode = packageInfo.versionCode + "";                mInfo.put("versionName", versionName);                mInfo.put("versionCode", versionCode);                Field fields[] = Build.class.getFields();                if (fields != null && fields.length > 0) {                    for (Field field : fields) {                        field.setAccessible(true);                        mInfo.put(field.getName(), field.get(null).toString());                    }                }            }        } catch (PackageManager.NameNotFoundException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }    }}
public class MainActivity extends AppCompatActivity {    private String mStr;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    private void initContent() {        System.out.println("" + (1 / 0));    }    public void error() {        initContent();    }}
public class CustomApplication extends Application {    private CrashHandler crashHandler;    @Override    public void onCreate() {        super.onCreate();        crashHandler = CrashHandler.getmInstance();        crashHandler.init(this);    }}

5、最后推荐一个目前比较火的全局异常捕获库:Bugly

更多相关文章

  1. Android编程之manifest上遇到的错误
  2. [置顶] Android(安卓)调用js,传对象到js里面使用addJavascriptInt
  3. Eclipse android 项目转android studio填坑之旅
  4. Android(安卓)调用js,传对象到js里面使用addJavascriptInterface
  5. Android(安卓)eclipse - aapt.exe has stopped working.
  6. Android老版本项目导入到新版SDK提示错误
  7. Android工程中R.java文件的重新生成——注意资源文件的错误
  8. Android入门篇四:使用全局变量在Activity之间传递数据
  9. android user版本进行编译出现proguard错误混淆

随机推荐

  1. 《Android》Lesson09-Acitivity的四种启
  2. Android支持横行滚动的ListView控件
  3. 使用eclipse创建android工程时得到警告
  4. android:shape的使用
  5. android 简单的上拉加载实现
  6. Android(安卓)Studio打包Signed APK 碰到
  7. [Android] 无法创建项目问题解决
  8. WebView显示网页
  9. Android(安卓)系统搜索框(有浏览记录)
  10. Android图片压缩及内存缓存