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

前言

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

描述

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

public Map encryptParams(Map params) throws Exception {

return params;

}

在主工程中有一个改类的子类复写类该方法,做了一些其他的逻辑,开发的时候为类方便把混淆关了直接关联工程开发。调试完毕之后开了混淆准备打包然后就build 失败。

8d5e3a0adbd34246a34d8b1f68f81caf.png

根据提示判断是因为父类中的encryptParams()方法未抛Exception,所以子类也不能抛。看代码确定是有throw Exception的,于是Module打出来的jar反编译下看看到底有没有。

JD-GUI可以很方便的反编译jar包。使用AndroidStudio更方便直接把jar拖到libs下面,然后sync。

438d499db79a87ab0433df8687fba536.png

可以看到混淆后的代码

aa514688bf6e4ee97d72b097280fd1f8.png

来一张对比的

fa7d05bd81fa9a1e329b5f166e5c3f89.png

对比发现混淆后的jar是没有throw Exception的,这里的gradle版本是1.5.0,仔细观察发现map的泛型也没有。

再来一张gradle 2.3.3 版本的(因为我Studio版本是2.3.3的),有泛型没有throw Exception

02be654767412485f932b87ec699f4b6.png

最后放上三个对比的

// 混淆后 gradle 1.5.0

// public Map encryptParams(Map var1) {

// return var1;

// }

// 混淆后 gradle 2.3.3

// public MapencryptParams(Mapvar1) {

// return var1;

// }

//混淆前

public Map encryptParams(Map 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的异常处理机制进行处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当Spring Boot应用程序在启动时抛出`java.lang.NoSuchMethodError`异常,通常意味着你在运行时的Java环境中找不到某个类或方法,而这个方法是你的程序或者依赖中某个库所必需的。这可能是由于以下几个原因: 1. **版本冲突**:你的项目可能包含了多个版本的相同库,而在运行时,两个版本之间对于某些方法的定义不兼容。 2. **类路径问题**:确保所有的依赖和库都在类路径(classpath)中正确配置,且版本正确匹配。 3. **环境变量**:检查构建工具(如Maven或Gradle)的配置,确保环境变量设置正确,特别是JDK的路径。 4. **IDE问题**:IDE如IntelliJ IDEA可能会自动添加一些插件或代理类,检查这些设置是否影响到了类的加载。 5. **混淆或打包问题**:如果使用了混淆或插件,确认它们不会混淆或移除重要方法。 要解决这个问题,你可以尝试以下步骤: - **查看错误堆栈**:仔细阅读异常堆栈信息,找出具体哪个方法找不到。 - **更新依赖**:检查是否有版本升级或降级的需要,确保所有依赖都是最新且兼容的。 - **排除第三方库**:逐个排除怀疑的第三方库,看看哪一个是冲突源。 - **清理并重新构建**:删除本地缓存,重建项目以确保所有资源都被正确处理。 - **使用日志帮助诊断**:启用详细的日志,有助于找到引发错误的具体代码行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值