Android:混淆文件proguard.cfg详解

在android项目中,一般都要使用代码混淆,在项目的根目录下,
这里写图片描述
红色圈中部分是代码混淆的文件。
下面给出proguard.cfg文件的内容:

#指定代码的压缩级别
-optimizationpasses 5
 #混淆时不会产生形形色色的类名  是否使用大小写混合
-dontusemixedcaseclassnames
 #指定不去忽略非公共的类库 是否混淆第三方jar
-dontskipnonpubliclibraryclasses
#不预校验  混淆时是否做预校验
-dontpreverify
#混淆时是否记录日志
-verbose 
-ignorewarnings
#优化 混淆时所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#不进行混淆、原样输出 保持哪些类不被混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService
#保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
# 保持 native 方法不被混淆
-keepclasseswithmembernames class * {
    native <methods>;
}
#保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
#保持自定义控件类不被混淆
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {  
    public <init>(android.content.Context);  
}
#保护指定类的成员,如果此类受到保护他们会保护的更好 
-keepclassmembers class * extends android.app.Activity { 
public void *(android.view.View); 
}
#保持枚举 enum 类不被混淆
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

#保护指定的类文件和类的成员
#保持 Parcelable 不被混淆
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** i(...);
}
-keepclassmembers class **.R$* {
    public static <fields>;
}
#引用的库的jar,添加进来
-libraryjars libs/android-support-v4.jar
-libraryjars libs/android-viewbadger.jar
-libraryjars libs/baidumapapi_v3_2_0.jar
-libraryjars libs/cyberplayer-sdk.jar
-libraryjars libs/jpush-sdk-release1.7.2.jar
-libraryjars libs/ksoap2-android.jar
-libraryjars libs/locSDK_3.3.jar
-libraryjars libs/universal-image-loader-1.9.4-with-sources.jar
-libraryjars libs/picasso-2.4.0.jar
-libraryjars libs/umeng-analytics-v5.2.4.jar
-libraryjars libs/HMSDK.jar
-libraryjars libs/KJFrameForAndroid_v2.245.jar

-dontwarn com.huamaitel.**
-keep class com.huamaitel.** { *;}

-dontwarn javax.security.sasl.**
-keep class javax.security.sasl.** { *;}

-dontwarn android.support.v4.**
-keep class android.support.v4.** { *;}

-dontwarn com.baidu.**
-keep class com.baidu.** { *;}

-dontwarn cn.jpush.**
-keep class cn.jpush.** { *;}

-dontwarn com.umeng.**
-keep class com.umeng.** { *;}
-dontwarn u.aly.**
-keep class u.aly.** { *;}

-dontwarn com.squareup.**
-keep class com.squareup.** { *;}

-dontwarn org.ksoap2.**
-keep class org.ksoap2.** { *;}
-dontwarn org.kobjects.**
-keep class org.kobjects.** { *;}
-dontwarn org.kxml2.**
-keep class org.kxml2.** { *;}
-dontwarn org.xmlpull.**
-keep class org.xmlpull.** { *;}

-dontwarn com.nostra13.universalimageloader.**
-keep class com.nostra13.universalimageloader.** { *;}

-keep class vi.com.gdi.bgl.** {*;}

-dontwarn com.readystatesoftware.**
-keep class com.readystatesoftware.** { *;}

-dontwarn org.kymjs.**
-keep class org.kymjs.** {*;}

#下面几行 是环信即时通信的代码混淆
-keep class com.easemob.** {*;}
-keep class org.jivesoftware.** {*;}
-keep class org.apache.** {*;}
-dontwarn  com.easemob.**

这是我在项目中使用到的整个代码混淆的内容。

什么是代码混淆

Java 是一种跨平台的、解释型语言,Java 源代码编译成中间”字节码”存储于 class 文件中。由于跨平台的需要,Java 字节码中包括了很多源代码信息,如变量名、方法名,并且通过这些名称来访问变量和方法,这些符号带有许多语义信息,很容易被反编译成 Java 源代码。为了防止这种现象,我们可以使用 Java 混淆器对 Java 字节码进行混淆。

