zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

【我的Android进阶之旅】Android 混淆文件资源分类整理

Android文件资源 之旅 进阶 混淆
2023-09-27 14:29:23 时间
之前将所有的混淆都配置在一个 proguard-rules.pro 这个Android Studio新建项目时自动生成的文件里面,而随着项目功能迭代越来越多,代码量越来越多,引用的第二方库、第三方库都越来越多,导致proguard-rules.pro 越来越臃肿,而且随着开发人员增多导致proguard-rules.pro 文件里面的配置越来越混乱。

之前将所有的混淆都配置在一个 proguard-rules.pro 这个Android Studio新建项目时自动生成的文件里面,而随着项目功能迭代越来越多,代码量越来越多,引用的第二方库、第三方库都越来越多,导致proguard-rules.pro 越来越臃肿,而且随着开发人员增多导致proguard-rules.pro 文件里面的配置越来越混乱。

一、拆分proguard-rules.pro混淆文件

因此今天我将proguard-rules.pro混淆文件进行拆分整理,大概拆分为以下4个文件:第三方混淆文件、第二份混淆文件、系统默认混淆文件、module单独混淆文件 。

这里写图片描述

如上图所示,四个文件分别为 proguard-system-common.pro, proguard-module.pro, proguard-second-party.pro, proguard-third-party.pro

二、配置混淆时候 proguardFiles 所引用的混淆文件

原来的混淆文件配置代码如下:

//混淆文件

proguardFiles getDefaultProguardFile(proguard-android.txt), proguard-rules.pro,

改为下面的将四个混淆文件都加入到混淆配置文件列表中

 //混淆文件

 proguardFiles getDefaultProguardFile(proguard-android.txt), proguard-system-common.pro, proguard-module.pro, proguard-second-party.pro, proguard-third-party.pro

如下图所示:

这里写图片描述

三、四个拆分的混淆文件具体代码 proguard-system-common.pro

proguard-system-common.pro 是Android系统通用的一些混淆配置,配置的内容大致如下:

# 指定代码的压缩级别

-optimizationpasses 5

-ignorewarnings # 抑制警告

-verbose # 混淆时是否记录日志(混淆后生产映射文件 map 类名 - 转化后类名的映射

-dontpreverify # 不预校验

-dontoptimize #不优化输入的类文件

-dontshrink #该选项 表示 不启用压缩 混淆时是否做预校验(可去掉加快混淆速度)

-dontusemixedcaseclassnames # 混淆时不会产生形形色色的类名 是否使用大小写混合

-dontskipnonpubliclibraryclasses #不跳过(混淆) jars中的 非public classes 默认选项

-keepattributes Exceptions # 解决AGPBI警告

-keepattributes Exceptions,InnerClasses,...

-keepattributes EnclosingMethod

-keepattributes SourceFile,LineNumberTable #运行抛出异常时保留代码行号

#过滤泛型

-keepattributes Signature

#过滤注解

-keepattributes *Annotation*

-keep class * extends java.lang.annotation.Annotation { *; }

-keep interface * extends java.lang.annotation.Annotation { *; }


#继承自activity,application,service,broadcastReceiver,contentprovider....不进行混淆 -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 -keep public class * extends android.support.v4.** -keep public class com.android.vending.licensing.ILicensingService -keep public class * extends android.support.multidex.MultiDexApplication -keep public class * extends android.view.View -keep class android.support.** {*;} # keep setters in Views so that animations can still work. # see http://proguard.sourceforge.net/manual/examples.html#beans -keepclassmembers public class * extends android.view.View { void set*(***); *** get*(); # 所有View的子类及其子类的get、set方法都不进行混淆 -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); #保持指定规则的方法不被混淆(Android layout 布局文件中为控件配置的onClick方法不能混淆) -keepclassmembers class * extends android.app.Activity { public void *(android.view.View); # 对于带有回调函数onXXEvent的,不能被混淆 -keepclassmembers class * { void *(*Event); #保持R文件不被混淆,否则,你的反射是获取不到资源id的 -keep class **.R$* { *; } # 不混淆R类里及其所有内部static类中的所有static变量字段,$是用来分割内嵌类与其母体的标志 -keep public class **.R$*{ public static final int *; -keepclassmembers class **.R$* { public static fields #过滤js -keepattributes *JavascriptInterface* #保护WebView对HTML页面的API不被混淆 -keep class **.Webview2JsInterface { *; } -keepclassmembers class * extends android.webkit.WebViewClient { #如果你的项目中用到了webview的复杂操作 ,最好加入 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 { #如果你的项目中用到了webview的复杂操作 ,最好加入 public void *(android.webkit.WebView,java.lang.String); #对WebView的简单说明下:经过实战检验,做腾讯QQ登录,如果引用他们提供的jar,若不加防止WebChromeClient混淆的代码,oauth认证无法回调, #反编译基代码后可看到他们有用到WebChromeClient,加入此代码即可。 -keepclasseswithmembers class * { public init (android.content.Context, android.util.AttributeSet); #保持自定义控件类不被混淆,指定格式的构造方法不去混淆 -keepclasseswithmembers class * { public init (android.content.Context, android.util.AttributeSet, int);
-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; #-keep public class * { # public protected *; #需要序列化和反序列化的类不能被混淆(注:Java反射用到的类也不能被混淆) -keep public class * implements java.io.Serializable { public *; #不混淆Serializable接口的子类中指定的某些成员变量和方法 -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; !static !transient fields private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); -keepclassmembers class * { public init (org.json.JSONObject); -keep class org.** {*;} -keep class com.android.**{*;} #-assumenosideeffects class_specification #v7 不混淆 -keep class android.support.v7.** { *; } -keep interface android.support.v7.** { *; } -dontwarn android.support.v7.** # support-design -dontwarn android.support.design.** -keep class android.support.design.** { *; } -keep interface android.support.design.** { *; } -keep public class android.support.design.R$* { *; } # support-v7-appcompat -dontwarn android.support.v7.** -keep class android.support.v7.** { *; } -keep class android.support.v7.internal.** { *; } -keep interface android.support.v7.internal.** { *; } -keep public class android.support.v7.widget.** { *; } -keep public class android.support.v7.internal.widget.** { *; } -keep public class android.support.v7.internal.view.menu.** { *; } # support-v4 -dontwarn android.support.v4.** -keep class android.support.v4.app.** { *; } -keep interface android.support.v4.app.** { *; } -keep class android.support.v4.** { *; } -keep public class * extends android.support.v4.view.ActionProvider { public init (android.content.Context); # support-v7-cardview.pro # http://stackoverflow.com/questions/29679177/cardview-shadow-not-appearing-in-lollipop-after-obfuscate-with-proguard/29698051 -keep class android.support.v7.widget.RoundRectDrawable { *; } -dontwarn android.net.http.** -keep class org.apache.http.** { *;}
proguard-third-party.pro

