안드로이드 개발 성능 최적화 건조, 당신의 APK 얇은 88 %를 보자

처음에 글;

비즈니스, 코드의 복잡성이 증가, 자원은 지속적으로 당신은 또한 APP의 크기를 증가하고, 증가하고있다. 사용자의 관점에서 APP의 메가 바이트의 모든 회전 수만의 얼굴이 아닌 와이파이의 경우 다운로드 여전히 주저, 더 다운로드 당신은 사용자를 잃을 수 있습니다. 회사 수준에 관한에서 트래픽이 돈이다, APP의 크기가 특히 중요합니다 줄일 수 있습니다. 개발자 측면에서이 기술이 약간 그리드 전체 힘이 될 것입니다 마스터했다.

아도는 주제를 시작합니다.

그런 것들은 1.APK 구조

너 자신을 알라, 자신 만이 알 수 있습니다. 우리에게 도움이 응용 프로그램 APK의 구조를 이해합니다. APK 파일은 응용 프로그램을 구성하는 모든 파일을 포함하는 ZIP 아카이브 구성,로 구성되어 있습니다. 이 파일은 자바 클래스 파일, 리소스 파일 및 컴파일 된 자원을 포함하는 파일이 포함됩니다.

APK는 다음 디렉토리를 포함합니다

  • META-INF는 / : CERT.SF 및 CERT.RSA 서명 파일 및 MANIFEST.MF 매니페스트 파일이 포함되어 있습니다.
  • 자산 / : 응용 프로그램 자원 AssetManager 검색 대상을 사용할 수있는 응용 프로그램이 포함되어 있습니다.
  • 입술은 / : 자원 resources.arsc로 컴파일하지 포함되어 있습니다.
  • LIB는 / : 프로세서 고유 소프트웨어 층은 컴파일 된 코드를 포함하는 방법. 이 디렉토리는 armeabi, armeabi-V7A, arm64-v8a, 86, x86_64에, 그리고 MIPS 등의 각 플랫폼의 하위 디렉토리가 포함되어 있습니다.
  • resources.arsc : 컴파일 된 자원을 포함. 이 파일은 모든 XML 구성의 고해상도 / 값 / 폴더의 내용이 포함되어 있습니다. XML 내용을 추출하는 도구를 포장하는 바이너리 형식과 내용 아카이브로 컴파일됩니다. 이것은 언어 문자열과 스타일, 그리고 예를 들어, 직접 경로 resources.arsc 파일에 포함 된 내용, 이미지 레이아웃 파일이 포함되어 있습니다.
  • classes.dex는 : 달빅 / ART 가상 머신 파일 형식 이해 DEX 컴파일 된 클래스가 포함되어 있습니다.
  • AndroidManifest.xml에 : 안드로이드 매니페스트 파일은 코어가 포함되어 있습니다. 이 문서는 참조 라이브러리에 응용 프로그램 이름, 버전 및 액세스를 나열합니다. 안드로이드 XML 형식을 사용하여 이진 파일.
  • Taobao의의 압축 해제 후 APP의 파일 디렉토리를 살펴 보자

일반적으로, APK 구조는 일반 classes.dex, LIB, 고해상도, 자산 등의 파일이나 디렉토리의 비교적 큰 부분이다. 다음은이 네 가지 경우에 대해 설명 할 것 그래서.

또한, 우리는 APK APK 분석기로 분석 할 수 있습니다

classes.dex 감소합니다

classes.dex 모든 자바 코드가 포함되어 있습니다. 응용 프로그램을 컴파일 할 때, Gradle을 하나의 파일 classes.dex로 덱스 파일에의 .class 파일 모듈 및 그 모든 파일을 변환합니다.

Classes.dex 하나의 파일은 64K 방법에 대해 보유 할 수 있습니다. 이 한계에 도달하면, 당신은 당신의 프로젝트에 multidexing 사용하도록 설정해야합니다. 이 방법의 나머지 부분을 저장하는 또 다른 classes1.dex 파일을 만듭니다. classes.dex 파일의 수에 의해 결정 그래서 당신은 방법을 계산합니다.