混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英文字母代号,在缺乏相应的函数名和程序注释的况下,即使被反编译,也将难以阅读。同时混淆是不可逆的,在混淆的过程中一些不影响正常运行的信息将永久丢失,这些信息的丢失使程序变得更加难以理解。

混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。由于以上介绍的缩短变量和函数名以及丢失部分信息的原因, 编译后 jar 文件体积大约能减少25% ,这对当前费用较贵的无线网络传输是有一定意义的。

代码混淆的方法

根据 SDK 的版本不同有 2 中不同的代码混淆方式,以上的 proguard.cfg 参数详解中所涉及到的信息是在较低版本 SDK 下的混淆脚本,事实上在高版本的 SDK 下混淆的原理和参数也与低版本的相差无几,只是在不同 SDK 版本的环境下引入混淆脚本的方式有所不同。具体方法如下:

  • 低版本

低版本 SDK 下,项目中同时包含 proguard.cfg 和 project.properties 文件,则只需在 project.properties 文件末尾添加 proguard.config=proguard.cfg 再将项目 Export 即可。
我的项目中的proguard.properties文件内容如下:

# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.

target=android-19
proguard.config=proguard.cfg
android.library=false
  • 高版本

高版本 SDK 下,项目中同时包含 proguard-project.txt 和 project.properties 文件,这时需要在 proguard-project.txt 文件中进行如下信息的配置,然后再将项目 Export 即可。

# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

下面给出代码混淆时候可能遇到的问题:

加入第三方jar包之后常出现的几个异常
proguard returned with error code 1.See console
情况1:
Proguard returned with error code 1. See console
Error: C:/Documents (系统找不到指定文件)
后来发现是因为将整个工程放到了桌面上,而桌面的目录是C:/Documents and Settings/Administrator/桌面,在这里面有空格,而proguard进行发编译的时候是不允许有空格的
如果换了正确路径还不好用的话,直接删除proguard就好了
注意:SDK和程序路径最好不要有空格符

情况2:
Proguard returned with error code 1. See console
异常:
java.lang.ArrayIndexOutOfBoundsException
解决办法:将proguard.cfg中的”-dontpreverify”改成“-dontoptimize”
参考文章:http://groups.google.com/group/android-developers/browse_thread/thread/eca3b0f5ce6ad00f

我把项目中生成的proguard文件夹(此时文件夹是空的)删掉,然后再重新运行项目,就OK 了。

情况3:
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] Proguard returned with error code 1. See console
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] java.io.IOException: Can’t read [proguard.ClassPathEntry@106082] (No such file or directory)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.readInput(InputReader.java:230)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.readInput(InputReader.java:200)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.readInput(InputReader.java:178)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.execute(InputReader.java:100)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.ProGuard.readInput(ProGuard.java:195)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.ProGuard.execute(ProGuard.java:78)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.ProGuard.main(ProGuard.java:499)
抛出这样的异常的原因是第三方jar的引用路径不对,没有找到这个需要忽略混淆的jar包。
参考:http://stackoverflow.com/questions/4884456/android-proguard-java-io-ioexception-cant-read-proguard-classpathentry

