Android Apk瘦身指南

目录

1. 为什么?

2. 包体分析

3. 常用方案

3.1 混淆代码

3.2 资源优化

3.2.1 使用Android Lint

3.2.2  清理无用资源

3.2.3 图片优化

3.2.4 支持插件化

4. 参考资料


1. 为什么?

APK越大,在下载安装过程中,耗费的流量会越多,安装等待的时间也会越长,安装包的大小对下载的失败率也有影响。而对于应用本身,就意味着下载转化率会越低,在竞品中,用户更愿意选择功能多,体验号,安装包最小的应用。因此apk的瘦身优化也很重要。

 

2. 包体分析

在Android Studio工具栏里,打开build–>Analyze APK, 选择要分析的APK包 

  • res 主要存放图片资源
  • lib 主要存放so库,各个cpu架构
  • classes.dex是java源码编译后生成的java字节码文件,因方法限制拆分了多个dex
  • assets 存放不需要编译处理的文件
  • resources.arsc是编译后的二进制资源文件,包括图片,文本索引等
  • META-INF 签名信息
  • AndroidManifest.xml 描述配置文件

可以看到占用空间的主要是代码、图片、资源和lib以及assert文件。

瘦身的主要方向:精简代码、压缩图片、去除无用库、减少asserts文件(或大小)。

 

3. 常用方案

3.1混淆代码

代码混淆 ProGuard是一个开源的Java代码混淆器(obfuscation),并且默认集成到Android SDK中,它具有以下功能:

  • 压缩:移除无效的类、属性、方法等。
  • 优化:移除没用的结构。
  • 混淆:把类名、属性名、方法名替换为一到两个字母。

ProGuard常用参数 ProGuard配置参数非常多,以下列出一些常用的参数,具体的参数可参考可参考ProGuard manual

  • 1. ProGuard配置
    • -include {filename}:从给定的文件中读取配置参数。
    • -basedirectory {directoryname}:指定基础目录为以后对应的档案名称。
    • -injars {class_path}:指定要处理的应用程序jar、war、ear和目录。
    • -outjars {class_path}:指定处理完后要输出的jar、war、ear和目录的名称。
    • -libraryjars {classpath}:指定要处理的应用程序jar、war、ear和目录所需的程序库文件。
    • -dontskipnonpubliclibraryclasses:指定不忽略非公共的库类。
    • -dontskipnonpubliclibraryclassmembers:指定不忽略包可见的库类的成员。
  • 2. 保留选项
    • -keep {Modifier} {class_specif ication}:保护指定的类文件和类的成员。
    • -keepclassmembers {modifier} {class_specification}:保护指定类的成员。
    • -keepclasseswithmembers {class_specif ication}:保护指定的类和类的成员,但条件是所有指定的类和类成员要存在。
    • -keepnames {class_specification}:保护指定的类和类的成员名称(如果不需要混淆)。
    • -keepclassmembernames {class_specification}:保护指定的类的成员名称(不需要混淆)。
    • -keepclassmembernames {class_specification}:保护指定的类的成员名称(不需要混淆)。
    • -keepclasseswithmembernames {class_specification}:保护指定的类和类的成员名称,如果所有指定的类成员出席(在压缩步骤之后)。
    • -printseeds {filename}:列出类和类的成员-keep选项的清单,标准输出到给定的文件。
  • 3. 压缩
    • -dontshrink:不压缩输入的类文件。
    • -printusage {filename}:输出无用文件。
  • 4. 优化
    • -dontoptimize:不优化输入的类文件。
    • -assumenosideeffects {class_specif ication}:优化时假设指定的方法,没有任何副作用。
    • -allowaccessmodif ication:优化时允许访问并修改有修饰符的类和类的成员。 (5)混淆
    • -dontobfuscate:不混淆输入的类文件。
    • -printmapping {filename}:输出映射表。
    • -applymapping {filename}:重用映射增加混淆。
    • -obfuscationdictionary {filename}:使用给定文件中的关键字作为要混淆方法的名称。
    • -overloadaggressively:混淆时应用侵入式重载。
    • -useuniqueclassmembernames:确定统一的混淆类的成员名称来增加混淆。
    • -renamesourcef ileattribute {string}:设置源文件中给定的字符串常量。

开启minifyEnabled混淆代码

在Android Studio中使用ProGuard

按照上一节的语法规则编写则编写proguard-rules.pro后,需要在build.gradle中配置,同时设置minifyEnabled为true,在编译工程时自动混淆代码,可大大减小APP大小,代码如下:

minifyEnabled 用开开启删除无用代码,比如没有引用到的代码

buildTypes {
    debug {
        minifyEnabled false
    }
    release {
        signingConfig signingConfigs.release

        minifyEnabled true
        proguardFiles proguard-rules.pro'
    }
}

 

3.2 资源优化

3.2.1 使用Android Lint