proguard-third-party.pro 是通用的第三方AAR库的混淆配置

# Facebook Fresco Start 

# Keep our interfaces so they can be used by other ProGuard rules.

# See http://sourceforge.net/p/proguard/bugs/466/

-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip

# Do not strip any method/class that is annotated with @DoNotStrip

-keep @com.facebook.common.internal.DoNotStrip class *

-keepclassmembers class * {

 @com.facebook.common.internal.DoNotStrip *;

# Keep native methods

-keepclassmembers class * {

 native methods 

-dontwarn okio.**

-dontwarn javax.annotation.**

-dontwarn com.android.volley.toolbox.**

-dontwarn com.squareup.okhttp.**

-dontwarn okhttp3.**

# Facebook Fresco End 


-dontwarn com.bumptech.** -keep public class * implements com.bumptech.glide.module.GlideModule -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { **[] $VALUES; public *; # Glide End
-dontwarn com.fasterxml.jackson.databind.** -keep class com.fasterxml.jackson.core.** {*;} -keep interface com.fasterxml.jackson.core { *; } -keep public class * extends com.fasterxml.jackson.core.** -keep class com.fasterxml.jackson.databind.introspect.VisibilityChecker$Std. clinit -keep class com.fasterxml.jackson.databind.ObjectMapper. clinit -keep class com.fasterxml.jackson.databind.** {*;} -keep class com.fasterxml.jackson.databind.introspect.VisibilityChecker$*{*;} -keep interface com.fasterxml.jackson.databind { *; } -keep public class * extends com.fasterxml.jackson.databind.** # Jackson End
## GSON 2.2.4 specific rules ## # 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* -keepattributes EnclosingMethod # Gson specific classes -keep class sun.misc.Unsafe { *; } -keep class com.google.gson.** { *; } -keep class com.google.gson.stream.** { *; } -keep class com.google.**{*;} -keep class com.google.gson.examples.android.model.** { *; } # GSON End # zxing Start -dontwarn com.google.zxing.** -dontwarn com.google.zxing.client.android.** -keep class com.google.zxing.**{*;} # zxing End
## GreenRobot EventBus specific rules ## # https://github.com/greenrobot/EventBus/blob/master/HOWTO.md#proguard-configuration -keepclassmembers class ** { public void onEvent*(***); # Only required if you use AsyncExecutor -keepclassmembers class * extends de.greenrobot.event.util.ThrowableFailureEvent { public init (java.lang.Throwable); # Dont warn for missing support classes -dontwarn de.greenrobot.event.util.*$Support -dontwarn de.greenrobot.event.util.*$SupportManagerFragment # EventBus 2 End
## New rules for EventBus 3.0.x ## # http://greenrobot.org/eventbus/documentation/proguard/ -keepattributes *Annotation* -keepclassmembers class ** { @org.greenrobot.eventbus.Subscribe methods -keep enum org.greenrobot.eventbus.ThreadMode { *; } # Only required if you use AsyncExecutor -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { init (java.lang.Throwable); # EventBus 3 End
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { long producerIndex; long consumerIndex; -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { rx.internal.util.atomic.LinkedQueueNode producerNode; -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { rx.internal.util.atomic.LinkedQueueNode consumerNode; # Rxjava End
-dontwarn java.nio.file.* -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement -dontwarn okio.** -keep class okio.** {*;} # OkHttp End
# Retrofit2 Start # Platform calls Class.forName on types which do not exist on Android to determine platform. -dontnote retrofit2.Platform # Platform used when running on RoboVM on iOS. Will not be used at runtime. -dontnote retrofit2.Platform$IOS$MainThreadExecutor # Platform used when running on Java 8 VMs. Will not be used at runtime. -dontwarn retrofit2.Platform$Java8 # Retain generic type information for use by reflection by converters and adapters. -keepattributes Signature # Retain declared checked exceptions for use by a Proxy instance. -keepattributes Exceptions -dontwarn retrofit2.adapter.** # Retrofit 2.X -dontwarn retrofit2.** -keep class retrofit2.** { *; } -keepattributes Signature -keepattributes Exceptions -keepclasseswithmembers class * { @retrofit2.http.* methods # Retrofit2 End
-keep class android.net.http.**{*;} -keep class com.android.internal.http.multipart.**{*;} -keep class org.apache.commons.**{*;} -keep class org.apache.org.**{*;} -keep class org.apache.harmony.**{*;} # pinyin4j End
-keep class com.nineoldandroids.** {*;}

一个可以快速生成对应第三方库的链接:http://proguard.herokuapp.com/

打开连接:http://proguard.herokuapp.com/

这里写图片描述

输入第三方库的名字,如下所示:
这里写图片描述

这里写图片描述

输入完后,点击Generate按钮,即可自动生成相应的混淆代码,如下所示:
这里写图片描述

# Created by https://proguard.herokuapp.com/api/

# Retrofit 1.X

-keep class com.squareup.okhttp.** { *; }

-keep class retrofit.** { *; }

-keep interface com.squareup.okhttp.** { *; }

-dontwarn com.squareup.okhttp.**

-dontwarn okio.**

-dontwarn retrofit.**

-dontwarn rx.**

-keepclasseswithmembers class * {

 @retrofit.http.* methods 

# If in your rest service interface you use methods with Callback argument.

-keepattributes Exceptions

# If your rest service methods throw custom exceptions, because youve defined an ErrorHandler.

-keepattributes Signature

# Also you must note that if you are using GSON for conversion from JSON to POJO representation, you must ignore those POJO classes from being obfuscated.

# Here include the POJOs that have you have created for mapping JSON response to POJO for example.

proguard-second-party.pro

proguard-second-party.pro 是我们自己开发的一些存在Maven私服的AAR库的混淆配置



# themeLib

-keep class com.xxx.theme.**{*;}

-dontwarn com.xxx.theme.**

-keep class com.xxx.md5.** {*;}

-keep class com.xxx.widget.**{*;}

-dontwarn com.xxx.widget.**

-keep class com.xxx.http.**{*;}


proguard-module.pro

其中 proguard-module.pro 文件是你们自己模块的单独混淆文件,主要配置下你们项目中所引用到的一些网络和数据库的bean,防止json解析的时候出现解析出null的情况



#所有jackson对应实体类不能混淆

-keep class com.netease.cloudmusic.net.bean.** {*;}

#数据库实体类

-keep class com.netease.cloudmusic.dao.bean.** {*;}




参考链接:

http://blog.csdn.net/ouyang_peng/article/details/51277332 https://github.com/yongjhih/android-proguards 一个可以快速生成对应第三方库的链接:http://proguard.herokuapp.com/

这里写图片描述

作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!

转载请保留原文地址:http://blog.csdn.net/ouyang_peng/article/details/73088090

如果本文对您有所帮助,欢迎您扫码下图所示的支付宝和微信支付二维码对本文进行打赏。 

这里写图片描述


Android C++系列:Linux文件IO操作(二) 注意这个读写位置和使用C标准I/O库时的读写位置有可能不同,这个读写 位置是记在内核中的,而使用C标准I/O库时的读写位置是用户空间I/O缓冲区中的位置。比如用fgetc读一个字节,fgetc有可能从内核中预读1024个字节到I/O缓冲区中,再返回第一 个字节,这时该文件在内核中记录的读写位置是1024,而在FILE结构体中记录的读写位置是 1。
Android C++系列:Linux文件IO操作(一) 事实上Unbuffered I/O这个名词是有些误导的,虽然write系统调用位于C标准库I/O缓 冲区的底层,但在write的底层也可以分配一个内核I/O缓冲区,所以write也不一定是直接 写到文件的,也可能写到内核I/O缓冲区中,至于究竟写到了文件中还是内核缓冲区中对于 进程来说是没有差别的,如果进程A和进程B打开同一文件,进程A写到内核I/O缓冲区中的数 据从进程B也能读到,而C标准库的I/O缓冲区则不具有这一特性(想一想为什么)
字节卷动 You will never know how excellent you are unless you impel yourself once.