一、为什么要进行代码混淆?

java是一种跨平台的、解释型语言、Java源代码编译成中间”字节码”存储于class文件中。由于跨平台的需要,Java字节码中包括很多源代码信息,如变量名、方法名,并且通过这些名称来访问变量和方法,这些符号带有许多语义信息,很容易被反编译成Java源代码。为了防止这种现象,我们可以使用Java混淆器对Java字节码进行混淆。

二、什么是代码混淆?

混淆就是对发布出去的程序进行重新组织和处理,使用处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英文字母代号,在缺乏相应的函数名和程序注释的情况下,即使被反编译,也将难以阅读。同时混淆是不可逆的,在混淆过程中有一些不影响正常运行的信息将永远丢失,这些信息的丢失使程序变得更加难以理解。

三、代码混淆的作用?

混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。由于以上介绍的缩短变量和函数名以及丢失部分信息的原因,编译后jar文件体积大约能减少25%,这对当前费用较贵的无线网络传输是有一定意义的。

四、混淆后apk个资源文件的比较(见图)

1、包名的比较

混淆前.png

混淆后.png

2、变量名

混淆前.png

混淆后.png

3、方法名

混淆前.png

混淆后.png

4、字节码文件

混淆前.png

混淆后.png

五、代码混淆怎么做?

1、AndroidStudio环境下代码混淆涉及到的文件及配置

1. 项目的app/build.gradle

image.png

image.png

2.代码混淆工具以及混淆的配置文件(android SDK目录下)

image.png

具体代码混淆操作

首先在app/build.gradle文件中开启代码混淆开关

minifyEnabled true //混淆开关

默认的混淆脚本文件(proguard-android.txt)中设置了默认的保留不混淆条件,但是大多数情况下我们仍然要设置我们自己的混淆脚本文件。具体操作如下:

image.png

然后需要在项目生成的混淆脚本中添加过滤混淆的条件

# Glide

-keep public class * implements com.bumptech.glide.module.GlideModule

-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {

**[] $VALUES;

public *;

}

# Gson

-keep class sun.misc.Unsafe { *; }

-keep class com.google.gson.stream.** { *; }

# OkHttp3

-keep class okhttp3.** { *; }

-keep interface okhttp3.** { *; }

-dontwarn okhttp3.**

# Okio

-dontwarn com.squareup.**

-dontwarn okio.**

-keep public class org.codehaus.* { *; }

-keep public class java.nio.* { *; }

# Retrofit

-dontwarn retrofit2.**

-keep class retrofit2.** { *; }

-keepattributes Signature

-keepattributes Exceptions

# RxJava RxAndroid

-dontwarn sun.misc.**

-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;

}

#数据模型(实体类)

-keep class com.seekfangle.pad.bean.* {*;}

#第三方架包

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

-keep class android_serialport_api.** { *;}

配置说明使用到的开源架包(Rxjava、Gson等)都能从网上找到混淆配置,直接拷贝到脚本文件中

image.png

使用但三方放架包时如下图,配置时最好打开找到其包名采用上述配置文件中的配置方式。

image.png

六、混淆为什么要保留类名或方法名?

1、让C/C++程序可以通过jni使用对应的java方法

2、四大组件由于在AndroidManifest.xml里面注册了,所以需要保留。

3、R文件混淆会导致引用错误。

4、第三方架包有的已经经过混淆了,再次混淆会导致找不到类名或者方法名

七、什么时候不被混淆?

一般以下情况都会不混淆:

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

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

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

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

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

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

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

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

八、混淆语法

基本规则

两个常用的混淆命令,注意一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;而两颗星表示把本包和所包含的子包下的类名都保留。

-keep class cn.hadcn.test.**

-keep class cn.hadcn.test.*

如果既想保持类名,又想保持里面的内容不被混淆,就执行以下方法

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

在此基础上,我们也可以使用Java的基本规则来保护特定类不被混淆,比如我们可以用extend,implement等这些Java规则。如下例子就避免所有继承Activity的类被混淆

保留我们使用的四大组件,自定义的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

2、基本混淆模板

#############################################

#

# 对于一些基本指令的添加

#

############################################## 代码混淆压缩比,在0~7之间,默认为5,一般不做修改

-optimizationpasses 5

# 混合时不使用大小写混合,混合后的类名为小写

-dontusemixedcaseclassnames

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

-dontskipnonpubliclibraryclasses

# 这句话能够使我们的项目混淆后产生映射文件# 包含有类名->混淆后类名的映射关系

-verbose

# 指定不去忽略非公共库的类成员

-dontskipnonpubliclibraryclassmembers

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

-dontpreverify

# 保留Annotation不混淆

-keepattributes *Annotation*,InnerClasses

# 避免混淆泛型

-keepattributes Signature

# 抛出异常时保留代码行号

-keepattributes SourceFile,LineNumberTable

# 指定混淆是采用的算法,后面的参数是一个过滤器# 这个过滤器是谷歌推荐的算法,一般不做更改

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

#############################################

#

# Android开发中一些需要保留的公共部分

#

#############################################

# 保留我们使用的四大组件,自定义的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

# 保留support下的所有类及其内部类

-keep class android.support.** {*;}

# 保留继承的

-keep public class * extends android.support.v4.**

-keep public class * extends android.support.v7.**

-keep public class * extends android.support.annotation.**

# 保留R下面的资源

-keep class **.R$* {*;}

# 保留本地native方法不被混淆

-keepclasseswithmembernames class * {

native ;

}

# 保留在Activity中的方法参数是view的方法,# 这样以来我们在layout中写的onClick就不会被影响

-keepclassmembers class * extends android.app.Activity{

public void *(android.view.View);

}

# 保留枚举类不被混淆

