android小知识——Android混淆打包及混淆后运行错误

本文针对Android项目中使用第三方jar包时出现的混淆问题提供了解决方案,包括ClassNotFoundException、NoSuchMethodError等异常处理方法。

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

Android引用第三方jar包混淆时打包报错(can't find referenced class)

           项目打包的时候,总是失败,提示Proguard returned with error code 1. See console。然后看控制台,报出好多can't find referenced class......

场景:项目中引用了第三方的jar包

原因:第三方jar包中引用了好多oracle发布的java标准中(也就是我们常用的JDK)包含的类,但是Android的java标准和oracle的不一样,android.jar里面去掉了oracle java标准中好多用不到的包和类。

解决办法:首先要把你项目中所引入的第三方jar包使用"-libraryjars 包路径"指定好。然后,用-dontwarn com.xx.bbb.**
-keep class com.xx.bbb.** { *;}告诉proguard.cfg不用混淆指定的jar包,也不用提示这个包所报出的错。这样就ok了。

注意:要是用dontwarn取消指定包报错之前,你要保证第三方引用的类在你的项目中没有用到。

 Android混淆后项目运行的时候出现异常(混淆之前没有该异常)

        1、ClassNotFoundException,NoSuchMethodError

        原因:这种异常会在好多情况下出现,比如:本地代码通过反射调用其他的类,但是经过了混淆之后,就会出现如上异常;调用了JNI之后,C或者C++和java代码进行交互的时候找不到java的类或者方法,导致发生了异常......等等,还有好多。

        解决办法:只需要将被调用的java类标注为不混淆即可。 -keep class package.classname{*;}

        2、ExceptionInInitializerError

       原因:这是由于类初始化的时候发生了异常。

       解决办法:找到具体是哪里的类哪个方法哪个类初始化的时候发生的异常,然后解决问题。

        注:遇到这个错误,首先要确认是不是因为第三方的jar包导致的。如果不是的话,就找本地代码,看是不是写的有问题。如果确实是因为第三方jar包的代码导致的,尽量找到源码或者反编译,查看问题到底是什么引起的,然后找到相应的配置在proguard里面配置。

        例如:我们项目中碰到过一个问题,就是因为第三方的jar包里面有一个字段初始化的时候报了空指针,然后导致我们的代码报了上面的错。当时很奇怪,为什么第三方的jar包还能报错,最后调查了之后才发现,是因为人家用到了类的注解,而proguard在混淆优化的时候把注解去掉了,所以报了空指针,只需要在proguard里面加上保护注解就可以了-keepattributes *Annotation*

          3、 ClassCastException

       原因:类强制转换的时候出错。

       解决办法:找到代码,看是代码写的问题,还是混淆后的问题。如果没有混淆正常运行的话,一般都是因为混淆后遇到了各种问题才报的错。我们项目中遇到的问题是因为没有让proguard保持泛型,所以强转的时候报错。只需要在proguard文件里面加上泛型即可-keepattributes Signature

4、Resources$NotFoundException(resource not found)资源没有找到,是因为第三方jar包或者自己的代码是通过反射获得R文件中的资源,所以需要将R文件屏蔽掉    原因:代码进行了混淆,R文件没有了,所以通过反射获取的R文件找不到    解决办法:在proguard文件里设置不混淆R文件    -keep class **.R$* { *; }

大家如果遇到其他的异常,可以在下面提出来,希望可以帮助大家解决问题。

### Android R8 淆配置及常见问题解决方案 #### 配置说明 R8 是 Google 推出的一款用于替代 ProGuard 的代码压缩、混淆和优化工具。它不仅提供了更高效的性能,还增强了对现代 Android 应用的支持[^2]。 在 `gradle.properties` 文件中可以通过以下方式进行全局配置: - **显式启用 R8** 添加如下属性即可强制启用 R8 工具: ```properties android.enableR8=true ``` - **仅针对库模块禁用 R8** 如果希望某些特定的库不被 R8 处理,则可设置: ```properties android.enableR8.libraries=false ``` - **完全关闭 R8 功能** 若要彻底停用 R8 并恢复到旧版 ProGuard 行为,可以这样操作: ```properties android.enableR8=false ``` #### 基础混淆规则 为了防止应用中的重要逻辑或第三方依赖因混淆而失效,在 `proguard-rules.pro` 中需定义清晰的保留策略: 1. **保持公共 API 不变** 使用 `-keep` 关键字来保护对外暴露的方法或类不受混淆影响: ```text -keep public class com.example.MyPublicApi { *; } ``` 2. **避免序列化对象破坏** 当涉及 Java Serializable 或 Parcelable 类型时,应特别注意其字段结构不可改变: ```text -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; !static !transient <fields>; !private <fields>; !private <methods>; } ``` 3. **处理反射调用场景** 若存在动态加载机制(如通过名称实例化类),则需要明确指定哪些部分不应参与混淆过程: ```text -keepnames class com.example.reflective.* ``` 4. **兼容第三方库** 很多开源框架自带推荐使用的 ProGuard/R8 规则文件,请仔细阅读官方文档并将其内容复制至本地配置中。例如 Retrofit 要求加入以下声明以保障网络请求功能正常运行: ```text -dontwarn retrofit2.** -keep class retrofit2.** { *; } -keepattributes Signature,RuntimeVisibleAnnotations -keepattributes Exceptions ``` #### 解决常见问题 尽管 R8 提供了许多改进之处,但在实际开发过程中仍可能遭遇一些挑战。以下是几种典型情况及其对应措施: 1. **反混淆映射无法匹配错误日志** 如当线上发生异常后收到一堆难以理解的堆栈信息时,可通过调整 Command-line Tools 版本来修复此现象。具体做法参见先前提到的技术博客建议——更新或者重新安装相关组件以便获得最新支持特性[^4]^。 2. **Release 构建阶段频繁崩溃** 此种状况通常源于以下几个方面的原因之一: - Lint 检测未通过; - 混淆参数设定不当致使必要资源遗漏; - 第三方插件冲突干扰打包流程; 针对此类难题,《Android 打包 Release 崩溃问题全解析》一文中给出了详尽指导方案,括但不限于排查 NoClassDefFoundError 异常以及学习如何利用 ADB Debugging 工具深入探究根本诱因[^3]^。 ```python def example_function(): """ This is just an illustrative function to show code block formatting. It has no direct relevance with the topic of Android R8 configuration. """ pass ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值