赞
踩
Exception 这种异常分两大类运行时异常和非运行时异常(编译异常)。程序中应当尽可能去处理这些异常。
运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常 (编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
二,异常的捕获方法:
try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch 块:用于处理try捕获到的异常。
finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。
1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;
2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;
3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;
三,常见异常和处理方法
奇葩的问题:
1.
图片。类,找不到,混淆问题:
android.content.res.Resources$NotFoundException: File res/drawable-xhdpi-v4/abnormal_purple_beg.png from drawable resource ID #0x7f020008
2.没有方法,可能是API低版本的不支持,
java.lang.NoSuchMethodError
3.
java.util.concurrent.TimeoutException:
4.
java.lang.SecurityException: Not allowed to start activity Intent
5.
Caused by: android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
6.
java.lang.RuntimeException: Could not read input channel file descriptors from parcel.
7.java.lang.reflect.InvocationTargetException
onSaveInstanceState方法是在该Activity即将被销毁前调用,来保存Activity数据的,如果在保存玩状态后
再给它添加Fragment就会出错。解决办法就是把commit()方法替换成 commitAllowingStateLoss()就行
解决IllegalStateException: Can not perform this action after onSaveInstanceState
3.Fragment java.lang.IllegalStateException: Fragment already added:
4. Java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
出现在Fragment或者是Adatper中!
分析mInflater.inflate(R.layout.eg_refresh_message, this, false);
5.清理 TidyShowActivity back建和onsaveinstance, 不调用父类的方法就可以
解决方法:
/** * 奔溃日志收集类 * @author rongweixin * @version 2017/2/15 11:26 * @email rongweixin@17renren.com */ public class CrashHandler implements Thread.UncaughtExceptionHandler { //系统默认的UncaughtException处理类 private Thread.UncaughtExceptionHandler mDefaultHandler; //CrashHandler实例 private static CrashHandler instance = new CrashHandler(); //程序的Context对象 private Context mContext; private static final String TAG=CrashHandler.class.getSimpleName(); /** 崩溃应用包名KEY */ private final String KEY_PKG = "key_pkg"; /** APP版本号KEY */ private final String KEY_VER = "key_ver"; /** APP渠道号KEY */ private final String KEY_CXHZCHANNEL = "key_cxhzchannel"; /** 厂商 */ private final String KEY_BRAND = "key_brand"; /** 机型 */ private final String KEY_MODEL = "key_model"; /** 系统版本KEY */ private final String KEY_OS_VER = "key_os_ver"; /** 崩溃时间KEY */ private final String KEY_TIME = "key_time"; //用来存储设备信息和异常信息 系统崩溃日志 private Map<String, String> infos; //用于格式化日期,作为日志文件名的一部分 private DateFormat formatter; /** 保证只有一个CrashHandler实例 */ private CrashHandler() { infos = new HashMap<String, String>(); formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.CHINA); } /** 获取CrashHandler实例 ,单例模式 */ public static CrashHandler getInstance() { return instance; } /** * 初始化 * @param context */ public void init(final Context context) { mContext = context; //获取系统默认的UncaughtException处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); //设置该CrashHandler为程序的默认处理器 Thread.setDefaultUncaughtExceptionHandler(this); new Thread(new Runnable() { @Override public void run() { String pkg = CXPackageManagerUtil.getCurProcessName(context); for(int i=0;i<3;i++){ if(pkg.contains(context.getPackageName())){ try { Thread.sleep(1000); }catch (Exception e){ e.printStackTrace(); } pkg = CXPackageManagerUtil.getCurProcessName(context); }else{ break; } } infos.put(KEY_PKG, pkg); if(pkg.contains(context.getPackageName())){ infos.put(KEY_VER, String.valueOf(CXPackageManagerUtil.getPackageVersionCode(context))); infos.put(KEY_CXHZCHANNEL, CXPackageManagerUtil.getChannel(context)); }else{ infos.put(KEY_VER, String.valueOf(CXPackageManagerUtil.getVersionCode(mContext, mContext.getPackageName()))); infos.put(KEY_CXHZCHANNEL, ""); } infos.put(KEY_BRAND, Build.BRAND); infos.put(KEY_MODEL, Build.MODEL); infos.put(KEY_OS_VER, Build.VERSION.RELEASE); CXLog.i(TAG, infos.toString()); } }).start(); } /** * 初始化数据 * @param pkg */ public void init(String pkg){ if(pkg != null){ infos.put(KEY_PKG, pkg); infos.put(KEY_VER, String.valueOf(CXPackageManagerUtil.getVersionCode(mContext, mContext.getPackageName()))); infos.put(KEY_CXHZCHANNEL, CXPackageManagerUtil.getChannel(mContext)); infos.put(KEY_BRAND, Build.BRAND); infos.put(KEY_MODEL, Build.MODEL); infos.put(KEY_OS_VER, Build.VERSION.RELEASE); CXLog.i(TAG, infos.toString()); } } /** * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. * * @param ex * @return true:如果处理了该异常信息;否则返回false. */ private boolean handleException(Throwable ex) { boolean handled = false; if(ex != null){ // 上传奔溃日志 postCrash(getCrashInfo(ex)); // 保存奔溃日志 CXLog.e(TAG, infos.toString()); CXLog.e(TAG, getCrashInfo(ex)); // writeCrashInfo(ex); //使用Toast来显示异常信息 if(infos.get(KEY_PKG).equals(mContext.getPackageName())){ new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(mContext, "程序发生异常,正在退出……", Toast.LENGTH_LONG).show(); Looper.loop(); } }.start(); } handled = true; } return handled; }
Exception 这种异常分两大类运行时异常和非运行时异常(编译异常)。程序中应当尽可能去处理这些异常。
运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常 (编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
二,异常的捕获方法:
try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch 块:用于处理try捕获到的异常。
finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。
1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;
2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;
3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;
三,常见异常和处理方法
7.java.lang.reflect.InvocationTargetException
onSaveInstanceState方法是在该Activity即将被销毁前调用,来保存Activity数据的,如果在保存玩状态后
再给它添加Fragment就会出错。解决办法就是把commit()方法替换成 commitAllowingStateLoss()就行
解决IllegalStateException: Can not perform this action after onSaveInstanceState
3.Fragment java.lang.IllegalStateException: Fragment already added:
4. Java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
出现在Fragment或者是Adatper中!
分析mInflater.inflate(R.layout.eg_refresh_message, this, false);
5.清理 TidyShowActivity back建和onsaveinstance, 不调用父类的方法就可以
解决方法:
/** * 奔溃日志收集类 * @author rongweixin * @version 2017/2/15 11:26 * @email rongweixin@17renren.com */ public class CrashHandler implements Thread.UncaughtExceptionHandler { //系统默认的UncaughtException处理类 private Thread.UncaughtExceptionHandler mDefaultHandler; //CrashHandler实例 private static CrashHandler instance = new CrashHandler(); //程序的Context对象 private Context mContext; private static final String TAG=CrashHandler.class.getSimpleName(); /** 崩溃应用包名KEY */ private final String KEY_PKG = "key_pkg"; /** APP版本号KEY */ private final String KEY_VER = "key_ver"; /** APP渠道号KEY */ private final String KEY_CXHZCHANNEL = "key_cxhzchannel"; /** 厂商 */ private final String KEY_BRAND = "key_brand"; /** 机型 */ private final String KEY_MODEL = "key_model"; /** 系统版本KEY */ private final String KEY_OS_VER = "key_os_ver"; /** 崩溃时间KEY */ private final String KEY_TIME = "key_time"; //用来存储设备信息和异常信息 系统崩溃日志 private Map<String, String> infos; //用于格式化日期,作为日志文件名的一部分 private DateFormat formatter; /** 保证只有一个CrashHandler实例 */ private CrashHandler() { infos = new HashMap<String, String>(); formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.CHINA); } /** 获取CrashHandler实例 ,单例模式 */ public static CrashHandler getInstance() { return instance; } /** * 初始化 * @param context */ public void init(final Context context) { mContext = context; //获取系统默认的UncaughtException处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); //设置该CrashHandler为程序的默认处理器 Thread.setDefaultUncaughtExceptionHandler(this); new Thread(new Runnable() { @Override public void run() { String pkg = CXPackageManagerUtil.getCurProcessName(context); for(int i=0;i<3;i++){ if(pkg.contains(context.getPackageName())){ try { Thread.sleep(1000); }catch (Exception e){ e.printStackTrace(); } pkg = CXPackageManagerUtil.getCurProcessName(context); }else{ break; } } infos.put(KEY_PKG, pkg); if(pkg.contains(context.getPackageName())){ infos.put(KEY_VER, String.valueOf(CXPackageManagerUtil.getPackageVersionCode(context))); infos.put(KEY_CXHZCHANNEL, CXPackageManagerUtil.getChannel(context)); }else{ infos.put(KEY_VER, String.valueOf(CXPackageManagerUtil.getVersionCode(mContext, mContext.getPackageName()))); infos.put(KEY_CXHZCHANNEL, ""); } infos.put(KEY_BRAND, Build.BRAND); infos.put(KEY_MODEL, Build.MODEL); infos.put(KEY_OS_VER, Build.VERSION.RELEASE); CXLog.i(TAG, infos.toString()); } }).start(); } /** * 初始化数据 * @param pkg */ public void init(String pkg){ if(pkg != null){ infos.put(KEY_PKG, pkg); infos.put(KEY_VER, String.valueOf(CXPackageManagerUtil.getVersionCode(mContext, mContext.getPackageName()))); infos.put(KEY_CXHZCHANNEL, CXPackageManagerUtil.getChannel(mContext)); infos.put(KEY_BRAND, Build.BRAND); infos.put(KEY_MODEL, Build.MODEL); infos.put(KEY_OS_VER, Build.VERSION.RELEASE); CXLog.i(TAG, infos.toString()); } } /** * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. * * @param ex * @return true:如果处理了该异常信息;否则返回false. */ private boolean handleException(Throwable ex) { boolean handled = false; if(ex != null){ // 上传奔溃日志 postCrash(getCrashInfo(ex)); // 保存奔溃日志 CXLog.e(TAG, infos.toString()); CXLog.e(TAG, getCrashInfo(ex)); // writeCrashInfo(ex); //使用Toast来显示异常信息 if(infos.get(KEY_PKG).equals(mContext.getPackageName())){ new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(mContext, "程序发生异常,正在退出……", Toast.LENGTH_LONG).show(); Looper.loop(); } }.start(); } handled = true; } return handled; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。