您的位置:首页 > 移动开发 > Android开发

关于Android应用代码混淆的一次折腾

2015-03-02 22:32 204 查看
先谈一下这次折腾的一些感想: 对一块不熟悉的地方的探索,时间最好安排在早上,因为那时最有耐性,而不易半途而废。

对于Android应用代码保护,一般有两种方式: 一是借助第三方加密,这种方式不需要什么技术,等着就行了;二是使用谷歌提供的代码混淆工具proguard。两种方式各优缺点,前者,须借助他人,还须等待,但是省事。后者步骤繁琐,错误情况百出,但是更靠谱。

话归正题,我把代码混淆分成两部分:编译成功前+编译成功后;

编译成功前

找到我们项目根目录下的project.properties,里面有这样一句代码:

[code]    #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt


把前面的#去掉,这是告诉编辑器,在项目导出(export)时,要对代码进行混淆了,混淆需要的配置信息保存在项目根目录下的proguard-project.txt里;好了project.properties就不用再管它了。

项目中需要做特殊处理的,有这样几种:引入第三方jar包,引用的第三方的库,特殊的类和包;

如果你现在开始导出项目(需要等个几分钟,不清楚是不是特例),可能会报错(proguard-project.txt如果为空的话,不会报错,ye也不会混淆),只要有报错信息,就好办,剩下就是百度了;补充一句如果编译期间eclipse占用大量内存,如果eclipse挂掉了,改一下eclipse.ini配置信息就好了,具体不在此详述。

好了,开始一步步解决问题;打开proguard-project.txt,只有几行注释掉得文字,不妨读一下。

以我这次的项目为例,一般项目都有support V4包

在proguard-project.txt

[code]-dontwarn android.support.v4.** //对于v4中找不到相应的类和方法,在编译时不警告
    -keep class android.support.v4.** { *; } //对于v4中的类不进行代码混淆
    -keep interface android.support.v4.app.** { *; } //对于v4中的接口不进行代码混淆


导出一次,报错了:

[code]Warning: com.baidu.location.au: can't find referenced method 'boolean isScanAlwaysAvailable()' in library class android.net.wifi.WifiManager


项目中用到了百度定位,百度了一下,原来百度定位的jar包,已经混淆过了,所以不用再混淆了,加上:

-dontwarn com.baidu.location.**     //所有类 

 -keep class com.baidu.location.** {  //不混淆百度定位中的代码 一般-dontwarn和 -keep 

  *;       //该类中的所有方法 

}


注意:-libraryjars libs/android-support-v4.jar 在以前可能要将上这句,用户找到jar包中类的位置,随着proguard的升级,默认给加上了,所以省了。

再次导出一下,上面那个错误,哈哈,不在了。

go on!

后来错误中有jpush字样,我知道是极光推送的问题了;

[code]-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontnote
-verbose
-dontwarn cn.jpush.android.**
-keep class cn.jpush.android.** {*;}


跑起来,靠,又报错了,还是jpush,我都加上了啊,百度中… 最后发现极光推送代码混淆,需要proguard4.x以上,拷贝了一份新的,覆盖到sdk中,问题解决。

然后是afinal框架

[code]#afinal
-dontwarn net.tsz.afinal.**
-keep class net.tsz.afinal.** { *; }
-keep public class * extends net.tsz.afinal.** 
-keep public interface net.tsz.afinal.** {*;}

-keepattributes Signature
-keepattributes *Annotation*

-keepclasseswithmembers class com.xxx.xxx.**{  //自己对afinal封装的工具类
     <fields>;
     <methods>;
}


继续

其他引用的jar包,或可从百度,帮助文档中得知,再次不在赘述。

该吃饭了,在导出一次,哎呀,终于他母亲的看见apk了。

编译后

说好了分成两部分的,安装到手机上,跑跑,卡,崩了。

只能去看logcat,找问题了;

嗯,gson的问题

[code]##---------------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.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# 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.xx.xxx.bean.** { *; }//特别注意 所有实体类所在的包

# 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();
}

-keep public class * implements java.io.Serializable {*;}

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


再继续

嗯,是LogUtil.i()方法出问题了,管他是什么原因,注释掉再说

Ok 测试一遍,功能正常,反编译一下,还不错。

未完待续……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: