Android常用异常及解决方案
16lz
2022-05-09
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
更多相关文章
- Android编程之manifest上遇到的错误
- [置顶] Android(安卓)调用js,传对象到js里面使用addJavascriptInt
- Eclipse android 项目转android studio填坑之旅
- Android(安卓)调用js,传对象到js里面使用addJavascriptInterface
- Android(安卓)eclipse - aapt.exe has stopped working.
- Android老版本项目导入到新版SDK提示错误
- Android工程中R.java文件的重新生成——注意资源文件的错误
- Android入门篇四:使用全局变量在Activity之间传递数据
- android user版本进行编译出现proguard错误混淆