Android Lint工具可以用来扫描布局层级,Android Lint也能扫描到没有使用的资源文件。

  • 资源文件最少化

        系统根据不同分辨率会自动加载不同图片资源(ldpi、mdpi、tvdpi、hdpi、xhdpi、xxhdpi等),如果为了适配不同屏幕,每个文件夹都放一套图,对安装包大小的影响非常严重,虽然Android支持这么多的屏幕密度,但是不代表应用为每一个屏幕都提供一套资源,在这方面可以参考以下几个建议:

  •  尽量使用一套图片资源,遇到一些图片在不同分辨率手机上变化差异过大的情况时,再考虑在相应文件夹下放入这个特定的图片。
  • 使用一套图、一套布局、多套dimens.xml文件,在使用最小资源的情况下,解决多分辨率适配。
  • 减少项目中的预设图片,预置图片改成服务器下发,尽可能将程序与资源分离。
  • 删除无用so包
    • armable-v7下so包
      • 基本上armble的so也是兼容armable-v7的,armable-v7a的库会对图形渲染方面有很大的改进,如果没有这方面的要求,可以精简。
    • x86包下的so包
      • x86包下的so在x86型号的手机是需要的,如果产品没用这方面的要求也可以精简。建议实际工作的配置是只保留armable、armable-x86下的so文件,算是一个折中的方案。
    • 删除无用的语言资源
      • 大部分应用其实不需要支持多种语言的国际化,可以配置gradle的语言,比如国内应用只支持中文。
android {
    defaultConfig {
        resConfigs "zh"
    }
}

 

3.2.2  清理无用资源

  • Android 工具
    • 使用AndroidStuido -> Refactor -> Remove Unused Resources 筛选出无用的资源文件

         

 

  • 避免重复库   
    • 在应用开发中,比如几种图片开源库,可能一个开源库不能支持所有业务功能,而需要用到多个开源库,若一个应用放了两个图片库,不但增加了安装包大小,也增加了维护成本,此时,建议选择性价比更高、更适合当前应用业务需求的一个,在这个基础上增加相应的功能,扩展当前的图片库,而非引入新的开源库。 
  • 清理三方库和冗余代码

     

    • 版本迭代过程中,因为删减功能经常有冗余代码和第三方库留下,这或多或少都会增加包体,这种情况没有捷径,只能每个文件查找,这是苦力活。还有要查看第三方库有没可能精简,比如谷歌分基础、广告和分析包,网络库、supportv4等,这个就具体情况具体分析。
    • (比如使用ShareSDK的分享功能,图标和默认的分享弹窗都没有用到,引用时可以根据需求删减)

3.2.3 图片优化

  • Android应用的资源中主要用到两种格式的图片:PNG和JPG。
    • PNG(Portable Network Graphic Format)用来存储灰度图像时,灰度图像的深度可多到16位,存储彩色图像时,彩色图像的深度可多到48位,并且可存储多达16位的透明通道数据。
    • JPG(JPEG)图片以24位颜色存储单个位图。JPEG是与平台无关的格式,支持最高级别的压缩,但这种压缩有损耗,并且没有透明通道。
  • 在开发Android应用时,PNG资源图片在应用打包过程中,资源打包工具AAPT(Android Asset Packaging Tool)自动对PNG图片做压缩处理,但减小的大小比较有限,除了靠工具自动打包,一般还能采用以下两种方式。
    •  降低图片色彩位数 如果使用的图片色彩比较单一,可以降低图像位数来减少图片大小。
    • PNG图片压缩工具

对于非透明的大图,JPG文件会比PNG文件小很多,通常会减小到一半以上。一般使用于应用中的一些闪屏介绍页,全图背景等。

  • 使用tinyPng压缩
    • TinyPNG工具只支持上传PNG图片到官网上压缩,然后下载保存,在保持alpha通道的情况下对PNG的压缩可以达到1/3之内,而且用肉眼基本上分辨不出压缩的损失.
    • Tinypng的官方网站:http://tinypng.com/
  • 覆盖三方库里的大图
    • 有些第三库里引用了一些大图但是实际上并不会被我们用到,就可以考虑用1x1的透明图片覆盖。
  • 使用shape背景
    • 特别是在扁平化盛行的当下,很多纯色的渐变的圆角的图片都可以用shape实现,代码灵活可控,省去了大量的背景图片。
  • 使用着色方案
    • 很多图片相似,只是颜色不同,可以通过着色方案减少图片的使用。 
  • 使用旋转方案
    • 很多图片相似,只是方向不同,可以通过旋转图片减少图片的使用。  

 

3.2.4 支持插件化

插件化除了可以解决方法数超标的问题,同时如果插件放到服务器,在需要时再下载下来,可以减少安装包大小。但是需要注意的是,因为使用时需要临时下载,所以建议在用户使用率不高的功能模块上使用,或者使用预加载。

 

4. 参考资料

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值