-keepclassmembers enum * {

public static **[] values();

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

}

# 保留我们自定义控件(继承自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);

}

# 保留Parcelable序列化类不被混淆

-keep class * implements android.os.Parcelable {

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

}

# 保留Serializable序列化的类不被混淆

-keepclassmembers class * implements java.io.Serializable {

static final long serialVersionUID;

private static final java.io.ObjectStreamField[] serialPersistentFields;

!static !transient ;

!private ;

!private ;

private void writeObject(java.io.ObjectOutputStream);

private void readObject(java.io.ObjectInputStream);

java.lang.Object writeReplace();

java.lang.Object readResolve();

}

# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆

-keepclassmembers class * {

void *(**On*Event);

void *(**On*Listener);

}

# webView处理,项目中没有使用到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);

}

android代码混淆作用,Android代码混淆相关推荐

  1. android代码混淆作用,Android分享:代码混淆那些事

    1) 前言 ProGuard是一个开源的Java代码混淆器.它可以混淆Android项目里面的java代码,对的,你没看错,仅仅是java代码.它是无法混淆Native代码,资源文件drawable. ...

  2. android 混淆作用,Android开发之——Android 代码混淆(1)

    前言 在开始之前我们先看几个概念: 混淆 概念: 混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正 ...

  3. android注解的作用,Android 用注解来提升代码质量

    Android 用注解来提升代码质量 Android,注解,annotation 2018.07.13 Android 提供了一个注解的 support 包,这个注解包配合 IDE 可以用来提升我的代 ...

  4. android热补丁作用,Android热修复之 - 阿里开源的热补丁

    这里就有一个概念那就AndFix.apatch补丁用来修复方法,接下来我们看看到底是怎么实现的. 1.2 生成apatch包 假如我们收到了用户上传的崩溃信息,我们改完需要修复的Bug,这个时候就会有 ...

  5. android布局的作用,Android UI布局经验总结

    如何在Android中动态设置颜色透明?10%20%到100% Android布局分析工具HierarchyView Android使用include/merge/ViewStub优化布局 List的 ...

  6. android minheight的作用,Android 自定义 View 最少必要知识

    1. 什么是自定义 View? 1.1 定义 在 Android 系统中,界面中所有能看到的元素都是 View.默认情况下,Android 系统为开发者提供了很多 View,比如用于展示文本信息的 T ...

  7. android.support.v4作用,Android Support V4, V7, V13的作用与用法

    1, Android Support V4, V7, V13是什么? 本质上就是三个java library. 2,  为什么要有support库? 如果在低版本Android平台上开发一个应用程序, ...

  8. android scaletype没作用,Android ImageView的ScaleType属性

    参考 ScaleType属性 常量 含义 fitXY 横向.纵向独立缩放,以适应该ImageView fitCenter 保持纵横比缩放图片,缩放完成后将图片放在ImageView的中央 fitSta ...

  9. android scaletype没作用,Android源码系列之深入理解ImageView的ScaleType属性

    做Android开发的童靴们肯定对系统自带的控件使用的都非常熟悉,比如Button.TextView.ImageView等.如果你问我具体使用,我会给说:拿ImageView来说吧,首先创建一个新的项 ...

  10. android scaletype没作用,Android ImageView 的scaleType 属性图解

    ImageView 是 Android 中最常用的控件之一,而在使用ImageView时,必不可少的会使用到它的scaleType属性.该属性指定了你想让ImageView如何显示图片,包括是否进行缩 ...

最新文章

  1. oracle-闪回技术2
  2. c语言程序改错类型,C语言程序改错总结
  3. c语言if(!k1)x=1,C语言选择题题库2
  4. 手机工商银行怎么转账_工商银行信用卡要哪些申请条件?想成功办理你需要了解这些!...
  5. WCF 第八章 安全 客户端认证
  6. 前端面试题汇总(jQuery)
  7. 下面的3条指令执行后,CPU几次修改IP?
  8. note3 android system recovery,三星note3 N900v刷第三方rom
  9. redhat 7 防火墙配置
  10. SpringBoot中多种Filter配置方式
  11. mysql分组函数_mysql分组函数
  12. 通过JLINK下载程序(附JLINK驱动)
  13. FFT运算的加深理解——频谱泄露
  14. 【虚拟校园】虚拟学生入学清华,中国传媒大学打造元宇宙大学
  15. linux如何查看隐藏进程中勒索病毒,.FileFuck勒索病毒删除+数据恢复(HiddenTear变体)...
  16. STM32+A4988控制步进电机
  17. GAN的评价指标IS和FID
  18. Spring Cloud Netflix Eureka Server 搭建服务注册中心
  19. 腾讯360再较量  谁是反垄断巨头
  20. Qt--模拟按下按键(键盘)

热门文章

  1. 字段分行加一 sql语句
  2. 探讨下Tag标签的数据库设计(千万级数据量) 转
  3. 190616每日一句
  4. 21个GIF动图让你了解各种数学概念
  5. Atitit 数据建模的技术总结 目录 1. 数据建模 1 2. 常见建模技术 2 2.1. 电子表格程序 计算机辅助设计 (CAD)  2 2.2. Er图 2 3. 建模方法 2 3.1. .
  6. Atitit golang开发环境搭建 目录 1. 编辑helo.go 1 1.1. 调试编译 1 2. Ide选择liteide 2 3. 问题解决 2 4. 附录 2 4.1. Go语言标准库常
  7. Atitit html5.1 新特性attilax总结
  8. paip.win32的internet扩展已停止工作解决大法
  9. 什么是Ⅰ类、Ⅱ类、Ⅲ类银行账户?秒懂!
  10. 看不见的“网” ,一文读懂阿里云基础设施网络