Android混淆(包括混淆四大组件)

本文介绍了Android应用中使用ProGuard进行代码混淆的概念和好处,包括增加反编译难度、优化代码体积和性能。文章详细展示了混淆前后代码的差异,并提供了基本的混淆规则和常用的配置示例。同时,提到了自定义混淆字典的方法以及混淆四大组件的特殊处理。文章还强调了混淆时需要注意的事项,如保留特定类和方法不被混淆,以防止程序出错。附带了一个Demo链接供读者实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ps:这篇文章主要是自己对混淆的理解

目录

概念:

使用:

基本的混淆规则:

常用的混淆规则:

自定义混淆规则:

混淆四大组件:

注意事项:

Demo地址:


概念:

简单的来说就是将源代码变成难以看懂的,如果不想app上架之后被人反编译拿到源代码直接CV的话建议看一看,哈哈

  • 好处:

        增加反编译只会源代码的阅读难度

        自动优化代码 用以减小应用体积,移除未被使用的类和成员

        在字节码级别执行优化,让应用运行的更快。

废话不多说,对比两张图片比较一下:

混淆之前:

混淆之后 :

从这两张图的对比很容易发现,这里的很多包名以及类名都被混淆了,还有代码的优化 

使用:

在Android主工程build.gradle添加代码

android{
 buildTypes {

        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }

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

这样就可以了,是不是很简单呢 

minifyEnabled 就是混淆的开关
在对应的模块当中会有proguard-rules.pro文件,如果需要自己定制混淆规则,可以在这个文件当中去更改

基本的混淆规则:

偷懒扔个链接:

混淆规则参考

常用的混淆规则:

懒人可以直接CV大法到项目当中使用

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#
# Starting with version 2.2 of the Android plugin for Gradle, this file is distributed together with
# the plugin and unpacked at build-time. The files in $ANDROID_HOME are no longer maintained and
# will be ignored by new version of the Android plugin for Gradle.

# Optimizations can be turned on and off in the 'postProcessing' DSL block.
# The configuration below is applied if optimizations are enabled.
# Adding optimization introduces certain risks, since for example not all optimizations performed by
# ProGuard works on all versions of Dalvik.  The following flags turn off various optimizations
# known to have issues, but the list may not be complete or up to date. (The "arithmetic"
# optimization can be used if you are only targeting Android 2.0 or later.)  Make sure you test
# thoroughly if you go this route.
# --------------------------------------------基本指令区-------------------------------------------# 指定代码的压缩级别(在0~7之间,默认为5)
-optimizationpasses 5
# 是否使用大小写混合(windows大小写不敏感,建议加入)
-dontusemixedcaseclassnames
 # 是否混淆非公共的库的类
-dontskipnonpubliclibraryclasses
# 是否混淆非公共的库的类的成员
-dontskipnonpubliclibraryclassmembers
# 混淆时是否做预校验(Android不需要预校验,去掉可以加快混淆速度)
# 混淆时是否记录日志(混淆后会生成映射文件)
-verbose


# 混淆时所采用的算法(谷歌推荐算法)
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable
-useuniqueclassmembernames
-allowaccessmodification
# 将文件来源重命名为“SourceFile”字符串
-renamesourcefileattribute SBFile

# 保持注解不被混淆
-keepattributes *Annotation*
-keep class * extends java.lang.annotation.Annotation {*;}

# 保持泛型不被混淆
-keepattributes Signature
# 保持反射不被混淆
-keepattributes EnclosingMethod
# 保持异常不被混淆
-keepattributes Exceptions
# 保持内部类不被混淆
-keepattributes Exceptions,InnerClasses
# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable

# --------------------------------------------默认保留区--------------------------------------------#
# 保持基本组件不被混淆
-keep public class * extends android.app.Fragment
-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


# Support包规则
-dontwarn android.support.**
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**

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

# 保留自定义控件(继承自View)不被混淆
-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);
}

# 保留在Activity中的方法参数是view的方法(避免布局文件里面onClick被影响)
-keepclassmembers class * extends android.app.Activity {
    public void *(android.view.View);
}

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

# 保持R(资源)下的所有类及其方法不能被混淆
-keep class **.R$* { *; }

# 保持 Parcelable 序列化的类不被混淆(注:aidl文件不能去混淆)
-keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}

