Android开发过程中异常的处理方法

本文深入解析Java中的异常处理机制,包括Error与Exception的区别,运行时异常与非运行时异常的特性,以及如何使用throw和throws进行异常抛出与声明。同时,介绍了Android中全局异常的捕获方法及预防异常的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版,欢迎购买。点击进入详情


异常是指程序指令非正常执行的情况,比如空指针、数组下标越界、类型强制转换异常等,由此导致程序异常退出。Java里面的分两类:一个Error,一个Exception,它们都继承自Throwable。见图所示:
在这里插入图片描述

Error

Error情况是程序本身不能处理的,比如JVM自身的异常,导致程序处于非正常不可恢复状态,比如常见的OutOfMemoryError内存溢出异常。

Exception

程序中能够处理的就是Exception了。
Exception也分两类,一个是运行时异常,一个是非运行时异常

运行时异常就是程序运行时产生的异常,也是我们平常最常见到的异常。像NullPointerException、IndexOutOfBoundsException等。
对于运行时异常,java编译器不要求强制进行异常处理或声明,由程序员自行决定;

非运行时异常,顾名思义就是在程序运行前的异常,也就是编译异常,Java编译器会要求我们强制进行异常处理,比如FileNotFoundException、IOExeption、SQLException、JSONException之类的异常。
比如读文件的方法,可能存在文件不存在的情况,那么Java编译器会要求我们强制捕获并处理FileNotFoundException这类的异常。

抛出异常

throw

  1. 只能用在方法体内;
  2. 抛出的是一个异常实例对象;
private void throwsTest(int a, int b) throws Exception1, Exception3 {
        try {
            ......
        } catch (Exception1 e) {
            throw e;
        } catch (Exception2 e) {
            System.out.println("出错了!");
        }
        if (a != b) {
            throw new
        }  Exception3("自定义异常");
    }

Exception1:方法内部捕获后再抛出,交由该方法的调用者处理;
Exception2:方法内部捕获后处理完成,不再向上抛出;
Exception3:方法内部自行抛出异常,交由该方法的调用者处理;

throws

  1. 跟在方法名后面;
  2. 可以跟多个异常类名;
  3. 由该方法调用者处理该抛出的异常;

例子见上面throw代码。
需要说明一点的是该方法调用者如何处理该抛出的异常:

private void main() {
	try {
			throwsTest();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

可以看到,throwsTest方法的调用者main方法需要捕获throwsTest方法可能抛出的异常。

捕获异常

try catch是最常用的异常捕获手段:

	try{
            return JSON.parseObject(json);
        }
        catch (Exception e){
            LogUtil.e(TAG, "toObject: " + e.getMessage());
        } finally {
       		 ......
		}

有一个地方需要注意的是,try中如果有return语句,那么它和finally直接的关系是怎么样的呢?
我们通过一个例子看下:

	System.out.println(test());
	public static int test() {
		int x = 1;
		try {
			x++;
			return x;
		} finally {
			++x;
			System.out.println(x); 
		}

输出结果是:3,2
也就是finally会先执行,但是try中的return会先将变量x的值保存起来,然后再执行finally中的语句,最后将保存的值返回。

Android全局异常的捕获

Android提供了UncaughtExceptionHandler接口,我们可以新建一个实现了该接口的类,然后通过setDefaultUncaughtExceptionHandler方法注册这个接口,这样就可以捕获异常了。

public class CrashHandler implements Thread.UncaughtExceptionHandler {

    private Context mContext;
    private Thread.UncaughtExceptionHandler mDefaultHandler;
    private static CrashHandler INSTANCE = new CrashHandler();

    public static CrashHandler getInstance() {
        return INSTANCE;
    }

    public void init(Context context) {
        mContext = context.getApplicationContext();
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();// 获取系统默认的UncaughtException处理器
        Thread.setDefaultUncaughtExceptionHandler(this);// 设置该CrashHandler为程序的默认处理器
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        if (mDefaultHandler != null) {
            if (Constant.EXCEPTION_MVP_VIEW_NOT_ATTACHED.equals(e.getMessage())) {// for MVP when presenter calls view but view has already destroyed
                return;
            }
            mDefaultHandler.uncaughtException(t, e);// 退出程序
        }
    }
}

预防异常

以场景的null异常为例:

  1. 增加字符串判空:if(StringUtils.isEmpty(str)){ …}
  2. equal判断:(“常量”).equals(var); 常量在equals前面;
  3. toString:String.valueOf(…),而不是var.toString();
  4. 使用@NonNull 和 @Nullable注解,借助编译器帮助编译前排查null对象;
  5. 使用Guava的checkNotNull,帮助我们主动抛出异常;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值