记一次混淆后引起的异常,被覆盖的方法未抛出Exception

前言

本地开发的时候运行正常,开启了混淆之后编译通过运行失败

描述

项目中遇到了一个问题,module中有一个方法,改方法会抛Exception,

    public Map<String, String> encryptParams(Map<String, String> params) throws Exception {
        return params;
    }
在主工程中有一个改类的子类复写类该方法,做了一些其他的逻辑,开发的时候为类方便把混淆关了直接关联工程开发。调试完毕之后开了混淆准备打包然后就build 失败。

0001

根据提示判断是因为父类中的encryptParams()方法未抛Exception,所以子类也不能抛。看代码确定是有throw Exception的,于是Module打出来的jar反编译下看看到底有没有。
JD-GUI可以很方便的反编译jar包。使用AndroidStudio更方便直接把jar拖到libs下面,然后sync。

这里写图片描述

可以看到混淆后的代码

0003

来一张对比的

0004

对比发现混淆后的jar是没有throw Exception的,这里的gradle版本是1.5.0,仔细观察发现map的泛型也没有。
再来一张gradle 2.3.3 版本的(因为我Studio版本是2.3.3的),有泛型没有throw Exception

0005

最后放上三个对比的
//    混淆后 gradle 1.5.0
//    public Map encryptParams(Map var1) {
//        return var1;
//    }

//    混淆后 gradle 2.3.3
//    public Map<String, String> encryptParams(Map<String, String> var1) {
//        return var1;
//    }

    //混淆前
    public Map<String, String> encryptParams(Map<String, String> params) throws Exception {
        return params;
    }
Demo地址

结论

gradle 1.5.0版本 在开启混淆生成jar的时候会把泛型和throw Exception去掉,gradle 2.3.3版本开启有泛型无throw Exception。原因暂未查到,有清楚的欢迎讨论。

补充

后期发现泛型是因为没有在混淆配置中添加忽略,添加以下内容就可以保留混淆。
# 避免混淆泛型
-keepattributes Signature

最终解决方案

今天突然想起来,EventBus在注册了两次之后会抛异常,就去看下EventBus怎么处理的。直接看代码

    // Must be called in synchronized block
    private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
       ...
        if (subscriptions == null) {
            subscriptions = new CopyOnWriteArrayList<>();
            subscriptionsByEventType.put(eventType, subscriptions);
        } else {
            if (subscriptions.contains(newSubscription)) {
                throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                        + eventType);
            }
        }
        ...

抛了异常但方法上没有throws ,跟进去EventBusException

public class EventBusException extends RuntimeException { ... }

原来如此。
方法来了,只需要把我们之前的Exception 换成 RuntimeException或者自定义一个他的子类就可以解决库中抛的异常不会打进jar中的问题了,然后在需要的地方处理catch到的异常。
Exception:在程序中必须使用try…catch进行处理。
RuntimeException:可以不使用try…catch进行处理,但是如果有异常产生,则异常将由JVM进行处理。
所以,为了保证程序再出错后依然可以执行,在开发代码时最好使用try…catch的异常处理机制进行处理。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值