【移动应用开发技术】Andriod APK体积优化_第1页
【移动应用开发技术】Andriod APK体积优化_第2页
【移动应用开发技术】Andriod APK体积优化_第3页
【移动应用开发技术】Andriod APK体积优化_第4页
【移动应用开发技术】Andriod APK体积优化_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】AndriodAPK体积优化

随着项目的不断迭代,功能越来越多,构建出来的apk文件的大小也会越来越大,这样会导致在移动网络情况下下载时,使用的网络流量会增大,并且apk太大,导致下载的时间也增加,虽然当前每个人的手机的流量都很多,对用户流量影响不大,但是据一些网站统计,安装包越大,用户的转化率是在降低的,所以减少apk的体积,可以让更多的用户愿意去下载和体验产品。所以,对apk体积进行瘦身还是很有必要的。在对apk体积进行瘦身前,最好保证这个apk已经是经过Proguard优化过的。经过了Proguard对apk进行压缩,优化,混淆后,在去对这个已经进行优化过的apk进行瘦身更有意义。下面是项目总常用的对apk进行优化的方式:在app的主module下的gradle文件中做如下配置buildTypes

{ release

{ //开启代码混淆 minifyEnabled

true //Zipalign优化 zipAlignEnabled

true //移除无用的resource文件 shrinkResources

true proguardFiles

getDefaultProguardFile('proguard-android.txt'),

'' }}使用shrinkResources进行移除,配合//Zipalign优化使用shrinkResources必须先开启代码混淆minifyEnabled关于混淆相关的配置,不是本文重点,下面进行简单介绍proguard-android.txt文件中的常用的混淆配置信息如下:#

This

is

a

configuration

file

for

ProGuard.#

/index.html#manual/usage.html-dontusemixedcaseclassnames-dontskipnonpubliclibraryclasses-verbose#

Optimization

is

turned

off

by

default.

Dex

does

not

like

code

run#

through

the

ProGuard

optimize

and

preverify

steps

(and

performs

some#

of

these

optimizations

on

its

own).-dontoptimize-dontpreverify#

Note

that

if

you

want

to

enable

optimization,

you

cannot

just#

include

optimization

flags

in

your

own

project

configuration

file;#

instead

you

will

need

to

point

to

the#

"proguard-android-optimize.txt"

file

instead

of

this

one

from

your#

perties

file.-keepattributes

*Annotation*-keep

public

class

com.google.vending.licensing.ILicensingService-keep

public

class

com.android.vending.licensing.ILicensingService#

For

native

methods,

see

/manual/examples.html#native-keepclasseswithmembernames

class

*

{

native

<methods>;}#

keep

setters

in

Views

so

that

animations

can

still

work.#

see

/manual/examples.html#beans-keepclassmembers

public

class

*

extends

android.view.View

{

void

set*(***);

***

get*();}#

We

want

to

keep

methods

in

Activity

that

could

be

used

in

the

XML

attribute

onClick-keepclassmembers

class

*

extends

android.app.Activity

{

public

void

*(android.view.View);}#

For

enumeration

classes,

see

/manual/examples.html#enumerations-keepclassmembers

enum

*

{

public

static

**[]

values();

public

static

**

valueOf(java.lang.String);}-keepclassmembers

class

*

implements

android.os.Parcelable

{

public

static

final

android.os.Parcelable$Creator

CREATOR;}-keepclassmembers

class

**.R$*

{

public

static

<fields>;}#

The

support

library

contains

references

to

newer

platform

versions.#

Dont

warn

about

those

in

case

this

app

is

linking

against

an

older#

platform

version.

We

know

about

them,

and

they

are

safe.-dontwarn

android.support.**-dontusemixedcaseclassnames表示混淆时不使用大小写混合类名。-dontskipnonpubliclibraryclasses表示不跳过library中的非public的类。-verbose表示打印混淆的详细信息。-dontoptimize表示不进行优化,建议使用此选项,因为根据proguard-android-optimize.txt中的描述,优化可能会造成一些潜在风险,不能保证在所有版本的Dalvik上都正常运行-dontpreverify表示不进行预校验。这个预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度。-keepattributesAnnotation表示对注解中的参数进行保留。更多关于proguard混淆规则的介绍,请参考Android安全***战,反编译与混淆技术完全解析(下)大部分应用其实并不需要支持几十种语言的国际化支持,比如国内应用只支持中文,配置如下:defaultConfig

