Android混淆你了解多少?,Android开发快速学习

resConfigs “en”, “zh”

}

}

_3_自定义混淆规则


品尝完了以上"配菜",下面让我们来品味一下本文的"主菜":自定义混淆规则。首先,我们来了解一下常见的混淆命令。

keep 命令

这里说的 keep 命令指的是一系列以 -keep 开头的命令,它主要用来保留 Java 中不需要进行混淆的元素。以下是常见的 -keep 命令:

-keep

作用:保留指定的类和成员,防止被混淆处理。例如:

保留包:com.moos.media.entity 下面的类以及类成员

-keep public class com.moos.media.entity.**

保留类:NumberProgressBar

-keep public class com.moos.media.widget.NumberProgressBar {*;}

-keepclassmembers

作用:保留指定的类的成员(变量/方法),它们将不会被混淆。如:

保留类的成员:MediaUtils类中的特定成员方法

-keepclassmembers class com.moos.media.MediaUtils {

public static *** getLocalVideos(android.content.Context);

public static *** getLocalPictures(android.content.Context);

}

-keepclasseswithmembers

作用:保留指定的类和其成员(变量/方法),前提是它们在压缩阶段没有被删除。与-keep 使用方式类似:

保留类:BaseMediaEntity 的子类

-keepclasseswithmembers public class * extends com.moos.media.entity.BaseMediaEntity{*;}

保留类:OnProgressBarListener接口的实现类

-keep public class * implements com.moos.media.widget.OnProgressBarListener {*;}

@Keep

除了以上方式,你也可以选择使用 @Keep 注解来保留期望代码,防止它们被混淆处理。比如,我们通过 @Keep 修饰一个类来保留它不被混淆:

@Keep

data class CloudMusicBean(var createDate: String,

var id: Long,

var name: String,

var url: String,

val imgUrl: String)

同样地,我们也可以让 @Keep 来修饰方法或者字段进而保留它们。

其他命令

dontwarn

-keep class twitter4j.** { *; }

-dontwarn twitter4j.**

-dontwarn 命令一般在我们引入新的 library 时会使用到,常用于处理 library 中无法解决的警告。如:

其他的命令用法可参考 Android 系统提供的默认混淆规则:

#混淆时不生成大小写混合的类名

-dontusemixedcaseclassnames

#不跳过非公共的库的类

-dontskipnonpubliclibraryclasses

#混淆过程中记录日志

-verbose

#关闭预校验

-dontpreverify

#关闭优化

-dontoptimize

#保留注解

-keepattributes Annotation

#保留所有拥有本地方法的类名及本地方法名

-keepclasseswithmembernames class * {

native ;

}

#保留自定义View的get和set方法

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

void set*(***);

*** get*();

}

#保留Activity中View及其子类入参的方法,如: onClick(android.view.View)

-keepclassmembers class * extends android.app.Activity {

public void *(android.view.View);

}

#保留枚举

-keepclassmembers enum * {

**[] $VALUES;

public *;

}

#保留序列化的类

-keepclassmembers class * implements android.os.Parcelable {

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

}

#保留R文件的静态成员

-keepclassmembers class *.R$ {

public static ;

}

-dontwarn android.support.**

-keep class android.support.annotation.Keep

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

-keepclasseswithmembers class * {

@android.support.annotation.Keep ;

}

-keepclasseswithmembers class * {

@android.support.annotation.Keep ;

}

-keepclasseswithmembers class * {

@android.support.annotation.Keep (…);

}

更多混淆命令可以参考文章:Proguard 最全混淆规则说明 ,这里就不做详细讲解了。

https://juejin.im/entry/58f6d2a10ce463006bc9e6af

_4_混淆"黑名单"


我们在了解了混淆的基本命令之后,很多人应该还是一头雾水:到底哪些内容该混淆?

其实,我们在使用代码混淆时,ProGuard 对我们项目中大部分代码进行了混淆操作,为了防止编译时出错,我们应该通过 keep 命令保留一些元素不被混淆。所以,我们只需要知道哪些元素不应该被混淆:

枚举

项目中难免可能会用到枚举类型,然而它不能参与到混淆当中去。原因是:枚举类内部存在 values 方法,混淆后该方法会被重新命名,并抛出 NoSuchMethodException。

庆幸的是,Android 系统默认的混淆规则中已经添加了对于枚举类的处理,我们无需再去做额外工作。想了解更多枚举内部细节可以去查看源码,篇幅有限不再细说。

被反射的元素

被反射使用的类、变量、方法、包名等不应该被混淆处理。原因在于:代码混淆过程中,被反射使用的元素会被重命名,然而反射依旧是按照先前的名称去寻找元素,所以会经常发生 NoSuchMethodException 和 NoSuchFiledException 问题。

实体类

实体类即我们常说的"数据类",当然经常伴随着序列化与反序列化操作。很多人也应该都想到了,混淆是将原本有特定含义的"元素"转变为无意义的名称,所以,经过混淆的"洗礼"之后,序列化之后的 value 对应的 key 已然变为没有意义的字段,这肯定是我们不希望的。

同时,反序列化的过程创建对象从根本上来说还是借助于反射,混淆之后 key 会被改变,所以也会违背我们预期的效果。

四大组件

Android 中的四大组件同样不应该被混淆。

原因在于:

  • 四大组件使用前都需要在 AndroidManifest.xml 文件中进行注册声明,然而混淆处理之后,四大组件的类名就会被篡改,实际使用的类与 manifest 中注册的类并不匹配,故而出错。

  • 其他应用程序访问组件时可能会用到类的包名加类名,如果经过混淆,可能会无法找到对应组件或者产生异常。

JNI 调用的Java 方法

当 JNI 调用的 Java 方法被混淆后,方法名会变成无意义的名称,这就与 C++ 中原本的 Java 方法名不匹配,因而会无法找到所调用的方法。

其他不应该被混淆的
  • 自定义控件不需要被混淆

  • JavaScript 调用 Java 的方法不应混淆

  • Java 的 native 方法不应该被混淆

  • 项目中引用的第三方库也不建议混淆

混淆后的堆栈跟踪


代码经过 ProGuard 混淆处理后,想要读取 StackTrace(堆栈追踪)信息就会变得很困难。由于方法名称和类的名称都经过混淆处理,即使程序发生崩溃问题,也很难定位问题所在。幸运的是,ProGuard 为我们提供了补救的措施,在着手进行之前,我们先来看一下 ProGuard 每次构建后生成了哪些内容。

混淆输出结果

混淆构建完成之后,会在 /build/outputs/mapping/release/ 目录下生成以下文件:

dump.txt

说明 APK 内所有类文件的内部结构。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2020-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节

还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

一线互联网面试专题

379页的Android进阶知识大全

379页的Android进阶知识大全

点击:

Android架构视频+BAT面试专题PDF+学习笔记》即可免费获取~

Gnvl7-1711370667379)]

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2020-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节

还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

[外链图片转存中…(img-xaU7ksyd-1711370667379)]

[外链图片转存中…(img-xVcFPMM6-1711370667380)]

[外链图片转存中…(img-P1s5Y4RT-1711370667380)]

点击:

Android架构视频+BAT面试专题PDF+学习笔记》即可免费获取~

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

  • 12
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值