情况4:
1,android-support-v4.jar报错的话,要加上下面的代码
-ignorewarnings
-dontwarn android.support.v4.**
-keep class android.support.v4.* { ; }
-keep interface android.support.v4.app.* { ; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.app.Fragment
2,所有的*.jar包都要加上
-libraryjars libs/*.jar
3,混淆代码除了可以更安全还有一个好处是:你的APK文件变得更小,大概为混淆之前的1/2吧。

参考地址:http://www.cnblogs.com/sunzn/archive/2013/03/06/2946952.html
http://blog.csdn.net/fhl13017599952/article/details/24265831

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 这个错误通常是由于在编译时混淆代码所导致的。Android Studio 中可以通过 ProGuard 工具来进行代码混淆,而在最新版本的 Android Studio 中,ProGuard 被 Google 替换为了 R8。 你可以尝试以下几个解决方法: 1. 在 build.gradle 文件中禁用 R8 混淆工具: ```gradle android { ... buildTypes { release { ... minifyEnabled true useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 禁用 R8 android.enableR8=false } } } ``` 2. 如果禁用 R8 无法解决问题,可以尝试更新 Android Gradle 插件和 R8 版本: ```gradle buildscript { ... dependencies { classpath 'com.android.tools.build:gradle:3.5.0' // 更新 Android Gradle 插件版本 } } android { ... buildTypes { release { ... minifyEnabled true useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 使用最新版的 R8 android.enableR8.fullMode=true } } } ``` 3. 如果以上两种方法都无法解决问题,那么可能是代码混淆时出现了一些错误,你需要手动检查混淆规则并进行调整。 ### 回答2: 这个错误表示在Java程序中出现了类型转换错误。具体地说,错误信息中提到的两个类型 `com.android.tools.r8.graph.R0` 和 `com.android.tools.r8.graph.q0` 不兼容,无法进行类型转换。 要解决这个问题,我们可以考虑以下几点: 1. 检查代码逻辑:在程序中检查是否有出现类型转换的地方,并确保进行类型转换时,两个类型是兼容的。 2. 检查依赖库的兼容性:错误中提到的类型可能是由依赖库或框架提供的。我们需要确保使用的依赖库的版本与代码中的类型兼容。如果不兼容,可以尝试更新依赖库的版本,或者寻找适配的库。 3. 检查使用的工具:错误信息中提到了 `com.android.tools.r8`。我们需要确保使用的工具版本与代码中的类型兼容。如果不兼容,可以尝试更新工具的版本,或者尝试使用其他工具。 4. 检查错误栈信息:查看完整的错误栈信息,尝试找到触发错误的具体代码行,这可能会提供更多的线索和解决方向。 在处理此类类型转换错误时,深入了解相关的类和库,并且有针对性地进行排查和修复是非常重要的。如果以上方法都不起作用,可以在开发者社区或论坛中寻求帮助,以获取更详细的指导和解决方案。 ### 回答3: D8: java.lang.ClassCastException: com.android.tools.r8.graph.R0与com.android.tools.r8.graph.q0不兼容。 这个错误表明在使用D8编译器时发生了一个类转换异常。具体来说,代码尝试将"com.android.tools.r8.graph.R0"类转换为"com.android.tools.r8.graph.q0"类,但这两个类是不兼容的。 通常情况下,这可能是由于以下几个原因引起的: 1. 版本不一致:这两个类可能来自不同的版本,其中一个类可能已经被更新或更改了。由于这些更改,它们之间的接口或实现可能已经发生了变化,导致类型转换异常。 2. 类路径问题:在构建或编译过程中,可能发生了一些类路径错误或混淆问题。这可能会导致错误的类被加载或引用,进而导致类型转换异常。 3. 编译器错误:这个错误也有可能是D8编译器本身的一个问题,可能是由于编译器的某些错误或限制而引起的。 要解决这个问题,可以尝试以下几个步骤: 1. 确保使用的库、依赖项或插件的版本是兼容的。检查它们的文档或更新日志,查看是否存在任何版本不一致的问题。 2. 检查类路径和编译选项,确保它们正确设置并排除任何引起混淆的问题。 3. 如果可能的话,升级D8编译器的版本,以获取更好的兼容性和性能。 4. 如果以上步骤都不能解决问题,可能需要调查更深入的原因。可以尝试使用调试器或其他工具来跟踪错误并定位问题所在。 总之,D8: java.lang.ClassCastException: com.android.tools.r8.graph.R0与com.android.tools.r8.graph.q0不兼容,是一个类型转换异常,可能由版本不一致、类路径问题或编译器错误引起。通过检查和修复这些问题,可以解决这个错误。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值