{

...

//只保留指定和默认的资源

//resConfigs('zh-rCN','ko')

resConfigs

"zh"}经过上面的配置后,打包出的apk,在进行apk的分析,这样效果会更好。Androidstudio从2.2开始就提供了分析apk文件的功能,在AndroidStudio工具栏里,打开build–>AnalyzeAPK,选择要分析的APK包,或者直接将apk包拖到AS中。下图是对apk分析的结果:但是在看上面这个图之前,需要先了解各个部分的含义:lib这个目录存放应用程序依赖的用C/C++编写的native库文件,该目录下可以包含3种类型,根据CPU类型的不同加载不同目录下的so库,这3种类型分别为ARM架构、MIPS架构、X86架构。所示,不同的CPU架构设备在应用程序运行时,根据CPU架构类型加载对应的目录,每个目录可以存放很多对应版本的so库,同时这个目录结构固定,用户必须严格按照这个目录存放自己的so文件。assetsassets目录可以根据应用需求存放任何文件夹架构,如配置文件、资源文件(如WebView本地资源、图片资源等),这些文件的内容在程序运行过程中可以通过AssetManager类获得。和res的不同点在于,res目录下的文件会在.R文件中生成对应的资源IDassets不会自动生成对应的ID,而是通过AssetManager类的接口获取。resres是resource的缩写,这个目录存放资源文件,在这个文件夹下的所有文件都会生成对应的ID映射到Android工程的.R文件中,访问时可以直接使用资源。classes.dexJava可执行程序,需要先把Java文件编译成class文件,字节码都保存在class文件中,Java虚拟机可以通过解释并执行这些class文件。而Dalvik虚拟机在Java虚拟机进行了优化,执行的是Dalvik字节码,这些Dalvik字节码由Java字节码转换而来,一般情况下,Android应用在打包时通过AndroidSDK中的dx工具将Java字节码转换为Dalvik字节码。dx工具可以对多个class文件进行合并重组、优化,达到减小体积、缩短运行时间的目的。META-INF保存应用的签名信息,签名信息可以验证APK文件的完整性。AndroidSDK在打包APK时会计算APK包中所有文件的完整性,并且把这些完整性保存到META-INF文件夹下,应用程序在安装时首先根据META-INF文件夹校验APK的完整性,这样可以保证APK中的每一个文件都不能被篡改。以此来确保APK应用程序不被恶意修改或者病毒感染,有利于确保Android应用的完整性和系统的安全性。META-INF目录下包含的文件有CERT.RSA、CERT.DSA、CERT.SF和MANIFEST.MF,其中CERT.RSA是开发者利用私钥对APK进行签名的签名文件,CERT.SF、MANIFEST.MF记录了文件中文件的SHA-1哈希值。AndroidManifest.xmlAndroid应用程序的配置文件是用来描述Android应用“整体资讯”的设定文件,简单来说,相当于Android应用向Android系统“自我介绍”的配置文件。Android系统可以根据这个“自我介绍”完整地了解APK应用程序的资讯,每个Android应用程序都必须包含一个AndroidManifest.xml文件,且它的名字固定的,不能修改。在开发Android应用程序时,一般都在AndroidManifest.xml中注册代码中的每个Activity、Service、Provider和Receiver,只有这样系统才能启动对应的组件,另外这个文件还包含一些权限声明以及使用的SDK版本信息等。rsources.arsc记录资源文件和资源ID之间的映射关系,用来根据资源ID寻找资源。Android的开发是分模块的,res目录专门用来存放资源文件,在代码中需要调用资源文件时,只需要调用findviewbyId()就可以得到资源文件,每当在res文件夹下放一个文件,aapt就会自动生成对应的ID保存在.R文件中,调用这个ID就可以,但是只有这个ID还不够,.R文件只是保证编译程序不报错,实际上在程序运行时,系统要根据ID寻找对应的资源路径,而resources.arsc文件就是用来记录这些ID和资源文件位置对应关系的文件。通过上图中对apk文件中各个部分的文件占比的分析,可以看到占用空间的主要是代码、图片、资源和lib和assert文件,主要方向精简代码、压缩图片、去除无用的库、减少asserts里面文件。so文件优化首先对lib文件夹进行瘦身:lib文件夹中存放的都是so文件,so文件存放到不同的cpu架构的文件夹中,之所以这样处理,就需要了解so的编译类型,Android只支持3种cpu架构分为:arm,mips,x86,目前用的最多的是arm体系cpu,x86和mips体系的很少用到了。arm体系中,又分32位和64位armeabi/armeabi-v7a:这个架构是arm类型的,主要用于Android4.0之后的,cpu是32位的,其中armeabi是相当老旧的一个版本,缺少对浮点数的硬件支持,基本已经淘汰,可以不用考虑了。arm64-v8a:这个架构是arm类型的,主要是用于Android5.0之后,cpu是64位的。平时项目中引入第三方的so文件时,第三方会根据cpu的架构编译成不同类型的so文件,项目引入这些so文件时,会将这些文件分别放入jniLibs目录下的arm64-v8a,armeabi-v7a等这些目录下,其实对于arm体系的so文件,没这个必要,因为arm体系是向下兼容的,比如32位的so文件是可以在64位的系统上运行的。Android上每启动一个app都会创建一个虚拟机,Android64位的系统加载32位的so文件时,会创建一个64位的虚拟机的同时,还会创建一个32位的虚拟机,这样就能兼容32位的app应用了。鉴于兼容的原理,在app中,可以只保留armeabi-v7a版本的so文件就足够了。64位的操作系统会在32位的虚拟机上加载这个它。这样就极大的精简了app打包后的体积。虽然这样可以精简apk的体积,但是,在64位平台上运行32位版本的ART和Android组件,将丢失专为64位优化过的性能(ART,webview,media等等)所以,更好的方法是,为相应的abi打对应的apk包,这样就可以为不同abi版本生成不同的apk包。所以可以通过如下配置,只保留armeabi-v7a版本的so文件在module的build.gradle文件中defaultConfig节点做下面的配置:

