性能优化专题九--应用包体缩减实战

首先推荐两个性能优化的最佳指南一个是官方指南--性能--缩减应用体量,另外一个是Android studio的官方指南--配置编译版本--压缩您的应用。涵盖了压缩应用体积的所有方面,

官网:https://developer.android.google.cn/topic/performance/reduce-apk-size

AS:https://developer.android.google.cn/studio/build/shrink-code

下面针对几个比较实用的。我们挑选出来我们实战下。

1、移除未使用的备用资源

Gradle 资源缩减器只会移除未由您的应用代码引用的资源,这意味着,它不会移除用于不同设备配置的备用资源。如有必要,您可以使用 Android Gradle 插件的 resConfigs 属性来移除应用不需要的备用资源文件。

例如,大部分应用其实并不需要支持几十种语言的国际化支持,如果您使用的是包含语言资源的库(如 AppCompat 或 Google Play 服务),则您的 APK 中将包含这些库中消息的所有已翻译语言的字符串,而无论应用的其余部分是否翻译为相同的语言。如果您只想保留应用正式支持的语言,则可以使用 resConfig 属性来指定这些语言。系统会移除未指定语言的所有资源。

以下代码段展示了如何设置只保留英语和法语的语言资源:

android {
        defaultConfig {
            ...
            resConfigs "en", "fr"
        }
    }
    

优化前有82个语言285.7KB大小:

优化过后,就只剩英文一种大小为221.8KB

扫描二维码关注公众号,回复: 11695308 查看本文章

2、压缩图片

  • 2.1使用webP格式

WebP 格式提供有损压缩(如 JPEG)以及透明度(如 PNG),与 JPEG 或 PNG 相比这种格式可以提供更好的压缩效果。

webp支持透明度,压缩比比jpg更高但显示效果却不输于jpg,官方评测quality参数等于75均衡最佳。 相对于jpg、png,webp作为一种新的图片格式,从Android 4.0+开始原生支持,但是不支持包含透明度,直到Android 4.2.1+才支持显示含透明度的webp,使用的时候要注意。

可以使用 Android Studio 将现有 BMP、JPG、PNG 或静态 GIF 图片转换为 WebP 格式。如需了解详情,请参阅使用 Android Studio 创建 WebP 图片。将所有图片转化为webp,选中图片文件夹,右键选中Convert to WebP即可

      

完成后可以到减小了100多KB,因为图片较少,所以效果可能没有那么明显,但是对原始图片的压缩率是很大的,达到了90%左右

原始:   转化webp:

  • 2.2使用tinypng有损压缩

 android打包本身会对png进行无损压缩,所以使用像tinypng这样的有损压缩是有必要的。 重点是Tinypng使用智能有损压缩技术,以尽量少的失真换来图片大小的锐减,效果非常好,强烈推荐。 Tinypng的官方网站:http://tinypng.com/

  • 2.3使用jpg格式

如果对于非透明的大图,jpg将会比png的大小有显著的优势,虽然不是绝对的,但是通常会减小到一半都不止。 在启动页,活动页等之类的大图展示区采用jpg将是非常明智的选择。

  • 2.4使用矢量图形 

可以使用矢量图形创建与分辨率无关的图标和其他可伸缩媒体。使用这些图形可以极大地减少 APK 占用的空间。 矢量图片在 Android 中以 VectorDrawable 对象的形式表示。借助 VectorDrawable 对象,100 字节的文件可以生成与屏幕大小相同的清晰图片。

不过,系统渲染每个 VectorDrawable 对象需要花费大量时间,而较大的图片则需要更长的时间才能显示在屏幕上。因此,请考虑仅在显示小图片时使用这些矢量图形。如需详细了解如何使用 VectorDrawable 对象,请参阅使用可绘制资源

  • 2.5缩小大图

如果经过上述步骤之后,你的工程里面还有一些大图,考虑是否有必要维持这样的大尺寸,是否能适当的缩小。 事实上,由于设计师出图的原因,我们拿到的很多图片完全可以适当的缩小而对视觉影响是极小的。

  • 2.6覆盖第三库里的大图

有些第三库里引用了一些大图但是实际上并不会被我们用到,就可以考虑用1x1的透明图片覆盖。 你可能会有点不舒服,因为你的drawable下竟然包含了一些莫名其妙的名称的1x1图片

3、so库优化,只保留armeabi-v7a

