Android 打包混淆

proguard原理:

       

缺省情况下,proguard 会混淆所有代码,但是下面几种情况是不能改变java 元素的名称,否则就会这样就会导致程序出错。

 

一, 我们用到反射的地方。

二, 我们代码依赖于系统的接口,比如被系统代码调用的回调方法,这种情况最复杂。

三, 是我们的java 元素名称是在配置文件中配置好的。

所以使用proguard时,我们需要有个配置文件告诉proguard 那些java 元素是不能混淆的。

 

       在旧版的ADT创建项目是 混淆文件是proguard.cfg。需要在project.properties中加入  proguard.config=proguard.cfg。

 

        在新版本的ADT创建项目时,混码的文件不再是proguard.cfg,而是project.properties和proguard-project.txt。

如果需要对项目进行全局混码,只需要进行一步操作:

将project.properties的中

“#  proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt”的“#”去掉就可以了。

 

 

proguard 配置

 

最常用的配置选项

-dontwarn 缺省proguard 会检查每一个引用是否正确,但是第三方库里面往往有些不会用到的类,没有正确引用。如果不配置的话,系统就会报错。

-keep 指定的类和类成员被保留作为 入口 。

-keepclassmembers 指定的类成员被保留。

-keepclasseswithmembers 指定的类和类成员被保留,假如指定的类成员存在的话。

 

proguard 问题和风险

 

代码混淆后虽然有混淆优化的好处,但是它往往也会带来如下的几点问题

1,混淆错误,用到第三方库的时候,必须告诉 proguard 不要检查,否则proguard 会报错。

2,运行错误,当code 不能混淆的时候,我们必须要正确配置,否则程序会运行出错,这种情况问题最多。

3,调试苦难,出错了,错误堆栈是混淆后的代码 ,自己也看不懂。

 

为了防止混淆出问题,你需要熟悉你所有的code ,系统的架构 ,以及系统和你code的集成的接口,并细心分析。 同时你必须需要一轮全面的测试。 所以混淆也还是有一定风险的。

 为了避免风险,你可以只是混淆部分关键的代码,但是这样你的混淆的效果也会有所降低。

 

常见的不能混淆的androidCode

Android 程序 ,下面这样代码混淆的时候要注意保留。

Android系统组件,系统组件有固定的方法被系统调用。

被Android Resource 文件引用到的。名字已经固定,也不能混淆,比如自定义的View 。

Android Parcelable ,需要使用android 序列化的。

其他Anroid 官方建议 不混淆的,如

android.app.backup.BackupAgentHelper

android.preference.Preference

com.android.vending.licensing.ILicensingService

Java序列化方法,系统序列化需要固定的方法。

枚举 ,系统需要处理枚举的固定方法。

本地方法,不能修改本地方法名

annotations 注释

数据库驱动

有些resource 文件

用到反射的地方

 

 

然而,现在的系统已经配置在混淆代码的时候会保留如下的代码不混淆

1、Android系统组件

2、自定义View

3、Android Parcelable

4、Android R 文件

5、Android Parcelable

6、枚举

 

开发人员必须检查自己的code 是否用到反射 ,和其他不能混淆的地方。告诉我来修改配置文件(已经保留的就不需要了)

 

 

proguard 参数

 

-include {filename}    从给定的文件中读取配置参数 

 

-basedirectory {directoryname}    指定基础目录为以后相对的档案名称 

 

-injars {class_path}    指定要处理的应用程序jar,war,ear和目录 

 

-outjars {class_path}    指定处理完后要输出的jar,war,ear和目录的名称 

 

-libraryjars {classpath}    指定要处理的应用程序jar,war,ear和目录所需要的程序库文件 

 

-dontskipnonpubliclibraryclasses    指定不去忽略非公共的库类。 

 

-dontskipnonpubliclibraryclassmembers    指定不去忽略包可见的库类的成员。 

 

 

保留选项 

-keep {Modifier} {class_specification}    保护指定的类文件和类的成员 

 

-keepclassmembers {modifier} {class_specification}    保护指定类的成员,如果此类受到保护他们会保护的更好

 

-keepclasseswithmembers {class_specification}    保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。 

 

-keepnames {class_specification}    保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除) 

 

-keepclassmembernames {class_specification}    保护指定的类的成员的名称(如果他们不会压缩步骤中删除) 

 

-keepclasseswithmembernames {class_specification}    保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后) 

 

-printseeds {filename}    列出类和类的成员-keep选项的清单,标准输出到给定的文件 

 

压缩 

-dontshrink    不压缩输入的类文件 

 

-printusage {filename} 

 

-whyareyoukeeping {class_specification}     

 

优化 

-dontoptimize    不优化输入的类文件 

 

-assumenosideeffects {class_specification}    优化时假设指定的方法,没有任何副作用 

 

-allowaccessmodification    优化时允许访问并修改有修饰符的类和类的成员 

 

混淆 

-dontobfuscate    不混淆输入的类文件 

 

-printmapping {filename} 

 

-applymapping {filename}    重用映射增加混淆 

 

-obfuscationdictionary {filename}    使用给定文件中的关键字作为要混淆方法的名称 

 

-overloadaggressively    混淆时应用侵入式重载 

 

-useuniqueclassmembernames    确定统一的混淆类的成员名称来增加混淆 

 

-flattenpackagehierarchy {package_name}    重新包装所有重命名的包并放在给定的单一包中 

 

-repackageclass {package_name}    重新包装所有重命名的类文件中放在给定的单一包中 

 

-dontusemixedcaseclassnames    混淆时不会产生形形色色的类名 

 