세 번째 라이브러리의 사용을 줄입니다

잦은 변화와 비즈니스의 복잡성 증가, 우리는 때때로 우리는 함수의 작은 부분을 사용할 수 있습니다 타사 Libaray을 사용하는 경향이 시간 필요가 조심스럽게 완전한 레퍼런스로 간주합니다. 달성하기 위해 자신을 참조하는 선호 개발의 관점에서 내 경험,에서뿐만 아니라 우리는 타사 라이브러리를 소개하고 싶지 않아요.

열거를 피하십시오

열거 응용 프로그램 파일 classes.dex 크기 1.4 KB 1.0에 대한 추가 할 수 있습니다. 이러한 추가 신속하게 복잡한 시스템 또는 공유 라이브러리에 쌓일 수 있습니다. , @IntDef 노트를 사용하는 것이 가능하면 변환이 유형의 형태 보증 된 열거의 모든 장점을 유지합니다.

사용 ProGuard에서

코드 압축 build.gradle 파일의 다음 코드는 릴리스 빌드를 사용할 수 있습니다 :

 

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

또한 minifyEnabled 속성뿐만 아니라 ProGuard에서 proguardFiles 속성을 정의하기위한 규칙 :

getDefaultProguardFile ( '난독-android.txt') 방법은 ProGuard에서 안드로이드 SDK 도구 / 난독 화 / 폴더를 기본 설정에서 얻을 수 있습니다.

提示:要想做进一步的代码压缩,请尝试使用位于同一位置的 proguard-android-optimize.txt 文件。它包括相同的 ProGuard 规则,但还包括其他在字节码一级(方法内和方法间)执行分析的优化,以进一步减小 APK 大小和帮助提高其运行速度。

proguard-rules.pro 文件用于添加自定义 ProGuard 规则。默认情况下,该文件位于模块根目录(build.gradle 文件旁)。

3.优化assets和res中的资源文件

题外话

res/raw和assets的相同点:

两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。

res/raw和assets的不同点:

  1. res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
  2. res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹。
  3. 针对不同的情况,对于资源文件有不同的优化策略。一般来讲,对于res/drawable-**ddpi中的png资源可以进行压缩。

3.1 图片资源优化策略

格式压缩

使用TinyPng或者Guetzli进行压缩。

使用WebP文件格式

定位Android 3.2(API级别13)或更高级别时 ,您也可以使用WebP文件格式来制作图像,而不是使用PNG或JPEG文件。WebP格式提供有损压缩(如JPEG)以及透明度(如PNG),但可以提供比JPEG或PNG更好的压缩。

Android 4.0 (API level 14) 支持有损压缩的WebP格式,Android 4.3 (API level 18) 开始支持无损透明WebP图像。

看下图:

 

压缩效率极高,仅为PNG格式的12%。惊喜不惊喜。。。

使用矢量图形

您可以使用矢量图形来创建与分辨率无关的图标和其他可伸缩媒体。使用这些图形可以大大减少您的APK足迹。矢量图像在Android中表示为VectorDrawable对象。通过一个VectorDrawable对象,一个100字节的文件可以生成一个与屏幕尺寸一致的清晰图像。

但是,系统渲染每个 VectorDrawable对象需要很长时间,而较大的图像需要更长的时间才能显示在屏幕上。因此,只有在显示小图像时才考虑使用这些矢量图形。

其它策略

有时候我们可能对一张图片进行重复利用,比如一张图片仅仅是整体颜色的变换可以使用setColorFilter或者tint。尽量减少使用帧动画,那可是一堆图片呀。

3.2 压缩资源

要启用资源压缩,请在 build.gradle 文件中将 shrinkResources 属性设置为 true。

 

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

资源压缩器目前不会移除 values/ 文件夹中定义的资源(例如字符串、尺寸、样式和颜色)。这是因为 Android 资源打包工具 (AAPT) 不允许 Gradle 插件为资源指定预定义版本。

同时,我们也可以指定哪些资源可以保留下来。

