android代码混淆

在一个android项目的发布过程中,需要对代码进行混淆,遇到了不少问题,现在对这些问题和解决方法进行一次总结。

首先代码混淆的方式,根据编译sdk版本的不同,分为两种:

1.低版本sdk下,eclipse项目的工作目录中包含proguard.cfg和project.properties文件,则只需在project.properties文件末尾添加proguard.config=proguard.cfg,在将项目打包成apk,此时代码已完成混淆。

2.高版本的sdk下, eclipse项目的工作目录中包含proguard-project.txt和project.properties文件,这时需要在proguard-project.txt文件中进行如下配置,再将项目导出,即可完成混淆。

# 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=/Volumes/develop/eclispe/sdk/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-17

其中/Volumes/develop/eclispe/sdk/tools 为我的android sdk所在文件夹的绝对目录。


2.编写proguard-project.txt文件:

在混淆时,需要注意的一点是,native方法和一些public方法因为没有在类内部中调用的方法,在混淆后,并没有被编译到apk文件中。然后apk被安装运行后,会抱方法找不到的异常。所以在proguard-project文件里,需要对这种情况进行声明。

保持native方法不被混淆

-keepclasseswithmembernames class * {
    native <methods>;
}

保持view的get ,set方法不被混淆
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

上面的内容可以在 sdk path下的tools/proguard/proguard-android.txt可以找到。

还有就是继承parcelable的类和自定义控件也需要进行声明,保持不被混淆,否则parcelable对象会在传递的过程中出错,自定义控件也会无法编译。

-keep class * implements android.os.Parcelable { 

    public static final android.os.Parcelable$Creator *;

}

-keepclasseswithmembers class * { 

    public <init>(android.content.Context, android.util.AttributeSet);

}

-keepclasseswithmembers class * {

    public <init>(android.content.Context, android.util.AttributeSet,int);

}

下面是一个proguard-property.txt文件的事例说明:

-optimizationpasses 5                                                           # 指定代码的压缩级别
-dontusemixedcaseclassnames                                                     # 是否使用大小写混合
-dontskipnonpubliclibraryclasses                                                # 是否混淆第三方jar
-dontpreverify                                                                  # 混淆时是否做预校验
-verbose                                                                        # 混淆时是否记录日志
-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 * extends android.app.backup.BackupAgentHelper               # 保持哪些类不被混淆
-keep public class * extends android.preference.Preference                      # 保持哪些类不被混淆
-keep public class com.android.vending.licensing.ILicensingService              # 保持哪些类不被混淆

-keepclasseswithmembernames class * {                                           # 保持 native 方法不被混淆
    native <methods>;
}

-keepclasseswithmembers class * {                                               # 保持自定义控件类不被混淆
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);     # 保持自定义控件类不被混淆
}

-keepclassmembers class * extends android.app.Activity {                        # 保持自定义控件类不被混淆
   public void *(android.view.View);
}

-keepclassmembers enum * {                                                      # 保持枚举 enum 类不被混淆
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {                                # 保持 Parcelable 不被混淆
  public static final android.os.Parcelable$Creator *;
}

-keep class MyClass;                                                            # 保持自己定义的类不被混淆

3.第三方jar包的引入:

由于项目中引用了不少第三方的jar包,混淆时需要将这些jar包也混淆进去。否则在导出apk文件时,会报出 类1 can't find referenced class 类2,You may need to specify addtional library jars(using '-libraryjars') 的异常,导致apk无法导出。此时则需要将所引用的jar包加入: -libraryjarslibs/Android_SDK.jar

在引入第三方jar时,可能会出现找不到某个类的引用而无法导出apk的情况。这时可以使用这种方法来解决: -dontwarn android.net.http.**


4.混淆成功

混淆成功后,在eclipse的proguard文件夹里,会出现这4个文件:

dump.txt – 描述.apk文件中所有类文件间的内部结构
mapping.txt – 列出了原始的类,方法和字段名与混淆后代码间的映射。这个文件很重要,当你从release版本中收到一个bug报告时,可以用它来翻译被混淆的代码。
seeds.txt – 列出了未被混淆的类和成员
usage.txt – 列出了从.apk中删除的代码

应用发布时,记得保存这些文件,因为下一次版本更新,这些文件会被覆盖掉,mappig里面字段的名字也会改变,这样你再进行bug修复时,找不到对应的类,那就悲剧了。

混淆成功,得到apk后,记得将apk安装在真机上跑跑,确保无错误后再进行发布。


引用资料:http://my.eoe.cn/eric_wu/archive/4358.html 点击打开链接

                    http://proguard.sourceforge.net/index.html#点击打开链接









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值