-keepattributes {attribute_name,...}    保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses. 

 

-renamesourcefileattribute {string}    设置源文件中给定的字符串常量

 

 

 

 

示例:

 

 

# 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 *;

#}

 

#-libraryjars 'C:\Program Files (x86)\Java\jdk1.7.0_21\jre\lib\rt.jar'

 

-optimizationpasses 5

##混淆时不会产生形形色色的类名

-dontusemixedcaseclassnames

##指定不去忽略非公共的库类。

-dontskipnonpubliclibraryclasses

##指定不去忽略包可见的库类的成员

-dontskipnonpubliclibraryclassmembers

##不预校验

-dontpreverify

 

-verbose

-dump class_files.txt

-printseeds seeds.txt

-printusage unused.txt

-printmapping mapping.txt

 

##优化

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-allowaccessmodification

 

##保持annotation注释属性,泛型中常用

-keepattributes *Annotation*

-renamesourcefileattribute SourceFile

 

##保持SourceFile/LineNumberTable属性

-keepattributes SourceFile,LineNumberTable

-repackageclasses ''

 

##继承之下面的类不进行混淆保持原样

-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

-dontnote com.android.vending.licensing.ILicensingService

-keep public class com.linker.json.Bean2JsonUtils

-dontnote com.linker.json.Bean2JsonUtils

-keep public class com.linker.bean.ClientRegisterBean

-dontnote com.linker.bean.ClientRegisterBean

-keep public class com.linker.bean.RegisterData

-dontnote com.linker.bean.RegisterData

 

##保留指定包下面的内容不混淆

 

##---------------iflytek配置  Begin: proguard configuration for iflytek  ----------

 

-libraryjars /libs/SpeechApi.jar

-dontwarn com.iflytek.speech.**

-keepattributes Signature

-keep class com.iflytek.speech.**{*;}

 

##---------------iflytek配置  End: proguard configuration for iflytek  ----------

 

 

 

#保持参数签名不被混淆

-keepattributes Signature

-keep class com.jdsy.gdt.ui.entity.** { *;}  

-keep class com.jdsy.core.entity.** { *;} 

 

 

-libraryjars /libs/android-support-v4.jar

-dontwarn android.support.v4.**

-keepattributes Signature

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

 

 

-libraryjars /libs/universal-image-loader-1.9.1.jar

-dontwarn com.nostra13.universalimageloader.**

-keepattributes Signature

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

 

-libraryjars /libs/commons-net-3.3.jar

-dontwarn org.apache.commons.net.**

-keepattributes Signature

-keep public class org.apache.commons.net.**{ *; }

 

-libraryjars /libs/httpmime-4.2.1.jar

-dontwarn org.apache.http.entity.mime.**

-keepattributes Signature

-keep public class org.apache.http.entity.mime.**{ *; }

 

-dontwarn com.handmark.pulltorefresh.**

-keepattributes Signature

-keep public class com.handmark.pulltorefresh.**{ *; }

 

-dontwarn com.linker.install.**

-keepattributes Signature

-keep public class com.linker.install.**{ *; }

 

-dontwarn com.linker.bean.**

-keepattributes Signature

-keep public class com.linker.bean.**{ *; }

 

 

##---------------GSON配置 Begin: proguard configuration for Gson  ----------

 

# Gson uses generic type information stored in a class file when working with fields. Proguard

# removes such information by default, so configure it to keep all of it.

 

-libraryjars /libs/gson-2.2.4.jar

-dontwarn com.google.gson.**

-keep public class com.google.gson.**{ *; }

 

# Explicitly preserve all serialization members. The Serializable interface

# is only a marker interface, so it wouldn't save them.

-keepclassmembers class * implements java.io.Serializable {

    static final long serialVersionUID;

    private static final java.io.ObjectStreamField[] serialPersistentFields;

    private void writeObject(java.io.ObjectOutputStream);

    private void readObject(java.io.ObjectInputStream);

    java.lang.Object writeReplace();

    java.lang.Object readResolve();

    public <fields>;

}

 

-keepattributes Signature

 

# Gson specific classes

-keep class sun.misc.Unsafe { *; }

#-keep class com.google.gson.stream.** { *; }

 

# Application classes that will be serialized/deserialized over Gson

-keep class com.google.gson.examples.android.model.** { *; }

 

##---------------End: proguard configuration for Gson  ----------

 

 

 

# 序列化Explicitly preserve all serialization members. The Serializable interface

# is only a marker interface, so it wouldn't save them.

 

-keepclassmembers class * implements java.io.Serializable {

    static final long serialVersionUID;

    private static final java.io.ObjectStreamField[] serialPersistentFields;

    private void writeObject(java.io.ObjectOutputStream);

    private void readObject(java.io.ObjectInputStream);

    java.lang.Object writeReplace();

    java.lang.Object readResolve();

}

 

 

#Native方法 Preserve all native method names and the names of their classes.

-keepclasseswithmembers class * {

    native <methods>;

}

 

-keepclasseswithmembers class * {

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

}

 

-keepclasseswithmembers class * {

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

}

 

# 内部类 Preserve static fields of inner classes of R classes that might be accessed

# through introspection.

-keepclassmembers class **.R$* {

  public static <fields>;

}

 

# 枚举Preserve the special static methods that are required in all enumeration classes.

-keepclassmembers enum * {

    public static **[] values();

    public static ** valueOf(java.lang.String);

}

 

-keep public class * {

    public protected *;

}

 

 

##Parcelable子类

-keep class * implements android.os.Parcelable {

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

}

 

##---------------End: proguard configuration common for all Android apps ----------

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值