关于apk瘦身

作者: zcwfeng | 来源:发表于2020-12-17 11:39 被阅读0次

    了解Apk结构

    APK 文件就是一个Zip格式的文件,其中包含构成应用的所有文件。这些文件包括 Java 类文件、资源文件和 包含已编译资源的文件。
    APK 包含以下目录:

    • META-INF/:包含 CERT.SF 和 CERT.RSA 签名文件,以及 MANIFEST.MF 清单文件。
    • assets/:包含应用的资源;应用可以使用 AssetManager 对象检索这些资源。
    • res/:包含未编译到 resources.arsc 中的资源(图片、音视频等)。
    • lib/:包含特定于处理器软件层的已编译代码。此目录包含每种平台类型的子目录,如 armeabi、
      armeabi-v7a、arm64-v8a、x86、x86_64 和 mips。

    APK 还包含以下文件。在这些文件中,只有 AndroidManifest.xml 是必需的。

    • resources.arsc:包含已编译的资源。此文件包含 res/values/ 文件夹的所有配置中的 XML 内容。打包 工具会提取此 XML 内容,将其编译为二进制文件形式,并压缩内容。此内容包括语言字符串和样式,以 及未直接包含在 resources.arsc 文件中的内容(例如布局文件和图片)的路径。
    • classes.dex:包含以 Dalvik/ART 虚拟机可理解的 DEX 文件格式编译的类。
    • AndroidManifest.xml:包含核心 Android 清单文件。此文件列出了应用的名称、版本、访问权限和引用
      的库文件。该文件使用 Android 的二进制 XML 格式。

    Android Size Analyzer

    Android Size Analyzer 工具可轻松地发现和实施多种缩减应用大小的策略。

    AS 中搜索插件安装就可以了

    有时安装了插件也不会出来Analyze选项,此时进入已安装插件,关闭插件再重新开启即可。

    从菜单栏中依次选择 Analyze > Analyze App Size,对当前项目运行应用大小分析。分析 了项目后,系统会显示一个工具窗口,其中包含有关如何缩减应用大小的建议。

    2020-12-16 16.38.46.png

    启用资源缩减

    如果在应用的 build.gradle 文件中启用了资源缩减: shrinkResources,则 Gradle 在打包APK时可以自动 忽略未使用资源。 资源缩减只有在与代码缩减:minifyEnabled 配合使用时才能发挥作用。在代码缩减器移 除所有不使用的代码后,资源缩减器便可确定应用仍要使用的资源,从而在打包时优化这些资源 。

    signingConfigs {
            release {
                storeFile file('zcw.keystore')
                storePassword 'xxxxxx'
                keyAlias 'xxxxxx'
                keyPassword 'xxxxxx'
            }
        }
    
        buildTypes {
            release {
                signingConfig signingConfigs.release
                minifyEnabled true
                shrinkResources true
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
    

    shrinkResources,proguard-rules.pro

    proguard-rules.pro 除了混淆还有优化作用

    xxxxx

    自定义要保留的资源

    如果有想要特别声明需要保留或舍弃的特定资源,创建 res/raw/keep.xml , tools:keep 属性中指定每个要 保留的资源,在 tools:discard 属性中指定每个要舍弃的资源。这两个属性都接受以逗号分隔的资源名称列表。 还可以将星号字符用作通配符。

    使用Lint分析器

    lint工具是 Android Studio 中附带的静态代码分析器,可检测到 res/ 文件夹中未被代码引用的资源。 lint 工具不会扫描 assets/ 文件夹、通过反射引用的资源或已链接至应用的库文件。此外,它也不会移除 资源,只会提醒有未使用的资源。
    从菜单栏中依次选择 Analyze > Run Inspection By Name > 输入“unused resources” 回车执行。

    2020-12-16 17.29.08.png

    移除未使用的备用资源

    一般开发我们都会引入各种依赖,这些依赖可能包含各种备用资源,如中文、英文、日韩文等等。如果我 们不需要这些语言可以让他们不打包进入Apk

    2020-12-16 17.36.28.png

    大部分来自compact包

    我们可以配置一下resConfigs "zh-rCN"

    android {
        defaultConfig{
        ...
    resConfigs "zh-rCN"
        }
    }
    
    2020-12-16 17.47.27.png

    动态库打包配置

    对于arm64架构的设备,如果使用armv7a也能够兼容,但是不如使用arm64的so性能。随着现在arm64架构设备 渐渐成为主导。因此现在部分应用市场会根据设备提供不同架构的Apk安装。此时我们需要打包出针对arm64的 apk与armv7a的apk,可以使用productFlavor也可以使用APK分包:splits。

    可以配置

     
    android{
        defaultConfig{
          ndk{
            abiFilters "armeabi-v7a"
            } 
        }
    }
    

    对于第三方服务,如百度地图、Bugly等会提供全平台的cpu架构。进行了上面的配置之后,表示只会把armeabi- v7a打包进入Apk。从而减少APK大小。
    对于arm64架构的设备,如果使用armeabi-v7a也能够兼容,但是不如使用arm64的so性能。因此现在部分应用市 场会根据设备提供不同架构的Apk安装。此时我们需要打包出针对arm64的apk与armv7a的apk,可以使用
    productFlavor 。

    flavorDimensions "default"
        productFlavors {
            arm32 {
                dimension "default"
                ndk {
                    abiFilters "armeabi-v7a"
                }
            }
            arm64 {
                dimension "default"
                ndk {
                    abiFilters "arm64-v8a"
                }
            }
        }
    
      
    

    也可以使用:

      splits {
            abi {
                enable true
                reset()
                include 'arm64-v8a','armeabi-v7a'
    //      exclude 'armeabi'
                universalApk true  //是否打包一个包含所有so的apk
            }
        }
    

    图片的优化-使用矢量图

    矢量图可以创建与分辨率无关的图标和其他可伸缩媒体。使用这些图形可以极大地减少 APK 占用的空间。 矢 量图片在 Android 中以 VectorDrawable 对象的形式表示。借助 VectorDrawable 对象,100 字节的文件可以 生成与屏幕大小相同的清晰图片。
    不过,系统渲染每个 VectorDrawable 对象需要花费大量时间,而较大的图片则需要更长的时间才能显示在屏 幕上。因此,建议仅在显示小图片时使用这些矢量图。

    截屏2020-12-16 18.03.42.png

    生成png格式的图片用 svg 小图标的优化 < 200x200
    app gradle
    generatedDensities = ['xhdpi','xxhdpi']
    vectorDrawables.useSupportLibrary = true

    重复使用资源

    现在我们有一个矢量图:

    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24"
        android:viewportHeight="24"
        android:tint="?attr/colorControlNormal">
      <path
          android:fillColor="@android:color/white"
          android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
    </vector>
    

    如果我们需要让矢量图显示红色怎么办?这种情况,我们不需要再去创建一个新的矢量图。可以直接给 ImageView设置 android:tint 属性 来完成颜色的修改。

    <ImageView
    android:layout_width="50dp" android:layout_height="50dp" android:tint="@color/colorAccent" android:src="@drawable/tabbar_home_vector" />
    

    选择器

    如果需要让矢量图实现触摸变色。只需要创建selector,设置给tint即可

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item android:color="@color/colorPrimary" android:state_pressed="true" />
        <item android:color="@color/colorAccent" />
    </selector>
    
    
    
    <ImageView
    android:clickable="true" android:layout_width="50dp" 
    android:layout_height="50dp" 
    android:src="@drawable/tabbar_home_vector" 
    android:tint="@color/tabbar_home_tint_selector" 
    />
    

    其他

    使用精简版本的依赖:如protobuf-lite版本;对于分模块的库按需引入:如netty分模块引入; 主动移除无用代码(开启R8/Progurad自动移除)

    避免使用枚举,使用 @IntDef 代替。 开启资源混淆:

    支付宝删除Dex debugItem

    对于发布Google paly的应用选择使用:AAB

    相关文章

      网友评论

        本文标题:关于apk瘦身

        本文链接:https://www.haomeiwen.com/subject/woecyktx.html