Android使用R8压缩,混淆,优化App
在Android开发中,为了使App尽可能小,可以使用R8来压缩,混淆,优化App,当使用Android Gradle插件3.4.0或更高版本时,插件不再使用ProGuard执行优化而是R8。
R8的功能
- 代码压缩:安全地从App及其库依赖项中删除未使用的类,字段,方法和属性。
- 资源压缩:从打包的App中删除未使用的资源,包括应用程序库依赖项中未使用的资源。它与代码压缩一起使用,这样一旦删除了未使用的代码,也可以安全地删除不再引用的资源。
- 代码混淆:使用简短无意义的名称重命名代码里的类,字段和方法,从而减少DEX文件大小。
- 代码优化:删除未使用的代码或重写代码使其更简洁。
R8 和 Proguard
R8和Proguard 相比,R8 可以更快地缩减代码,同时改善输出大小,R8 默认处于启用状态,你可将以下代码添加到项目的 gradle.properties 文件以停用 R8:
android.enableR8=false
R8 普通模式是兼容 Proguard的,R8 完全模式与会启用一些额外的优化,这个时候可能需要一些其它ProGuard规则以避免运行时问题,可以在 项目的gradle.properties 文件中设置以下内容启用完全模式。
android.enableR8.fullMode=true
启用压缩,混淆,优化
使用Android Studio创建新项目时,默认情况下不启用压缩,混淆,优化,因为这会增加项目的构建时间,而且有些代码混淆后会出错。要想启用这些功能,需要在项目的build.gradle包含下面的内容。
getDefaultProguardFile(‘proguard-android.txt’) 方法可从 Android SDK tools/proguard/ 文件夹获取默认的 ProGuard规则文件。
proguard-rules.pro文件用于添加自定义 ProGuard 规则。默认情况下,该文件位于模块根目录。
android {buildTypes {release {//启用代码压缩,混淆,优化minifyEnabled true//启用资源压缩shrinkResources true//ProGuard规则文件proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'}}...
}
自定义要保留的资源
如果您有想要保留或舍弃的特定资源,请在您的项目中创建一个包含 标记的 XML 文件,并在 tools:keep 属性中指定每个要保留的资源,在 tools:discard 属性中指定每个要舍弃的资源。这两个属性都接受逗号分隔的资源名称列表。您可以使用星号字符作为通配符。
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"tools:discard="@layout/unused2" />
严格压缩模式
如果你的代码或库代码(例如AppCompat)调用了Resources.getIdentifier(),这就表示你的代码将根据动态生成的字符串查询资源名称,默认情况下资源压缩器会采取防御性行为,将所有具有匹配名称格式的资源标记为可能已使用,无法移除。例如,以下代码会使所有带 img_ 前缀的资源标记为已使用。
String name = String.format("img_%1d", angle + 1);
res = getResources().getIdentifier(name, "drawable", getPackageName());
在 keep.xml 文件中将 shrinkMode 设置为 strict可以停用该防御性行为,这个时候你必须用tools:keep 属性手动保留这些资源。
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"tools:shrinkMode="strict" />
合并重复资源
默认情况下,Gradle 还会合并同名资源,例如可能位于不同资源文件夹中的同名可绘制对象。这一行为不受 shrinkResources 属性控制,也无法停用,因为在有多个资源匹配代码查询的名称时,有必要利用这一行为来避免错误。
只有在两个或更多个文件具有完全相同的资源名称、类型和限定符时,才会进行资源合并。
自定义要保持的代码
在ProGuard规则文件中可以使用-keep保持特定代码不被移除或混淆,或者向你想保持的代码添加 @Keep 注解,在类上添加 @Keep 可原样保持整个类,在方法或字段上添加它可完整保持方法/字段(及其名称)以及类名称。
-keep public class MyClass
必须保持的代码
- AndroidManifest.xml引用的类。
- JNI调用的方法。
- 反射用到的类。
- WebView中JavaScript使用的类。
- Layout文件引用的自定义View。
常用ProGuard规则
关闭压缩
-dontshrink
关闭代码优化,默认Proguard规则文件已包含
-dontoptimize
关闭混淆
-dontobfuscate
指定代码优化级别,值在0-7之间,默认为5
-optimizationpasses 5
混淆时不使用大小写混合类名,默认Proguard规则文件已包含
-dontusemixedcaseclassnames
不忽略库中的非public的类,默认Proguard规则文件已包含
-dontskipnonpubliclibraryclasses
不忽略库中的非public的类成员
-dontskipnonpubliclibraryclassmembers
输出详细信息,默认Proguard规则文件已包含
-verbose
不做预校验,预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度,默认Proguard规则文件已包含
-dontpreverify
保持指定包下的类名,不包括子包下的类名
-keep class com.xy.myapp*
保持指定包下的类名,包括子包下的类名
-keep class com.xy.myapp**
保持指定包下的类名以及类里面的内容
-keep class com.xy.myapp.* {*;}
保持所有继承于指定类的类
-keep public class * extends android.app.Activity
其它keep方法:
保留 | 防止被移除或者被混淆 | 防止被混淆 |
---|---|---|
类和类成员 | -keep | -keepnames |
仅类成员 | -keepclassmembers | -keepclassmembernames |
如果拥有某成员,保留类和类成员 | -keepclasseswithmembers | -keepclasseswithmembernames |
如果我们要保留一个类中的内部类不被混淆则需要用$符号,如下例子表示保持MyClass内部类JavaScriptInterface中的所有public内容。
-keepclassmembers class com.xy.myapp.MyClass$JavaScriptInterface {public *;
}
保持指定类的所有方法
-keep class com.xy.myapp.MyClass {public <methods>;
}
保持指定类的所有字段
-keep class com.xy.myapp.MyClass {public <fields>;
}
保持指定类的所有构造器
-keep class com.xy.myapp.MyClass {public <init>;
}
保持用指定参数作为形参的方法
-keep class com.xy.myapp.MyClass {public <methods>(java.lang.String);
}
类文件除了定义类,字段,方法外,还为它们附加了一些属性,例如注解,异常,行号等,优化操作会删除不必要的属性,使用-keepattributes可以保留指定的属性
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
使指定的类不输出警告信息
-dontwarn com.squareup.okhttp.**
特殊ProGuard规则
由于enum类的特殊性,下面两个方法会被反射调用,默认Proguard规则文件已经处理。
-keepclassmembers enum * {public static **[] values();public static ** valueOf(java.lang.String);
}
Parcelable的子类和Creator静态成员变量要保持,否则会产生Android.os.BadParcelableException异常,默认Proguard规则文件已经处理。
-keepclassmembers class * implements android.os.Parcelable {public static final android.os.Parcelable$Creator CREATOR;
}
常用混淆模板
# 指定代码的压缩级别
-optimizationpasses 5 # 不忽略库中的非public的类成员
-dontskipnonpubliclibraryclassmembers # google推荐算法
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*# 避免混淆Annotation、内部类、泛型、匿名类
-keepattributes *Annotation*,InnerClasses,Signature,EnclosingMethod# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable# 保持四大组件
-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.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.**# 保持自定义控件
-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);
}# 保持所有实现 Serializable 接口的类成员
-keepclassmembers class * implements java.io.Serializable {static final long serialVersionUID;private static final java.io.ObjectStreamField[] serialPersistentFields;private void writeObject(java.io.ObjectOutputStream);private void readObject(java.io.ObjectInputStream);java.lang.Object writeReplace();java.lang.Object readResolve();
}# 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);
}
输出文件
启用R8或ProGuard构建项目后会在模块下的build\outputs\mapping\release文件夹下输出下列文件:
- dump.txt:说明 APK 中所有类文件的内部结构。
- mapping.txt:提供原始与混淆过的类、方法和字段名称之间的转换。
- seeds.txt:列出未进行混淆的类和成员。
- usage.txt:列出从 APK 移除的代码。
Android使用R8压缩,混淆,优化App相关推荐
- android 万能混淆文件,Android ProGuard 代码压缩混淆与打包优化
为什么要启动ProGuard(所有试验都在AS 环境) 代码压缩通过 ProGuard 提供,ProGuard 会检测和移除封装应用中未使用的类.字段.方法和属性, 包括自带代码库中的未使用项(这使其 ...
- Android包体积优化上篇- 资源混淆优化
导读:什么时候进行包体积优化?一般在app初创期时,由于业务代码较少,包体积也不大,相应这个时候对包体积的优化收益也较少.当业务逐渐成熟功能,迭代逐渐变多,包体积也会逐渐增加. 增加包体积主要影响如下 ...
- Android项目打包开启proguard的混淆优化带来的问题
1.引入一个sdk以后.打包报错: [INFO] Unexpected error while evaluating instruction: [INFO] Class = [com/ ...
- Android性能优化-App后台优化
原文链接 Background Optimizations 前言 后台进程是内存和电池敏感的.一个隐式的broadcast可能会启动很多监听它的后台进程,即使这些进程可能做得工作不多.这可能丢设备性能 ...
- Android性能优化-App启动优化
原文地址:https://developer.android.com/topic/performance/launch-time.html#common 通常用户期望app响应和加载速度越快越好.一个 ...
- android 电池容量检测,电池容量检测优化app
电池容量检测优化app是一款功能十分强大的手机电池优化服务软件,使用这款软件可以快速的对电池容量进行检测,同时还可以对手机内存进行一键清理,只需要轻松点击一下就可以节省高达50%的电池寿命,需要的朋友 ...
- android 常用混淆,Android常用的代码混淆整理【原创】
android里的代码混淆是比不可少的东西,下面就贴一些常用的代码混淆. #指定代码的压缩级别 -optimizationpasses 5 #包明不混合大小写 -dontusemixedcasecla ...
- [转]Android 项目的代码混淆,Android proguard 使用说明
简介 Java代码是非常容易反编译的.为了很好的保护Java源代码,我们往往会对编译好的class文件进行混淆处理. ProGuard是一个混淆代码的开源项目.它的主要作用就是混淆,当然它还能对字节码 ...
- 读懂Android中的代码混淆
本文为本人的一些实践总结,介绍一些混淆的知识和注意事项.希望可以帮助大家更好的学习和使用代码混淆. 什么是混淆 关于混淆维基百科上该词条的解释为 代码混淆(Obfuscated code)亦称花指令, ...
最新文章
- Android图片轮播
- leetcode算法题--二叉树的前序遍历
- rdbms mysql_RDBMS-mysql初步
- python boxplot pvalue_1.1.1数据质量分析Python boxplot,111,箱,线图
- aop+注解 实现对实体类的字段校验_SpringBoot实现通用的接口参数校验
- 机动车c1科三考试语言灯光,c1科目三灯光模拟考试
- C语言输出九九乘法表
- 原子变量, 无锁定且无等待算法
- 关于j2ee工程发布到was上后,部分更新,例修改web.xml配置文件不起作用的原因解析【转】...
- 抢椅子游戏java_抢椅子游戏作文(精选10篇)
- 聊聊图标和MBE图标
- C++IO流文件指针
- HDU - 4565 So Easy!
- 个人备案网站不能做博客了?
- 吃鸡是python写的吗_用Python来P图,分析怎么吃鸡?只有想不到,没有做不到
- 整理的java基础知识点笔记
- 哲理故事300篇(上)
- 自我健康检测及产品应用方案
- 中信soeasy网络硬盘 瑞星杀毒软件升级包
- 怎么把一个网页设置快捷方式弄到桌面上去
热门文章
- Charles修改请求和返回
- 关于Spark默认并行度spark.default.parallelism的理解
- excel转json对象工具推荐
- FFmpeg之视频封装格式、流媒体协议、视频编解码协议和传输流格式、时间戳和时间基、视频像素数据
- Inno setup 安装卸载前校验工作
- python设计模式 韦塞尔 pdf下载_《Python设计模式》 [美] 韦塞尔. 巴登霍斯特(Wessel Badenhorst)著 蒲成 译 【正版电子纸书阅读_PDF下载】- 书问...
- 【Python教你一招】用Python实现童年小游戏俄罗斯方块
- mysql dal层_MySQL读写分离的DAL层策略设计
- 20180908考试
- Egret 5.3 正式发布,为重度小游戏开发带来新技能