Android优雅的进行混淆——使用@Keep注解 重要

http://www.jianshu.com/p/be7ec1819d2f

http://www.jianshu.com/p/be7ec1819d2f

http://www.jianshu.com/p/be7ec1819d2f

http://www.jianshu.com/p/be7ec1819d2f



 
 

不能混淆的项

<pre class="hljs undefined" data-original-code="" 在androidmanifest中配置的类,比如四大组件"="" data-snippet-id="ext.4c8dd53355a8d1beda633d1900397448" data-snippet-saved="false" data-codota-status="done"> 在AndroidManifest中配置的类,比如四大组件 JNI调用的方法 反射用到的类 WebView中JavaScript调用的方法 Layout文件引用到的自定义View 一些引入的第三方库

使用工具AndroidStudio

release {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}

使用proguard混淆代码是对产品本身的一种保护,常见的方法就是编写projuard-rules.pro配置文件

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html

//混淆时不使用大小写混合类名
-dontusemixedcaseclassnames
//不跳过library中的非public的类
-dontskipnonpubliclibraryclasses
//打印混淆的详细信息
-verbose
 
# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
//不进行优化,建议使用此选项,理由见上
-dontoptimize
//不进行预校验,预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.
 
//保留注解参数
-keepattributes *Annotation*
//保留Google原生服务需要的类
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
 
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
//保留native方法的类名和方法名
-keepclasseswithmembernames class * {
    native <methods>;
}
 
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
//保留自定义View,如"属性动画"中的set/get方法
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}
 
# We want to keep methods in Activity that could be used in the XML attribute onClick
//保留Activity中参数是View的方法,如XML中配置android:onClick=”buttonClick”属性,Activity中调用的buttonClick(View view)方法
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}
 
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
//保留混淆枚举中的values()和valueOf()方法
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
 
//Parcelable实现类中的CREATOR字段是绝对不能改变的,包括大小写
-keepclassmembers class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator CREATOR;
}
 
//R文件中的所有记录资源id的静态字段
-keepclassmembers class **.R$* {
    public static <fields>;
}
 
# The support library contains references to newer platform versions.
# Dont warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.
//忽略support包因为版本兼容产生的警告
-dontwarn android.support.**

Proguard关键字

关键字                      描述
keep                        保留类和类中的成员,防止被混淆或移除
keepnames                   保留类和类中的成员,防止被混淆,成员没有被引用会被移除
keepclassmembers            只保留类中的成员,防止被混淆或移除
keepclassmembernames        只保留类中的成员,防止被混淆,成员没有引用会被移除
keepclasseswithmembers      保留类和类中的成员,防止被混淆或移除,保留指明的成员
keepclasseswithmembernames  保留类和类中的成员,防止被混淆,保留指明的成员,成员没有引用会被移除

Proguard通配符

通配符      描述
<field>     匹配类中的所有字段
<method>    匹配类中所有的方法
<init>      匹配类中所有的构造函数
*           匹配任意长度字符,不包含包名分隔符(.)
**          匹配任意长度字符,包含包名分隔符(.)
***         匹配任意参数类型
...

指定混淆时可使用字典

-applymapping filename 指定重用一个已经写好了的map文件作为新旧元素名的映射。
-obfuscationdictionary filename 指定一个文本文件用来生成混淆后的名字。
-classobfuscationdictionary filename 指定一个混淆类名的字典
-packageobfuscationdictionary filename 指定一个混淆包名的字典
-overloadaggressively 混淆的时候大量使用重载,多个方法名使用同一个混淆名(慎用)

    # 这里巧妙地使用java中的关键字作字典,混淆之后的代码更加不利于阅读
    #
    # This obfuscation dictionary contains reserved Java keywords. They can't
    # be used in Java source files, but they can be used in compiled class files.
    # Note that this hardly improves the obfuscation. Decent decompilers can
    # automatically replace reserved keywords, and the effect can fairly simply be
    # undone by obfuscating again with simpler names.
    # Usage:
    #     java -jar proguard.jar ..... -obfuscationdictionary keywords.txt
    #
    
    do
    if
    for
    int
    new
    try
    byte
    case
    char
    else
    goto
    long
    this
    void
    break
    catch
    class
    const
    final
    float
    short
    super
    throw
    while
    double
    import
    native
    public
    return
    static
    switch
    throws
    boolean
    default
    extends
    finally
    package
    private
    abstract
    continue
    strictfp
    volatile
    interface
    protected
    transient
    implements
    instanceof
    synchronized