在使用一些三方库的时候,会集成大量的so文件到项目中,这些so文件都对应着不同的CPU架构。Android系统目前支持以下七种不同的CPU架构:ARMv5、ARMv7、x86、MIPS、ARMv8、MIPS64、x86_64,每一个CPU架构对应一个ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。

如果项目中包含第三方SDK或者自己使用了ndk,如果不进行配置会打包全cpu架构的动态库进入apk。目前市面上绝大部分的CPU架构都是 ARMv7/ARMv8,所以可以在gradle中加入配置,只保留v7,v8。对于真机,只需要保留一个armeabi(armeabi-v7a)就可以了,微信大佬就这么干的!这里不排除有极少数设备会Crash,可能和不同的so有一定的关系,请大家务必测试周全后再发布

原始gradle配置里面添加了较多的架构:

    ndk {
            //设置支持的SO库架构
            abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
        }

可以看到so的体积占用了apk体积的70%,我们手机绝大多数都是ARM架构,所以不需要添加这么多架构的so 

我们改为ARM64:

    ndk {
            //设置支持的SO库架构
            abiFilters "armeabi-v7a"
        }

可以看到包体减少了55%,从原来的22MB减少到9.9MB,效果是非常明显的

4、使用Lint检测

在Analyze中:

        

将检测出来没有被引用到的资源文件删除掉即可,但是需要注意提前备份,以防无法回退回来。lint检测可以避免删除掉反射使用的资源,因此是较为安全的方式。

按照这种方式完成后,apk大小从9.9MB缩小到了9.8MB:

注意:lint 工具不会扫描 assets/ 文件夹、通过反射引用的资源或已链接至应用的库文件。此外,它也不会移除资源,只会提醒您它们的存在。 

5、开启混淆

Android代码混淆,又称Android混淆,是一种Android APP保护技术,用于保护APP不被破解和逆向分析。
ProGuard的三大作用

  • 压缩:移除未被使用的类、属性、方法等,并且会在优化动作执行之后再次执行(因为优化后可能会再次暴露一些未被使用的类和成员。
  • 优化:优化字节码,并删除未使用的结构。
  • 混淆:将类名、属性名、方法名混淆为难以读懂的字母

6、开启删除无用资源(与Lint不同)

debug {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

shrinkResources 用来开启压缩无用资源,也就是没有被引用的文件(经过实测是drawable,layout,实际并不是彻底删除,而是保留文件名,但是没有内容),但是因为需要知道是否被引用所以需要配合mififyEnable使用,只有当两者都为true的时候才会起到真正的删
除无效代码和无引用资源的目的。与去除无用资源不同的是,比如某个java类没有用到,被混淆时删除了,而该类引入了layout资源 ,此时会将这个资源也压缩掉。

使用混淆最重要是需要配置混淆keep文件,完成后看下效果,包体从9.8MB减少到了7.7MB,效果还是很明显的:

具体我们来看下他是怎么缩小包体的:

打开资源文件xml可以看到后面有很多47B大小的布局文件:

这时我们随便找一个toast_layout.xml看下源文件和优化后的文件对比:

优化后:

优化前:

再看一个layout_pupup.xml对比:

优化后:

优化前:

可以看到,原来是将没有用到的文件在编译时,通过简单的字符替换掉了,而不是简单粗暴的将源文件删除掉,因此大大降低了包体大小

对比lint而言,lint的代码检测会直接将无用的资源文件以及ID删除掉,因此使用lint优化无用资源时需要提前备份好数据,以免无法恢复。

7、自定义要保留的资源

如果您有想要保留或舍弃的特定资源,请在项目中创建一个包含 <resources> 标记的 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" />
    

将该文件保存在项目资源中,例如,保存在 res/raw/keep.xml。构建系统不会将此文件打包到 APK 中。具体见官网

https://developer.android.google.cn/studio/build/shrink-code

具体使用方式,在raw下新建:keep.xml。里面填写不需要混淆的xml文件名称即可。

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/base_*" />
    <!--tools:keep="strict"-->

完成后上面toast_layout.xml以及layout_pupup.xml,就不会被X占位符替代掉了。

8、在 Android Studio 中使用 Android Size Analyzer

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

9、避免使用枚举

单个枚举会使应用的 classes.dex 文件增加大约 1.0 到 1.4KB 的大小。这些增加的大小会快速累积,产生复杂的系统或共享库。如果可能,请考虑使用 @IntDef 注释和代码缩减移除枚举并将它们转换为整数。此类型转换可保留枚举的各种安全优势。

猜你喜欢

转载自blog.csdn.net/cpcpcp123/article/details/106306443