# 需要序列化和反序列化的类不能被混淆(注:Java反射用到的类也不能被混淆)
-keepnames class * implements java.io.Serializable

# 保持 Serializable 序列化的类成员不被混淆
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    !private <fields>;
    !private <methods>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

# 保持 BaseAdapter 类不被混淆
-keep public class * extends android.widget.BaseAdapter { *; }

# --------------------------------------------webView区--------------------------------------------#
# WebView处理,项目中没有使用到webView忽略即可
# 保持Android与JavaScript进行交互的类不被混淆
-keep class **.AndroidJavaScript { *; }
-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.WebChromeClient {
     public void *(android.webkit.WebView,java.lang.String);
}

# 网络请求相关
-keep public class android.net.http.SslError



################retrofit###############
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions

################butterknife###############
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
   @butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
 @butterknife.* <methods>;
}

################gson###############
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.sunloto.shandong.bean.** { *; }


################okhttp###############
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn com.squareup.okhttp.**

-keep class com.facebook.** { *; }

################autolayout###############
-keep class com.zhy.autolayout.** { *; }
-keep interface com.zhy.autolayout.** { *; }

################RxJava and RxAndroid###############
-dontwarn org.mockito.**
-dontwarn org.junit.**
-dontwarn org.robolectric.**

-keep class io.reactivex.** { *; }
-keep interface io.reactivex.** { *; }

-keepattributes Signature
-keepattributes *Annotation*
-keep class com.squareup.okhttp.** { *; }
-dontwarn okio.**
-keep interface com.squareup.okhttp.** { *; }
-dontwarn com.squareup.okhttp.**

-dontwarn io.reactivex.**
-dontwarn retrofit.**
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
    @retrofit.http.* <methods>;
}


-dontwarn java.lang.invoke.*


-keepclassmembers class io.reactivex.internal.util.unsafe.*ArrayQueue*Field* {
    long producerIndex;
    long consumerIndex;
}

自定义混淆规则:

从最开始的两张图片可以看到混淆后的名字都是a,b,c之类的,但是如果想自定义这么处理,这个也很简单需要在proguard-rules.pro文件当中加入

#指定外部模糊字典
-obfuscationdictionary filename.txt
#指定class模糊字典
-classobfuscationdictionary filename.txt
#指定package模糊字典
-packageobfuscationdictionary filename.txt

filename.txt文件我放在了demo当中,位置在..app/filename.txt,直接copy下来就可以,

当然如果想要自己控制filename.txt内容请按照以下步骤:

  1. 下载demo
  2. 将proguardcreater包拷贝到自己的工程,或者再接在demo当中运行Main类当中的main方法(记得自己更改规则)(ps:可以是中文哈哈哈,玩一玩就好,因为打印出来的日志无法通过mapping去查看)
  3. 将生成好的文件拷贝到自己的项目当中即可

通过自定义混淆字典生成的apk目录:

 可以看到已经变成了我自己定义的规则,由0,o,O组成的包名,当然类名和方法是一样的

混淆四大组件:

有点小基础的都应该知道,一般情况下是不允许混淆四大组件的,会导致程序找不到组件报错,但是这里的混淆四大组件是通过增量混淆来实现的,无意间逛GitHub的时候发现一个大佬写的开源项目,由此记录一下。

GitHub地址:点我 GGG~~

注意事项:

有些类是不能被混淆的,特此记录:

  • 使用了自定义View要保证不能被混淆
  • 使用了枚举要保证枚举不被混淆
  • 对第三方库中的类不进行混淆
  • 运用了反射的类也不进行混淆
  • 使用了 Gson 之类的工具要使 JavaBean 类即实体类不被混淆
  • 在引用第三方库的时候,一般会标明库的混淆规则的,建议在使用的时候就把混淆规则添加上去,免得到最后才去找
  • 有用到 WebView 的 JS 调用也需要保证写的接口方法不混淆,原因和第一条一样
  • Parcelable 的子类和 Creator 静态成员变量不混淆,否则会产生 Android.os.BadParcelableException 异常
  • 使用的四大组件,自定义的Application* 实体类
  • JNI中调用的类
  • Layout布局使用的View构造函数(自定义控件)、android:onClick等。

Demo地址:

点我 GO~https://gitee.com/li-weihao1010/text-proguard


 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值