使用proguardgui对jar包进行混淆

proguardgui工具支持Shrinking(压缩)、Optimization(优化)、Obfuscation(混淆)、Preverification(预校验)四项操作

详细步骤:
    1 Load configuration --> Next
    2 Add input/Add output
    3 添加jar包依赖
        JAVA_HOME/jre/lib/rt.jar
        Android_SDK/platfroms/android-23/android.jar
        AndroidStudioProjects/ProjectName/app/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.4.0/jars/classes.jar
        AndroidStudioProjects/ProjectName/app/build/intermediates/exploded-aar/com.android.support/support-v4/23.4.0/jars/classes.jar
        AndroidStudioProjects/ProjectName/app/build/intermediates/exploded-aar/com.android.support/support-v4/23.4.0/jars/libs/internal_impl-23.4.0.jar
        其他第三方jar文件
    4 Don`t use Shrink --> Next
    5 Add --> Extends/implements class --> android.app.Activity --> ok --> Next
    6 Next
    7 Next
    8 View configuration
tips:
    AndroidStudio中生成jar文件方法:
    jar -cvf filename.jar -C app/build/intermediates/classes/debug

5分钟快速混淆






#-------------------------------------------定制化区域----------------------------------------------
#---------------------------------1.实体类---------------------------------

-keep class com.demo.login.bean.** { *; }
-keep class com.demo.main.bean.** { *; }

#-------------------------------------------------------------------------

#---------------------------------2.第三方包-------------------------------

#eventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

#glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

#log4j
-libraryjars log4j-1.2.17.jar
-dontwarn org.apache.log4j.**
-keep class  org.apache.log4j.** { *;}

#-------------------------------------------------------------------------

#---------------------------------3.与js互相调用的类------------------------

-keepclasseswithmembers class com.demo.login.bean.ui.MainActivity$JSInterface { 
      <methods>; 
}

#-------------------------------------------------------------------------

#---------------------------------4.反射相关的类和方法-----------------------
# 有
#----------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------

#-------------------------------------------基本不用动区域--------------------------------------------
#---------------------------------基本指令区----------------------------------
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
#----------------------------------------------------------------------------

#---------------------------------默认保留区---------------------------------
-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 * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}

-keepclasseswithmembernames class * {
    native <methods>;
}
-keepclassmembers class * extends android.app.Activity{
    public void *(android.view.View);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep public class * extends android.view.View{
    *** get*();
    void set*(***);
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
-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 class **.R$* {
 *;
}
-keepclassmembers class * {
    void *(**On*Event);
}
#----------------------------------------------------------------------------

#---------------------------------webview------------------------------------
-keepclassmembers class fqcn.of.javascript.interface.for.Webview {
   public *;
}
-keepclassmembers class * extends android.webkit.WebViewClient {
    public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
    public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.WebViewClient {
    public void *(android.webkit.WebView, jav.lang.String);
}
#----------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------

# 删除代码中Log相关的代码
-assumenosideeffects class android.util.Log {
    public static boolean isLoggable(java.lang.String, int);
    public static int v(...);
    public static int i(...);
    public static int w(...);
    public static int d(...);
    public static int e(...);
}

网上有很多5分钟完成混淆规则的教程,但如何更优雅的完成这一枯燥的过程,即使用@Keep注解,使混淆变得轻松愉快

在proguard-rules.pro配置文件中加入以下规则

#手动启用support keep注解
#http://tools.android.com/tech-docs/support-annotations
-dontskipnonpubliclibraryclassmembers
-printconfiguration
-keep,allowobfuscation @interface android.support.annotation.Keep

-keep @android.support.annotation.Keep class *
-keepclassmembers class * {
    @android.support.annotation.Keep *;
}

哪里不对@Keep哪里,妈妈再也不用担心我不会混淆啦……

参考资料
http://blog.csdn.net/guolin_blog/article/details/50451259
http://www.jianshu.com/p/60e82aafcfd0



作者:Ziv_紫藤花开
链接:http://www.jianshu.com/p/be7ec1819d2f
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值