zoukankan      html  css  js  c++  java
  • android apk瘦身(2) R8编译器:压缩代码、压缩资源、优化代码

    1.官方文档

      https://developer.android.com/studio/build/shrink-code

      当您使用 Android Studio 3.4 或 Android Gradle 插件 3.4.0 及更高版本时,R8 是默认编译器,用于将项目的 Java 字节码转换为在 Android 平台上运行的 DEX 格式。同时还提供以下功能(默认关闭):

    • 压缩代码 : 从应用及其库依赖项中检测并安全地移除不使用的类、字段、方法和属性
    • 压缩资源 : 从封装应用中移除不使用的资源,包括应用库依赖项中不使用的资源。
    • 混淆代码 : 缩短类和成员的名字,从而减小 DEX 文件的大小.
    • 优化代码 : 检查并重写代码,深层次优化代码。  

    2.压缩代码

    2.1 开启

      R8 首先会根据组合的配置文件集确定应用代码的所有入口点。这些入口点包括 Android 平台可用来打开应用的 Activity 或服务的所有类。从每个入口点开始,R8 会检查应用的代码来构建一张图表,列出应用在运行时可能会访问的所有方法、成员变量和其他类。系统会将与该图表没有关联的代码视为执行不到的代码,并可能会从应用中移除该代码。

    在对应模块的build.gradle内  minifyEnabled true  开启。

     1 android {
     2     compileSdkVersion 30
     3     buildToolsVersion '30.0.2'
     4     ...
     5     buildTypes {
     6         debug {
     7             minifyEnabled false
     8         }
     9         release {
    10             minifyEnabled true
    11   
    12         }
    13     }
    14 }

    2.2 保留代码

      在项目的Proguard配置文件中使用  -keep 可保留不被压缩或混淆的代码。如:

     1 # Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
     2 # JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
     3 -keep class * extends com.google.gson.TypeAdapter
     4 -keep class * implements com.google.gson.TypeAdapterFactory
     5 -keep class * implements com.google.gson.JsonSerializer
     6 -keep class * implements com.google.gson.JsonDeserializer
     7 
     8 # Prevent R8 from leaving Data object members always null
     9 -keepclassmembers,allowobfuscation class * {
    10   @com.google.gson.annotations.SerializedName <fields>;
    11 }

    3.压缩资源

    3.1 开启

    在对应模块的build.gradle内 shrinkResources true 开启。

    压缩资源必需在与压缩代码 开启后,才有效。只有在移除所有不使用的代码后,才能准确定位所有未使用的资源。

     1 android {
     2     compileSdkVersion 30
     3     buildToolsVersion '30.0.2'
     4     ...
     5     buildTypes {
     6         debug {
     7             minifyEnabled false
     8             shrinkResources false
     9         }
    10         release {
    11             minifyEnabled true
    12             shrinkResources true
    13 
    14         }
    15     }
    16 }

    开启后,构建apk时,编译器移除不使用的资源,包括应用库依赖项中不使用的资源。

    3.2 保留资源

    res/raw/下新建xml文件,其中可定义要保留或者丢弃的资源文件。如下:

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <resources xmlns:tools="http://schemas.android.com/tools"
    3     tools:keep="@layout/l_used*_c,@color/svg_color_selector"
    4     tools:shrinkMode="strict"
    5     tools:discard="@layout/unused2"
    6     />
    • tools:keep 属性中指定要保留的资源
    • tools:discard 属性中指定要舍弃的资源 
    • tools:shrinkMode 压缩模式,可取值为[ strict ,safe ] :
      • scrict 严格按照keep和discard指定的资源留或舍。
      • safe:保守的删除未引用资源,如代码中用  Resources.getIdentifier()  引用的资源,会保留。如下:
        1    val name = String.format("img_%1d", angle + 1)
        2    val res = resources.getIdentifier(name, "drawable", packageName)
    • 多个资源文件中 以逗号分隔
    • 可以使用通配符*。
    • 这个xml文件可以有多份

    3.3 优化记录文件

      Gradle 会在 <module-name>/build/outputs/mapping/release/(ProGuard 输出文件所在的文件夹)中创建一个名为 resources.txt 的诊断文件。此文件包含一些详细信息,比如,哪些资源引用了其他资源,哪些资源在使用,哪些资源被移除。

    3.4 在项目源码中删除无用资源

      这个要谨慎

    在android studio中选择菜单项  

    • Refactor  -> Remove unused Resources...
    • Preveiew 查看有哪些未使用
    • Do Refactor 确认删除 

    4.去掉多余语言资源文件

    android studio 工具默认会为@strings/xxx 内的字符资源 生成116个版本。

    使用 resConfigs 可指定只用到的版本,去掉其它的。

     1 android {
     2     compileSdkVersion 30
     3     buildToolsVersion '30.0.2'
     4     defaultConfig {
     5         applicationId "com.jiankangyangfan.nurse"
     6         minSdkVersion 19
     7         targetSdkVersion 30
     8         ...
     9         resConfigs "zh-rCH","zh-rHK","zh-rTW"
    10     }
    11     ...
    12 }

    resConfigs 的取值可以通过一个未压缩的包中查看(上图中红色框内),然后选择目标版本。(并没有发现一个叫"en"的版本)

    5.混淆代码:缩小dex文件

      混淆处理不会从应用中移除代码,但如果应用的 DEX 文件将许多类、方法和字段编入索引,那么混淆处理将可以显著缩减应用的大小。

      R8 在每次运行时都会创建一个 mapping.txt 文件,其中列出了经过混淆处理的类、方法和字段的名称与原始名称的映射关系。

      此映射文件还包含用于将行号映射回原始源文件行号的信息。此文件保存在 <module-name>/build/outputs/mapping/<build-type>/ 目录中。每次发布新版本时都要注意保存一个该文件的副本.

       在 proguard-rules.pro 中加入以下代码可以还原行号 、 输出R8优化记录、输出混淆时被保留的入口类。

    1   -keepattributes LineNumberTable,SourceFile
    2   -printconfiguration ./build/tmp/full-r8-config.txt
    3   -printseeds ./build/tmp/seeds.txt
    • -keepattributes LineNumberTable,SourceFile 用来保留源文件和行号信息。可用来还原混淆。
    • -printconfiguration ./build/tmp/full-r8-config.txt  把混淆记录写入到文件full-r8-config.txt中。
    • -printseeds ./build/tmp/seeds.txt   把混淆入口类输出到seeds.txt中。

      

    6.优化代码

      R8 可深层次优化代码,在项目的 gradle.properties 文件中添加以下代码来启用深度优化功能:

    android.enableR8.fullMode=true

      开启后可能引起不确定bug或者崩溃,谨慎开启。

    具体的优化选项在: 

      https://jakewharton.com/blog

    7.R8配置文件

    R8根据ProGuard配置文件决定优化策略,一个项目中可能有多个模块,每个模块都可以自定义对应的R8配置文件。它们是累加的。一个模块中的配置可能影响到其它模块。

     来源 位置
    Android Studio <module-dir>/proguard-rules.pro
    Android Gradle 插件

    proguard-android-optimize.txt    由 Android Gradle 插件在编译时生成。

    库依赖项

    AAR 库:

    • <library-dir>/proguard.txt

    JAR 库:

    • <library-dir>/META-INF/proguard/
    Android 资源打包工具 2 (AAPT2)

    使用 minifyEnabled true 构建项目后:

      <module-dir>/build/intermediates/proguard-rules/debug/aapt_rules.txt

    自定义配置文件

    默认情况下,当您使用 Android Studio 创建新模块时,IDE 会创建 

      <module-dir>/proguard-rules.pro,以便您添加自己的规则。

    8.资源混淆

      微信的资源混淆参考 : 

      https://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=208135658&idx=1&sn=ac9bd6b4927e9e82f9fa14e396183a8f#rd

  • 相关阅读:
    68
    56
    Django manager 命令笔记
    Django 执行 manage 命令方式
    Django 连接 Mysql (8.0.16) 失败
    Python django 安装 mysqlclient 失败
    H.264 SODB RBSP EBSP的区别
    FFmpeg—— Bitstream Filters 作用
    MySQL 远程连接问题 (Windows Server)
    MySQL 笔记
  • 原文地址:https://www.cnblogs.com/mhbs/p/11947117.html
Copyright © 2011-2022 走看看