2024年Android最新安卓项目混淆详解(1),一线互联网公司面经总结

总结

算法知识点繁多,企业考察的题目千变万化,面对越来越近的“金九银十”,我给大家准备好了一套比较完善的学习方法,希望能帮助大家在有限的时间里尽可能系统快速的恶补算法,通过高效的学习来提高大家面试中算法模块的通过率。

这一套学习资料既有文字档也有视频,里面不仅仅有关键知识点的整理,还有案例的算法相关部分的讲解,可以帮助大家更好更全面的进行学习,二者搭配起来学习效果会更好。

部分资料展示:




有了这套学习资料,坚持刷题一周,你就会发现自己的算法知识体系有明显的完善,离大厂Offer的距离更加近。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

shrinkResources 是去除无效的资源文件,压缩资源。

minifyEnabled 是开启混淆。

这是默认的Proguard配置,proguard-rules.pro是需要在你的项目里创建的文件,层级跟build.gradle文件一样的,当然你可以随意改他的文件名,只不过需要在配置代码里面跟着修改,其实这个文件就是Proguard的自定义配置文件,没有这个文件你构建是会报错的。

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

如果你希望在不通的渠道版本里使用不同的ProGuard 规则,那就在相应的 productFlavor 代码块中再添加一个 proguardFiles 属性。例如,以下 Gradle 文件会向 flavor2 产品风味添加 flavor2-rules.pro。现在 flavor2 使用所有三个 ProGuard 规则,因为还应用了来自 release 代码块的规则。

android {

buildTypes {

release {

shrinkResources true

minifyEnabled true

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

}

}

productFlavors {

flavor1 {

}

flavor2 {

proguardFile ‘flavor2-rules.pro’

}

}

}

每次构建时 ProGuard 都会输出下列文件:

dump.txt //说明 APK 中所有类文件的内部结构。

mapping.txt //提供原始与混淆过的类、方法和字段名称之间的转换。

seeds.txt //列出未进行混淆的类和成员。

usage.txt //列出从 APK 移除的代码。

这些文件保存在 /build/outputs/mapping/release/。

Proguard基本语法


-dontwarn dontwarn是一个和keep可以说是形影不离,尤其是处理引入的library时

-keep 不混淆类和成员或者被重命名

-keepnames 保留类和类中的成员,防止被混淆或移除

-keepclassmembers 只保留类中的成员,防止被混淆,成员没有引用会被移除

–keepclassmembernames 只保留类中的成员,防止被混淆,成员没有引用会被移除

-keepclasseswithmembers 保留类和类中的成员,防止被混淆或移除,保留指明的成员

-keepclasseswithmembernames 保留类和类中的成员,防止被混淆,保留指明的成员,成员没有引用会被移除

而且还支持通配符*

例如

不混淆某个类

-keep public class com.xx.xx.xx { *; }

不混淆某个包

-keep public class com.xx.xx.** { *; }

不混淆某个类的子类

-keep public class * extends com.xx.xx { *; }

基本规则


//不混淆某个类

-keep public class com.xx.xx.mi{ *; }

//不混淆某个类的子类

-keep public class * extends com.xx.xx.mi { *; }

//不混淆所有类名中包含了“model”的类及其成员

-keep public class .model. {*;}

//不混淆某个接口的实现

-keep class * implements com.xx.xx.TestInterface { *; }

//不混淆某个类的构造方法

-keepclassmembers com.xx.xx.example.Test {

public ();

}

//不混淆某个类的特定的方法(不混淆mi这个类下的test方法)

-keepclassmembers class com.xx.xx.mi{

public void test(java.lang.String);

}

//不混淆某个类的内部类

-keep class class com.xx.xx.mi$* {

*;

}

//两个常用的混淆命令,注意:

//一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;

//两颗星表示把本包和所含子包下的类名都保持;

-keep class com.suchengkeji.android.ui.**

-keep class com.suchengkeji.android.ui.*

//用以上方法保持类后,你会发现类名虽然未混淆,但里面的具体方法和变量命名还是变了,

//如果既想保持类名,又想保持里面的内容不被混淆,我们就需要以下方法了

//不混淆某个包所有的类

-keep class com.xx.xx.bean.** { *; }

//在此基础上,我们也可以使用Java的基本规则来保护特定类不被混淆,比如我们可以用extend,implement等这些Java规则。如下

保留我们使用的四大组件,自定义的Application等等这些类不被混淆