``` //配置so库架构(真机:

arm

,模拟器

x86

) defaultConfig

{

...

ndk

{

//abiFilters

"armeabi",

"armeabi-v7a"

abiFilters

'armeabi-v7a'

}

} ``` 完成这个步骤后,就可以看到,apk包中的lib中,只剩下armeabi-v7a文件夹中的so文件了。重新编译so文件,用更小的库代替很多第三方我们导入进来只用到其中很小一部分功能,大部分功能都是我们用不上的。这时候我们找到源代码,将我们需要的那部分代码提取出来,重新编译成新的so文件,再导入到我们项目中。通过插件化,动态加载so库文件。assets目录中的优化如果存放的资源文件实在太大,可以考虑将部分不是立刻用到的资源文件,从网络上下载到本地。这样也能够减少asstes目录的大小。res目录优化:手动lint检查,手动删除无用的资源文件。版本迭代过程中,不但有废弃代码冗余,肯定会有无用的图片存在。在build.gradle里面配置shrinkResourcestrue,在打包的时候会自动清除掉无用的资源,但经过实验发现打出的包并不会,而是会把部分无用资源用更小的东西代替掉。注意,这里的“无用”是指调用图片的所有父级函数最终是废弃代码,而shrinkResourcestrue只能去除没有任何父函数调用的情况,真正起效果只能通过AndroidStudio自带的“RemoveUnusedResources”小插件来实现了。更人性化是该查找结果可以“一键删除”。当然,可能图片是经过反射或字符拼接等方式获取,所以这个检测列表也不是全对,删除后很大概率编译失败或部分页面挂死、无图等问题,这个无解,工具还没智能到这个地步,你只能一遍又一遍“编译—解决部分问题—再编译再”。使用tinypng等图片压缩工具对图片进行压缩TinyPNG工具只支持上传PNG图片到官网上压缩,然后下载保存,在保持alpha通道的情况下对PNG的压缩可以达到1/3之内,而且用肉眼基本上分辨不出压缩的损失.。Tinypng的官方网站:/大部分的图片使用webp格式替代webp支持透明度,压缩比比jpg更高但显示效果却不输于jpg,官方评测quality参数等于75均衡最佳。相对于jpg、png,webp作为一种新的图片格式,限于android的支持情况暂时还没用在手机端广泛应用起来。从Android4.0+开始原生支持,但是不支持包含透明度,直到Android4.2.1+才支持显示含透明度的webp,使用的时候要特别注意。官方介绍:/speed/webp/docs/precompiled尽量少使用帧动画,帧动画需要的图片较多,并且很占内存,建议使用属性动画替代。使用一套资源对于绝大对数APP来说,只需要取一套设计图就足够了。鉴于现在分辨率的趋势,建议取1080p的资源,放到xxhdpi目录,在加上一些屏幕适配的处理,基本能够适配大部分的手机。相对于多套资源,只使用1080P的一套资源,在视觉上差别不大,很多大公司的产品也是如此,但却能显著的减少资源占用大小,顺便也能减轻设计师的出图工作量了。使用jpg格式如果对于非透明的大图,jpg将会比png的大小有显著的优势,虽然不是绝对的,但是通常会减小到一半都不止。在启动页,活动页等之类的大图展示区采用jpg将是非常明智的选择。缩小大图如果经过上述步骤之后,你的工程里面还有一些大图,考虑是否有必要维持这样的大尺寸,是否能适当的缩小。事实上,由于设计师出图的原因,我们拿到的很多图片完全可以适当的缩小而对视觉影响是极小的。覆盖第三库里的大图有些第三库里引用了一些大图但是实际上并不会被我们用到,就可以考虑用1x1的透明图片覆盖。你可能会有点不舒服,因为你的drawable下竟然包含了一些莫名其妙的名称的1x1图片使用微信资源压缩打包工具(AndResGuard)矢量图矢量图是由点与线组成,和位图不一样,它再放大也能保持清晰度,而且使用矢量图比位图设计方案能节约30~40%的空间,现在谷歌一直在强调扁平化方式,矢量图可很好的契合该设计理念。优势(1)占用存储空间小(2)无极拉伸不会出现锯齿,可以照顾不同尺寸的机型(3)AndroidStudio自带很多资源,减小UI工作量劣势(1)只支持5.0及以上系统(2)与位图相比多了一层计算,需消耗更多性能(3)不支持.9图(4)不适合表现真实照片和复杂图形,一般使用在简单的icon和动画上

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论