例如,将下边的代码保存在 res/raw/keep.xml。构建不会将该文件打包到 APK 之中。

 

<?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" />

resources有以下属性:

  • tools:keep 指出哪些资源会保留
  • tools:discard 指定哪些资源需要剔除
  • tools:shrinkMode 资源压缩模式,有两种取值strict和safe,默认为safe

safe和strict的优化策略:

safe可以简单理解为安全模式,它会尽最大努力检查代码中可能会使用到的资源进行保留,避免运行时错误。

如果你的代码调用 Resources.getIdentifier(),这就表示你的代码将根据动态生成的字符串查询资源名称。当你执行这一调用时,默认情况下资源压缩器会采取防御性行为,将所有具有匹配名称格式的资源标记为可能已使用,无法移除。

 

String name = String.format("img_%1d", angle + 1);
res = getResources().getIdentifier(name, "drawable", getPackageName());

img_ 前缀的资源标记为已使用。

在strict模式下,img_前缀的资源会做未使用的处理,因此你需要使用tools:keep手动进行已使用标识。

移除未使用的备用资源

我们知道google给我们的apk提供了国际化支持,如适应不同的屏幕分辨率的drawable资源,还有适应不同语言的字符串资源等等,但是在很多情况下我们只需要一些指定分辨率和语言的资源就可以了,这个时候我们可以使用resConfigs方法来配置。

 

defaultConfig {
 // 对于国际化支持只打包中文资源,
 resConfigs "zh-rCN"
}

4.lib中资源优化

这里我们主要讲一下lib中动态链接库的优化策略,也就是SO文件。如果你有NDK的开发经验可能会更容易理解一些。

为了支持不同指令集的情况,应用可能会包含armeabi、armeabi-v7a、x86的SO文件等。

目前主流的机型都是支持armeabi-v7a的,并且armeabi-v7a兼容armeabi。所以在一般的开发中我们只需要使用armeabi-v7a 进行ABI支持。

有些SO库可以采用网络下载,把负担放到用户安装完应用之后。对于哪些SO文件可以放到网络中加载,还需要看具体业务情况。

题外话,如果运行时找不到SO的话,会导致应用崩溃。

 

java.lang.UnsatisfiedLinkError: Couldn't load stlport_shared
 from loader dalvik.system.PathClassLoader: findLibrary returned null
at java.lang.Runtime.loadLibrary(Runtime.java:365)
at java.lang.System.loadLibrary(System.java:535)
at com.your.app.NativeClass.<clinit>(Native.java:16)
... 63 more
Caused by: java.lang.UnsatisfiedLinkError: Library stlport_shared not found
at java.lang.Runtime.loadLibrary(Runtime.java:461)
at java.lang.System.loadLibrary(System.java:557)
at com.your.app.NativeClass.<clinit>(Native.java:16)
... 5 more

我们也是有办法应对的,可以参见这个开源项目ReLinker

本文的Android安装包大小优化知识到此结束

 

写在最后;

作者目前在深圳,13年java转Android开发,在小厂待过,也去过华为,OPPO等,去年四月份进了阿里一直到现在。后面转管理后也面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效,原理源码确实容易头疼,造成很多开发者工作几年后就陷入瓶颈难以往上突破。

 

我去年开始,整理了一份阿里P7级别的Android架构师全套学习资料,特别适合有3-5年以上经验的小伙伴深入学习提升。

主要包括腾讯,以及字节跳动,华为,小米,等一线互联网公司主流架构技术。

【阿里P7级】Android高级进阶技术脑图

(大家如果有想往上提升技术,建议先搭建一个全面的技术框架,然后再深挖)

 

 

 

也可以关注我的;Android高级进阶专栏。里面有很多在BAT等一线大厂待过,或者在职的技术大佬。哪怕只关注看看不学,也能一定程度上提升思维和格局。

欢迎关注和学习交流~

发布了17 篇原创文章 · 获赞 0 · 访问量 177

추천

출처blog.csdn.net/chuhe1989/article/details/104266708