因为这些子类都有可能被外部调用

-keep public class * extends android.app.Activity

-keep public class * extends android.app.Appliction

-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

libs下的第三方Jar包的混淆方式

保留libs下的jar包的方式也很简单,同样是使用-keep关键字:找到libs目录,打开相对于的jar文件,找到对应的包名,然后添加如下代码:

-keep class 包名.** { *; }

complie的第三方Jar包的混淆方式complie的第三方Jar包的混淆方式和libs下的相同,只需要打开:打开对应的引用jar文件,然后同样使用

-keep class 包名.** { *; }

保留代码


Android SDK 本身就提供混淆的功能,将混淆开关进行开启后,开发者需要做的是对Android Studio工程项目中的proguard-rules.pro文件进行混淆白名单的配置.

那么什么是混淆白名单呢?其实就是指定一些包名、类名、变量等不可以被混淆。假设没指定白名单就进行混淆打包,而某某类的类名被混淆了(假设变成了a),那么可能其他引用或使用该类的类就找不到该类,说不定应用就会因此崩溃或是导致相应的功能无法使用.


一般这些都需要保留代码不被混淆:

使用了自定义控件那么要保证它们不参与混淆

使用了枚举要保证枚举不被混淆

对第三方库中的类不进行混淆

运用了反射的类也不进行混淆

使用了 Gson 之类的工具要使 JavaBean 类即实体类不被混淆

在引用第三方库的时候,一般会标明库的混淆规则的,建议在使用的时候就把混淆规则添加上去,免得到最后才去找

有用到 WebView 的 JS 调用也需要保证写的接口方法不混淆,原因和第一条一样

Parcelable 的子类和 Creator 静态成员变量不混淆,否则会产生 Android.os.BadParcelableException 异常

使用的四大组件,自定义的Application* 实体类

JNI中调用的类

Layout布局使用的View构造函数(自定义控件)、android:onClick等。

与js互调的类,工程中没有直接跳过。一般你可以这样写

-keep class 你的类所在的包.** { *; }

如果是内部类的话,你可以这样

-keepclasseswithmembers class 你的类所在的包.父类$子类 { ; }

例如:

-keepclasseswithmembers class com.demo.login.bean.ui.MainActivity$JSInterface {

;

}

与反射有关的类,工程中没有直接跳过。类的话直接这样

-keep class 你的类所在的包.** { *; }

通用基础配置


以下是在项目里常使用的配置,再加上你需求混淆的第三方即可。

//— 基础混淆配置区 —

//指定代码的压缩级别

-optimizationpasses 5

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

-allowaccessmodification

//不使用大小写混合

-dontusemixedcaseclassnames

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

-dontskipnonpubliclibraryclasses

//混淆时是否记录日志

-verbose

//忽略警告,避免打包时某些警告出现,没有这个的话,构建报错

-ignorewarnings

//不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。

-dontpreverify

//过滤泛型 出现类型转换错误时,启用这个

-keepattributes Signature

//抛出异常时保留代码行号 方便测试

-keepattributes SourceFile,LineNumberTable

//混淆时所采用的算法

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

//— Android开发中一些需要保留的公共区 —

//不混淆注解相关

-keepattributes Annotation

#表示不混淆任何包含native方法的类的类名以及native方法名,这个和我们刚才验证的结果是一致

-keepclasseswithmembernames class * {

native ;

}

//保持枚举 enum 类不被混淆

-keepclassmembers enum * {

public static **[] values();

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

}

//不混淆Parcelable

-keep class * implements android.os.Parcelable {

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

}

//不混淆Serializable

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

-keepnames class * implements java.io.Serializable

-keepclassmembers class * implements java.io.Serializable {*;}

//— 不能被混淆的基类 —

-keep public class * extends android.app.Activity

-keep public class * extends android.app.Fragment

-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 class org.xmlpull.v1.** { *; }

//不混淆我们自定义控件(继承自View)

-keep public class * extends android.view.View{

*** get*();

void set*(***);

public (android.content.Context);

public (android.content.Context, android.util.AttributeSet);

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

}

//不混淆R文件

-keepclassmembers class *.R$ {

public static ;

自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

eep public class * extends android.view.View{

*** get*();

void set*(***);

public (android.content.Context);

public (android.content.Context, android.util.AttributeSet);

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

}

//不混淆R文件

-keepclassmembers class *.R$ {

public static ;

自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

[外链图片转存中…(img-4PLHvoEa-1715676139795)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值