Android之APK文件瘦身几种方式

APK越大,在下载安装过程中,他们耗费的流量会越多,安装等待时间也会越长,效率就比较地下,从下载开始用户的体验效果就很不好。所以

在Android Studio工具栏里,打开build–>Analyze APK, 选择要分析的APK包  
可以看到占用空间的主要是代码、图片、资源和lib和assert文件,主要方向精简代码、压缩图片、去除无用的库、减少asserts里面文件。

主要介绍几种apk瘦身方案:

一、只使用一套资源

对于绝大对数APP来说,只需要取一套设计图就足够了。鉴于现在分辨率的趋势,建议取720p的资源,放到xhdpi目录。 
相对于多套资源,只使用720P的一套资源,在视觉上差别不大,很多大公司的产品也是如此,但却能显著的减少资源占用大小,顺便也能减轻设计师的出图工作量了。 
注意,这里不是说把不是xhdpi的目录都删除,而是强调保留一套设计资源就够了。

二、开启minifyEnabled混淆代码

在gradle使用minifyEnabled进行Proguard混淆的配置,可大大减小APP大小:

android {
    buildTypes {
        release {
            minifyEnabled true
        }
    }
}

在proguard中,是否保留符号表对APP的大小是有显著的影响的,可酌情不保留,但是建议尽量保留用于调试。

参数:

-include {filename}    从给定的文件中读取配置参数   
-basedirectory {directoryname}    指定基础目录为以后相对的档案名称   
-injars {class_path}    指定要处理的应用程序jar,war,ear和目录   
-outjars {class_path}    指定处理完后要输出的jar,war,ear和目录的名称   
-libraryjars {classpath}    指定要处理的应用程序jar,war,ear和目录所需要的程序库文件   
-dontskipnonpubliclibraryclasses    指定不去忽略非公共的库类。   
-dontskipnonpubliclibraryclassmembers    指定不去忽略包可见的库类的成员。

保留选项

-keep {Modifier} {class_specification}    保护指定的类文件和类的成员   
-keepclassmembers {modifier} {class_specification}    保护指定类的成员,如果此类受到保护他们会保护的更好   
-keepclasseswithmembers {class_specification}    保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。   
-keepnames {class_specification}    保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)   
-keepclassmembernames {class_specification}    保护指定的类的成员的名称(如果他们不会压缩步骤中删除)   
-keepclasseswithmembernames {class_specification}    保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)   
-printseeds {filename}    列出类和类的成员-keep选项的清单,标准输出到给定的文件  

压缩

-dontshrink    不压缩输入的类文件   
-printusage {filename}   
-whyareyoukeeping {class_specification}  

优化

-dontoptimize    不优化输入的类文件   
-assumenosideeffects {class_specification}    优化时假设指定的方法,没有任何副作用   
-allowaccessmodification    优化时允许访问并修改有修饰符的类和类的成员  

混淆

-dontobfuscate    不混淆输入的类文件   
-printmapping {filename}   
-applymapping {filename}    重用映射增加混淆   
-obfuscationdictionary {filename}    使用给定文件中的关键字作为要混淆方法的名称   
-overloadaggressively    混淆时应用侵入式重载   
-useuniqueclassmembernames    确定统一的混淆类的成员名称来增加混淆   
-flattenpackagehierarchy {package_name}    重新包装所有重命名的包并放在给定的单一包中   
-repackageclass {package_name}    重新包装所有重命名的类文件中放在给定的单一包中   
-dontusemixedcaseclassnames    混淆时不会产生形形色色的类名   
-keepattributes {attribute_name,...}    保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.  
-renamesourcefileattribute {string}    设置源文件中给定的字符串常量  

三、开启shrinkResources将无用的一些资源全部去除

在gradle使用shrinkResources去除无用资源,效果非常好。

android {
    buildTypes {
        release {
            shrinkResources true
        }
    }
}

四、清理无用资源

有废弃代码冗余,肯定会有无用的图片存在。在build.gradle 里面配置shrinkResources true,在打包的时候会自动清除掉无用的资源,但经过实验发现打出的包并不会,而是会把部分无用资源用更小的东西代替掉。注意,这里的“无用”是指调用图片的所有父级函数最终是废弃代码,而shrinkResources true 只能去除没有任何父函数调用的情况,真正起效果只能通过Android Studio自带的 “Remove Unused Resources”小插件来实现了

五、使用tinypng有损压缩

TinyPNG工具只支持上传PNG图片到官网上压缩,然后下载保存,在保持alpha通道的情况下对PNG的压缩可以达到1/3之内,而且用肉眼基本上分辨不出压缩的损失. 

六、使用jpg格式

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

七、缩小大图

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

八、使用微信资源压缩打包工具

微信资源压缩打包工具通过短资源名称,采用7zip对APP进行极致压缩实现减小APP的目标,效果非常的好,强烈推荐。

建议开启7zip,注意白名单的配置,否则会导致有些资源找不到,官方已经发布AndResGuard到gradle中了,比较方便:

示例:

apply plugin: 'AndResGuard'
buildscript {
    dependencies {
        classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.1.7'
    }
}
andResGuard {
    mappingFile = null
    use7zip = true
    useSign = true
    keepRoot = false
    // add .R.drawable.icon into whitelist.
    // because the launcher will get thgge icon with his name
    def packageName = 
            whiteList = [
    //for your icon
    packageName + ".R.drawable.icon",
            //for fabric
            packageName + ".R.string.com.crashlytics.*",
            //for umeng update
            packageName + ".R.string.umeng*",
            packageName + ".R.string.UM*",
            packageName + ".R.string.tb_*",
            packageName + ".R.layout.umeng*",
            packageName + ".R.layout.tb_*",
            packageName + ".R.drawable.umeng*",
            packageName + ".R.drawable.tb_*",
            packageName + ".R.anim.umeng*",
            packageName + ".R.color.umeng*",
            packageName + ".R.color.tb_*",
            packageName + ".R.style.*UM*",
            packageName + ".R.style.umeng*",
            packageName + ".R.id.umeng*"
    ]
    compressFilePattern = [
    "*.png",
            "*.jpg",
            "*.jpeg",
            "*.gif",
            "resources.arsc"
    ]
    sevenzip {
        artifact = 'com.tencent.mm:SevenZip:1.1.7'
        //path = "/usr/local/bin/7za"
    }
}

会生成一个andresguard/resguard的Task,自动读取release签名进行重新混淆打包。

九、可使用矢量图

矢量图是由点与线组成,和位图不一样,它再放大也能保持清晰度,而且使用矢量图比位图设计方案能节约30~40%的空间,现在谷歌一直在强调扁平化方式,矢量图可很好的契合该设计理念。 
—优势 
(1)占用存储空间小 
(2) 无极拉伸不会出现锯齿,可以照顾不同尺寸的机型 
(3)Android Studio自带很多资源,减小UI工作量 
—劣势 
(1) 只支持5.0及以上系统 
(2) 与位图相比多了一层计算,需消耗更多性能 
(3) 不支持.9图 
(4)不适合表现真实照片和复杂图形,一般使用在简单的icon和动画上

十、使用shape背景

特别是在扁平化盛行的当下,很多纯色的渐变的圆角的图片都可以用shape实现,代码灵活可控,省去了大量的背景图片。

十一、使用selector文件着色方案

相信你的工程里也有很多selector文件,也有很多相似的图片只是颜色不同,通过着色方案我们能大大减轻这样的工作量,减少这样的文件。 
借助于android support库可实现一个全版本兼容的着色方

你可能感兴趣的:(Android,apk瘦身)