-
Android 减包 - 减少APK大小
2017-05-04 10:58:46这篇文章描述了怎样减少你的APK大小,这会让更多的用户愿意下载你的应用。 理解APK的结构 在讨论怎样减少应用大小之前,先了解APK的结构是有用的。一个APK文件就是ZIP包,其中包含了组成你的应用的所有文件,...用户经常会避免下载看起来体积较大的应用,特别是在不稳定的2G、3G网络或者在以字节付费的网络。这篇文章描述了怎样减少你的APK大小,这会让更多的用户愿意下载你的应用。
理解APK的结构
在讨论怎样减少应用大小之前,先了解APK的结构是有用的。一个APK文件就是ZIP包,其中包含了组成你的应用的所有文件,比如Java类文件,资源文件,和一个包含被编译资源的文件。
一个APK包含了以下目录:
-
META-INF/
: 包含CERT.SF和CERT.RSA签名文件,也包含了MANIFEST.MF文件。(译注:校验这个APK是否被人改动过) -
assets/
: 包含了应用的资源,这些资源能够通过AssetManager对象获得。 -
res/
: 包含了没被被编译到resources.arsc的资源。 -
lib/
: 包含了针对处理器层面的被编译的代码。这个目录针对每个平台类型都有一个子目录,比如armeabi, armeabi-v7a, arm64-v8a, x86, x86_64和mips。
一个APK也包含了以下文件,其中只有AndroidManifest.xml是强制的:
-
resources.arsc
: 包含了被编译的资源。该文件包含了res/values
目录的所有配置的XML内容。打包工具将XML内容编译成二进制形式并压缩。这些内容包含了语言字符串和styles,还包含了那些内容虽然不直接存储在resources.arsc文件中,但是给定了该内容的路径,比如布局文件和图片。 -
classes.dex
: 包含了能被Dalvik/Art虚拟机理解的DEX文件格式的类。 -
AndroidManifest.xml
: 包含了主要的Android配置文件。这个文件列出了应用名称、版本、访问权限、引用的库文件。该文件使用二进制XML格式存储。(译注:该文件还能看到应用的minSdkVersion, targetSdkVersion等信息)
译注:使用APK Analyzer能够清晰地看出以上文件的内容,具体请看:使用APK Analyzer分析你的APK。
减少资源个数和尺寸
APK的大小会影响应用加载的速度,使用的内存大小,消耗的电量大小。一个最简单的缩小APK大小的方式是减少资源的个数和大小。特别地,你能移除应用中不再使用的资源,你也能使用可缩放的Drawable对象代替图片文件。这节讨论一些通过减少资源从而减少APK大小的方法。
译注:减少资源个数和缩小资源大小的效果是很显著的,比如有一天发现我组里的项目中还包含了旧版本的引导页视频(1.5M),一下就就减少了1.5M,想想为了减少1.5M你得删多少代码才能办到。
移除不使用的资源
lint是Android Studio中的一个静态代码分析工具,检测在“res/”目录中你的代码没有引用的资源。当lint工具发现了项目中潜在的未使用的资源,它会打印以下类似信息:
res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources]
注意:lint工具不会扫描“asset/”目录,这个目录是通过反射引用的资源,或者链接到应用中的库文件。还有,lint不会移除资源,只会发出警告。
被引用的库中可能会包含没使用的资源。如果你在build.gradle文件中启用shrinkResources,则Gradle能自动移除这些资源。
为了使用shrinkResources,你必须要启用代码混淆。在构建过程中,首先proguard移除了未使用的代码,然后gradle移除未使用的资源。
译注:lint工具还能够检查出未使用的类、类中未使用的方法或变量。
更多关于通过代码混淆和其他方式减包,请看Shrink Your Code and Resources。
在Gradle插件0.7或更高版本,你能申明应用支持的配置。Gradle通过传递resConfigs和defaultConfig给构建系统,构建系统会防止不支持的配置出现在APK中,从而减少APK大小。更多信息请看Remove unused alternative resources。
译注:在hello world工程里,resConfigs配置为“zh”和不配置resConfigs,resources.arsc文件相差了80K。
最小化第三方库中资源的使用
当开发Android应用时,你经常使用第三方库提升应用的可用性和灵活性。比如,你引用Android Support Library提升旧设备的用户体验,或者使用Google Play服务实现文字自动翻译。
如果一个第三方库原本是为服务器或普通电脑设计,会引入许多不需要的对象和方法。为了只引入应用需要的库中的那部分,你可以编辑库文件(如果库的license允许你这么做)。你也能使用另外的针对手机的实现同样功能的库。
注意:代码混淆能清除库中不被使用的代码,但是他不能移除库的大量内部依赖。
只支持部分屏幕密度
Android支持很多设备集,其中包含了各种不同的屏幕密度。在Android 4.4及更高版本,框架支持不同的密度:ldpi, mdpi, tvdpi, hdpi, xhdpi, xxhdpi和xxxhdpi。尽管Android支持所有这些屏幕密度,但你不需要为每个密度都配置相应的资源。
如果你知道某种特定屏幕密度已经很少有用户使用了,那么你可以考虑是否需要为这个屏幕密度配置资源。如果你不包含针对特定屏幕密度的资源,那么Android会自动缩放原本针对其他密度的已有资源。
如果你的应用只需要缩放的图片,你甚至可以把图片存放在drawable-nodpi目录,从而节省更多空间。我们推荐每个应用都应该至少包含xxhdpi的图片。
更多关于屏幕密度的信息,请看Screen Sizes and Densities。
减少动画帧数
使用帧动画会大大增加APK的大小。图1显示了目录中构成帧动画的多个PNG文件。每个图片都是动画的一帧。
对于加入动画的每帧,你都增加了APK中图片的个数。图1中,帧动画的帧率是30 FPS。如果帧率降到15 FPS,图片数量将减少一半。
图1:帧动画的每一帧图片。
译注:还有一个常见的减包方案是删除帧动画中重复的图片资源,比如第1帧和第3帧的图片一样,那么只保留一个。
使用Drawable对象
一些图片不需要静态的图片资源,框架能在运行时动态地绘制图像。Drawable对象(XML的)只需要占用APK中的一点空间。另外,XML形式的Drawable对象能够产生遵循Material Design设计规范的图像。
重用资源
你能包含一张图片的很多变种,比如染色、阴影、旋转的版本。但是,我们推荐在运行时复用一张图片来定制化他们。
Android提供了很多方式改变资源的颜色。对于Android 5.0及以上,使用android:tint和tintMode属性。对于更低版本,使用ColorFilter类。
你也能够删除那些只是对另一个资源做旋转的资源。下面的代码片段提供了对一个箭头旋转180度。
<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_arrow_expand" android:fromDegrees="180" android:pivotX="50%" android:pivotY="50%" android:toDegrees="180" />
通过代码绘制
你也能通过代码绘制图像,从而减少APK大小。代码方式绘制图像不需要任何空间因为你不再需要在APK中存储图像文件。
压缩PNG文件
AAPT工具能够在构建过程中通过无损压缩优化res/drawable/中的图片资源。比如aapt工具能将需要颜色少于256色的PNG变为8位PNG图,这样能够在保证图片质量的同时减少内存使用。
需要注意aapt有以下局限性:
-
aapt工具不会压缩asset目录的PNG文件。
-
通过aapt的优化,图片文件会使用少于256色。
-
aapt工具可能会影响已经被压缩过的PNG文件。为了防止这种情况,你可以在gradle文件中设置cruncherEnabled为false禁用aapt对PNG的压缩。
aaptOptions { cruncherEnabled = false}
译注:建议把cruncherEnabled设为false,然后通过tinypng手工压缩PNG图片。
压缩PNG和JPEG文件
你能使用一些工具(比如pngcrush, pngquant, zopflipng)在不降低图像质量的前提下减少PNG文件大小。所有这些工具都能保留图像质量的情况下减少PNG文件大小。
pngcrush工具特别有效:这个工具通过迭代png过滤器和zlib参数,使用每种过滤器和参数的组合压缩图像,并选择最小的那个作为最后的输出。
对于JPEG文件,能使用packJPG压缩JPEG文件。
译注:guetzli是Google最近推出的JPEG编码器,官方宣称相同图片质量时,比libjpeg生成的图片小20–30%。
使用WebP文件格式
你也能使用WebP文件格式存储图片而不是PNG或者JPEG。WebP格式是有损压缩(像JPEG)且有透明通道(像PNG),且压缩率高于JPEG或PNG。
使用WebP文件格式也有一些缺点。第一,低于Android 3.2的版本不支持WebP,第二,WebP的解码时间比PNG长。
注意:Google Play的APK的应用启动图标只能使用PNG格式,而不支持其他格式。
在Android Studio中,能将BMP,JPG,PNG或者静态GIF图片转换成WebP格式。更多信息,请看Create WebP Images Using Android Studio。
使用向量图
你能使用向量图去创建一个分辨率无关的图标。使用向量图能够显著减少APK大小。在Android中向量图是以VectorDrawable对象形式存在的。使用VectorDrawable对象,一个100B的文件能生成一个屏幕大小的清晰图片。
但是,系统需要很长时间渲染VectorDrawable对象,更大的图片需要更长的时间显示在屏幕上。因此只有小图片才考虑使用向量图。
更多关于VectorDrawable对象的信息,请看Working with Drawables。
减少Native和Java代码
有许多方法能够减少Java和Native的代码量。
减少不必要的生成代码
确保理解任何自动生成的代码。比如,许多protocol buffer工具生成了过多的方法和类,这会让你的应用大小翻倍。
移除枚举
一个枚举能让classes.dex文件增加1–1.4K。枚举的加入会快速增加应用体积。我们可以使用@IntDef注解和Proguard代替枚举,它能提供和枚举一样的类型安全转换。
减少Native库的大小
如果你的应用使用了Native代码和Android NDK,你也能通过优化代码减少应用体积,这里介绍的两个技巧是删除调试符号和避免抽取Native库。
移除调试符号
如果应用在开发中并且仍需要调试,那么我们能理解使用调试符号。使用Android NDK提供的arm-eabi-strip工具,能从Native库中删除不必要的调试符号,之后你再编译release包。
避免抽取Native库
在APK中存储未压缩的so文件,并且在Manifest文件的中设置android:extractNativeLibs为false,这会防止在安装时PackageManager将APK中的so文件拷贝到文件系统,避免这种拷贝会让应用在做增量更新时的更新包更小。
维持多个小的APK包
你的APK会包含用户下载了但从未使用的内容,比如地区或语言信息(译注:比如我是中国人,我就不会用到其他语种的资源)。为了给用户创建小的下载包,你能把你的应用拆分成多个APK,这些APK的差别在于一些因素(比如屏幕大小或者GPU纹理支持)。
当一个用户下载了应用,设备根据自身的特性和设置获取正确的APK。这种方式能够让设备不获取设备不需要的资源。比如,如果设备是hdpi的,那么他就不需要xxxhdpi的资源。
更多信息请看Configure APK Splits和Maintaining Multiple APKs。
-
-
怎么减少iOS应用程序安装包大小技巧?
2015-02-06 17:28:49如果你存在着这样的苦恼,那么本文所收集的一些减小程序安装包大小的相关技巧以及减小iOS应用程序升级时所需下载的大小(这与第一次安装使用的工作原理有所不同)应该能帮助到你的。 检查应用...怎样才能让iPone设备程序安装包小一点,让程序的下载和安装更快速?升级程序时候,安装包所占用空间过大怎么办?如果你存在着这样的苦恼,那么本文所收集的一些减小程序安装包大小的相关技巧以及减小iOS应用程序升级时所需下载的大小(这与第一次安装使用的工作原理有所不同)应该能帮助到你的。
检查应用程序
首先是检查.app bundle,看一下程序包里面哪些文件占的空间最大。
在做任何相关优化之前,我们需要做一些权衡。通过权衡,可以知道把优化的重点集中在什么地方。本文提到的一些技术缺点我们也需要做出考虑,我们必须考虑相关影响,以确保做出正确的决定。如果不做权衡的话,我们无法知道需要对程序做出什么样的改变。
当第一安装iOS程序时,需要下载完整的一个.ipa文件。(注意这不同于升级)。实际上.ipa文件就是一个.zip结构。
*找出程序的.ipa文件方法:
1、从App Store下载应用,然后利用iTunes对iOS设备做同步处理,接着查看目录:
~/Music/iTunes/iTunes Music/Mobile Applications,就能找到.ipa文件了。
2、当然我们也可以通过使用: Xcode的Archive命令来构造出.ipa文件——该文件与提交到App Store上的格式基本一致。
检查.ipa文件
简单的将后缀为.ipa文件修改为.zip,然后利用Finder将其解压出来。右键单击解压出来的.app bundle,选择显示包内容,以查看里面的资源文件。通过该方法我们可以看到哪些文件占的空间最大。
*注意:.app bundle是经过压缩的,并且有些文件的压缩效果要比别的文件好,所以压缩后的效果才是才是最重要的。不过一般情况下在压缩前最大的文件,在压缩后依旧是最大的文件。我们可以将某个文件删除,然后在Finder中右键单击,选择压缩,这样可以更加精确的测量文件压缩效果。
Build Settings
编译选项
将build setting中的Optimization Level设置为Fastest, Smallest [-Os]; 将build setting 中的Strip Debug Symbols During Copy设置为YES(COPY_PHASE_STRIP = YES),这样可以减小编译出二进制文件的尺寸。这里提到的这些设置在Xcode工程中对于Release的配置是默认的。
*警告:这些设置会让你的程序很难debug。在一般开发环境build中不建议这样设置
Target针对较少的CPUs
默认情况下,Xcode工程都配置为:对程序指定的特定CPU类型做优化处理,以生成相对于的可执行文件。不同的硬件,将运行不同的可执行代码。虽然这样优化后的程序,只能针对某些设备运行,但是这大大减小可执行程序的大小。
要想只设定特定类型的CPUs,可以修改build setting中的Architectures,将其从Standard $(ARCHS_STANDARD)修改为你希望支持的列表中对应的特定类型CPU。有效的CPU名称列在Valid Architectures (VALID_ARCHS) build setting中。请不要修改Valid Architectures设置项,最好由Xcode管理。
Assets
对应用程序做一个完整性检查
利用Inspecting Your App中介绍的流程,对.app bundle做一个全面的检查,以了解那些是真正需要用到的。在程序中,经常会包含一些额外的文件,例如readme之类的,这些从来都不会被用到。
将数据从代码中剥离出来
将所有的资源(例如很长的字符串)从代码中剥离出来,并存入外部文件,这样会减小最终文件下载的大小,因为这些文件的压缩效果更好。(参考iOS App Store Specific Considerations中的完整介绍。)
Image Assets
尽量使用8-bit图片
使用8-bit的PNG图片,比32-bit的图片能减少4倍的压缩率。由于8-bit的图片支持最多256种不同的颜色,所以8-bit的图片一般只应该用于一小部分的颜色图片。例如灰度图片最好使用8-bit。
针对32-bit的图片尽量使用高压缩的比率
利用Adobe Photoshop的Save For Web可以减小JPEG和PNG的图片大小。在Xcode中,默认情况下,会自动的使用pngcrush来压缩.png图片。
Audio Assets
音频的压缩
参考WWDC中的Audio Development for Games,里面介绍了如何有效的处理音频。常规来说,我们要使用AAC或MP3来压缩音频,并且可以尝试降低一下音频的比特率。有时候44.1khz的采样是没有必要的,稍微低一点的比特率也不会降低音频的质量。
*温馨提示:以上这些方法仅供参考,而且仅适用于对程序占用空间特别在意又对自己的耐心非常有信息的同学们,要不然,头疼呵呵了什么的,只好自己忍着啦~
iOS App Store相关因素
作为提交到App Store中app里的可执行文件是被加过密的。加密的副作用是可执行文件的压缩效果没有之前的好了,因为加密会隐藏一些细节问题。因此,从App Store下载下来的.ipa文件大小要比从本地build出来的.ipa文件大。
注意:将长文本内容和表数据等从代码中移除,并添加到外部文件中,这样可以减小最终安装包下载的大小——因为这些文件的压缩效果更好。
如果你选择Organizer window中的某个archived,然后点击Estimate Size,Xcode可以对最终分发的程序尺寸做出一个评估。这里并不考虑Mac App Store上面的和企业级部署的iOS程序。
-
【腾讯Bugly干货分享】Android减包 - 减少APK大小
2017-05-04 12:39:22译者简介:damonxia(夏正冬),天天P图Android工程师 用户经常会避免下载看起来体积较大的应用,特别是在不稳定的2G、3G网络或者在以字节付费的网络。...理解APK的结构在讨论怎样减少应用大小之前,先了解A本文是对Google官方文档 Reduce APK Size 的翻译,点击“阅读原文”可以查看英文原文。
译者简介:damonxia(夏正冬),天天P图Android工程师
用户经常会避免下载看起来体积较大的应用,特别是在不稳定的2G、3G网络或者在以字节付费的网络。这篇文章描述了怎样减少你的APK大小,这会让更多的用户愿意下载你的应用。
理解APK的结构
在讨论怎样减少应用大小之前,先了解APK的结构是有用的。一个APK文件就是ZIP包,其中包含了组成你的应用的所有文件,比如Java类文件,资源文件,和一个包含被编译资源的文件。
一个APK包含了以下目录:
META-INF/
: 包含CERT.SF和CERT.RSA签名文件,也包含了MANIFEST.MF文件。(译注:校验这个APK是否被人改动过)assets/
: 包含了应用的资源,这些资源能够通过AssetManager对象获得。res/
: 包含了没被被编译到resources.arsc的资源。lib/
: 包含了针对处理器层面的被编译的代码。这个目录针对每个平台类型都有一个子目录,比如armeabi, armeabi-v7a, arm64-v8a, x86, x86_64和mips。
一个APK也包含了以下文件,其中只有AndroidManifest.xml是强制的:
resources.arsc
: 包含了被编译的资源。该文件包含了res/values
目录的所有配置的XML内容。打包工具将XML内容编译成二进制形式并压缩。这些内容包含了语言字符串和styles,还包含了那些内容虽然不直接存储在resources.arsc文件中,但是给定了该内容的路径,比如布局文件和图片。classes.dex
: 包含了能被Dalvik/Art虚拟机理解的DEX文件格式的类。AndroidManifest.xml
: 包含了主要的Android配置文件。这个文件列出了应用名称、版本、访问权限、引用的库文件。该文件使用二进制XML格式存储。(译注:该文件还能看到应用的minSdkVersion, targetSdkVersion等信息)
译注:使用APK Analyzer能够清晰地看出以上文件的内容,具体请看:使用APK Analyzer分析你的APK。
减少资源个数和尺寸
APK的大小会影响应用加载的速度,使用的内存大小,消耗的电量大小。一个最简单的缩小APK大小的方式是减少资源的个数和大小。特别地,你能移除应用中不再使用的资源,你也能使用可缩放的Drawable对象代替图片文件。这节讨论一些通过减少资源从而减少APK大小的方法。
译注:减少资源个数和缩小资源大小的效果是很显著的,比如有一天发现我组里的项目中还包含了旧版本的引导页视频(1.5M),一下就就减少了1.5M,想想为了减少1.5M你得删多少代码才能办到。
移除不使用的资源
lint是Android Studio中的一个静态代码分析工具,检测在“res/”目录中你的代码没有引用的资源。当lint工具发现了项目中潜在的未使用的资源,它会打印以下类似信息:
res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources]
注意:lint工具不会扫描“asset/”目录,这个目录是通过反射引用的资源,或者链接到应用中的库文件。还有,lint不会移除资源,只会发出警告。
被引用的库中可能会包含没使用的资源。如果你在build.gradle文件中启用shrinkResources,则Gradle能自动移除这些资源。
为了使用shrinkResources,你必须要启用代码混淆。在构建过程中,首先proguard移除了未使用的代码,然后gradle移除未使用的资源。
译注:lint工具还能够检查出未使用的类、类中未使用的方法或变量。
更多关于通过代码混淆和其他方式减包,请看Shrink Your Code and Resources。
在Gradle插件0.7或更高版本,你能申明应用支持的配置。Gradle通过传递resConfigs和defaultConfig给构建系统,构建系统会防止不支持的配置出现在APK中,从而减少APK大小。更多信息请看Remove unused alternative resources。
译注:在hello world工程里,resConfigs配置为“zh”和不配置resConfigs,resources.arsc文件相差了80K。
最小化第三方库中资源的使用
当开发Android应用时,你经常使用第三方库提升应用的可用性和灵活性。比如,你引用Android Support Library提升旧设备的用户体验,或者使用Google Play服务实现文字自动翻译。
如果一个第三方库原本是为服务器或普通电脑设计,会引入许多不需要的对象和方法。为了只引入应用需要的库中的那部分,你可以编辑库文件(如果库的license允许你这么做)。你也能使用另外的针对手机的实现同样功能的库。
注意:代码混淆能清除库中不被使用的代码,但是他不能移除库的大量内部依赖。
只支持部分屏幕密度
Android支持很多设备集,其中包含了各种不同的屏幕密度。在Android 4.4及更高版本,框架支持不同的密度:ldpi, mdpi, tvdpi, hdpi, xhdpi, xxhdpi和xxxhdpi。尽管Android支持所有这些屏幕密度,但你不需要为每个密度都配置相应的资源。
如果你知道某种特定屏幕密度已经很少有用户使用了,那么你可以考虑是否需要为这个屏幕密度配置资源。如果你不包含针对特定屏幕密度的资源,那么Android会自动缩放原本针对其他密度的已有资源。
如果你的应用只需要缩放的图片,你甚至可以把图片存放在drawable-nodpi目录,从而节省更多空间。我们推荐每个应用都应该至少包含xxhdpi的图片。
更多关于屏幕密度的信息,请看Screen Sizes and Densities。
减少动画帧数
使用帧动画会大大增加APK的大小。图1显示了目录中构成帧动画的多个PNG文件。每个图片都是动画的一帧。
对于加入动画的每帧,你都增加了APK中图片的个数。图1中,帧动画的帧率是30 FPS。如果帧率降到15 FPS,图片数量将减少一半。
图1:帧动画的每一帧图片。
译注:还有一个常见的减包方案是删除帧动画中重复的图片资源,比如第1帧和第3帧的图片一样,那么只保留一个。
使用Drawable对象
一些图片不需要静态的图片资源,框架能在运行时动态地绘制图像。Drawable对象(XML的)只需要占用APK中的一点空间。另外,XML形式的Drawable对象能够产生遵循Material Design设计规范的图像。
重用资源
你能包含一张图片的很多变种,比如染色、阴影、旋转的版本。但是,我们推荐在运行时复用一张图片来定制化他们。
Android提供了很多方式改变资源的颜色。对于Android 5.0及以上,使用android:tint和tintMode属性。对于更低版本,使用ColorFilter类。
你也能够删除那些只是对另一个资源做旋转的资源。下面的代码片段提供了对一个箭头旋转180度。
<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_arrow_expand" android:fromDegrees="180" android:pivotX="50%" android:pivotY="50%" android:toDegrees="180" />
通过代码绘制
你也能通过代码绘制图像,从而减少APK大小。代码方式绘制图像不需要任何空间因为你不再需要在APK中存储图像文件。
压缩PNG文件
AAPT工具能够在构建过程中通过无损压缩优化res/drawable/中的图片资源。比如aapt工具能将需要颜色少于256色的PNG变为8位PNG图,这样能够在保证图片质量的同时减少内存使用。
需要注意aapt有以下局限性:
- aapt工具不会压缩asset目录的PNG文件。
- 通过aapt的优化,图片文件会使用少于256色。
- aapt工具可能会影响已经被压缩过的PNG文件。为了防止这种情况,你可以在gradle文件中设置cruncherEnabled为false禁用aapt对PNG的压缩。
aaptOptions { cruncherEnabled = false }
译注:建议把cruncherEnabled设为false,然后通过tinypng手工压缩PNG图片。
压缩PNG和JPEG文件
你能使用一些工具(比如pngcrush, pngquant, zopflipng)在不降低图像质量的前提下减少PNG文件大小。所有这些工具都能保留图像质量的情况下减少PNG文件大小。
pngcrush工具特别有效:这个工具通过迭代png过滤器和zlib参数,使用每种过滤器和参数的组合压缩图像,并选择最小的那个作为最后的输出。
对于JPEG文件,能使用packJPG压缩JPEG文件。
译注:guetzli是Google最近推出的JPEG编码器,官方宣称相同图片质量时,比libjpeg生成的图片小20–30%。
使用WebP文件格式
你也能使用WebP文件格式存储图片而不是PNG或者JPEG。WebP格式是有损压缩(像JPEG)且有透明通道(像PNG),且压缩率高于JPEG或PNG。
使用WebP文件格式也有一些缺点。第一,低于Android 3.2的版本不支持WebP,第二,WebP的解码时间比PNG长。
注意:Google Play的APK的应用启动图标只能使用PNG格式,而不支持其他格式。
在Android Studio中,能将BMP,JPG,PNG或者静态GIF图片转换成WebP格式。更多信息,请看Create WebP Images Using Android Studio。
使用向量图
你能使用向量图去创建一个分辨率无关的图标。使用向量图能够显著减少APK大小。在Android中向量图是以VectorDrawable对象形式存在的。使用VectorDrawable对象,一个100B的文件能生成一个屏幕大小的清晰图片。
但是,系统需要很长时间渲染VectorDrawable对象,更大的图片需要更长的时间显示在屏幕上。因此只有小图片才考虑使用向量图。
更多关于VectorDrawable对象的信息,请看Working with Drawables。
减少Native和Java代码
有许多方法能够减少Java和Native的代码量。
减少不必要的生成代码
确保理解任何自动生成的代码。比如,许多protocol buffer工具生成了过多的方法和类,这会让你的应用大小翻倍。
移除枚举
一个枚举能让classes.dex文件增加1–1.4K。枚举的加入会快速增加应用体积。我们可以使用@IntDef注解和Proguard代替枚举,它能提供和枚举一样的类型安全转换。
减少Native库的大小
如果你的应用使用了Native代码和Android NDK,你也能通过优化代码减少应用体积,这里介绍的两个技巧是删除调试符号和避免抽取Native库。
移除调试符号
如果应用在开发中并且仍需要调试,那么我们能理解使用调试符号。使用Android NDK提供的arm-eabi-strip工具,能从Native库中删除不必要的调试符号,之后你再编译release包。
避免抽取Native库
在APK中存储未压缩的so文件,并且在Manifest文件的中设置android:extractNativeLibs为false,这会防止在安装时PackageManager将APK中的so文件拷贝到文件系统,避免这种拷贝会让应用在做增量更新时的更新包更小。
维持多个小的APK包
你的APK会包含用户下载了但从未使用的内容,比如地区或语言信息(译注:比如我是中国人,我就不会用到其他语种的资源)。为了给用户创建小的下载包,你能把你的应用拆分成多个APK,这些APK的差别在于一些因素(比如屏幕大小或者GPU纹理支持)。
当一个用户下载了应用,设备根据自身的特性和设置获取正确的APK。这种方式能够让设备不获取设备不需要的资源。比如,如果设备是hdpi的,那么他就不需要xxxhdpi的资源。
更多信息请看Configure APK Splits和Maintaining Multiple APKs。
更多精彩内容欢迎关注腾讯 Bugly的微信公众账号:
腾讯 Bugly是一款专为移动开发者打造的质量监控工具,帮助开发者快速,便捷的定位线上应用崩溃的情况以及解决方案。智能合并功能帮助开发同学把每天上报的数千条 Crash 根据根因合并分类,每日日报会列出影响用户数最多的崩溃,精准定位功能帮助开发同学定位到出问题的代码行,实时上报可以在发布后快速的了解应用的质量情况,适配最新的 iOS, Android 官方操作系统,鹅厂的工程师都在使用,快来加入我们吧!
-
bartender外部表不是预期格式_怎样在磁盘上查找MySQL表的大小?这里有答案
2020-12-24 00:02:20我想知道 MySQL 表在磁盘上占用多少空间,但看起来很琐碎。不应该在 INFORMATION_SCHEMA.TABLES 中提供这些信息吗?没那么简单!这个看似简单的问题实际上在 MySQL 中非常复杂。MySQL 支持许多存储引擎(其中一些根本不...我想知道 MySQL 表在磁盘上占用多少空间,但看起来很琐碎。不应该在 INFORMATION_SCHEMA.TABLES 中提供这些信息吗?没那么简单!
这个看似简单的问题实际上在 MySQL 中非常复杂。MySQL 支持许多存储引擎(其中一些根本不在磁盘上存储数据), 不同的存储数据格式。例如,InnoDB 存储引擎为 MySQL 5.7 提供了三种“基本”格式,其中包含 row_formats 和两种可压缩的种类。
简化一下:我们如何在磁盘上查找存储在其自己的表空间中的 InnoDB 表的表大小(前提是 innodb_file_per_table=1 )。
在我们得到答案之前,先展示通过 sysbench 运行预先获得的图表(批量数据插入表):
在磁盘上查找 MySQL 表的大小
此图显示了从 INFORMATION_SCHEMA.TABLES 获取的 data_length 和 index_length 所定义的表大小。可以预期,随着数据的增多,表格会跳跃增长(有时会增加 10GB 或更多)。
该图表与磁盘上数据的变化方式不匹配,它逐渐增长(如预期):
-rw-r----- 1 mysql mysql 220293234688 Jan 25 17:03 sbtest1.ibd-rw-r----- 1 mysql mysql 220310011904 Jan 25 17:03 sbtest1.ibd-rw-r----- 1 mysql mysql 222499438592 Jan 25 17:07 sbtest1.ibd
正如我们从这个实验中看到的那样,MySQL 并没有真正的实时维护 data_length 和 index_length 的值,而是定期刷新它们 - 而且不规则地刷新它们。图表的后半部分一些数据刷新变得更加规律。这与图表的第一部分不同,后者似乎每次有 10% 的行更改时,就更新一次统计信息。table_rows, data_free 或 update_time ,它们也是实时更新的。
要在 MySQL 5.7获取 information_schema 获取到更准确的实时信息,需要做两件事:
禁用 innodb_stats_persistent
启用 innodb_stats_on_metadata
这两者都会带来严重的代价。
禁用持久性统计信息意味着每次服务器启动时 InnoDB 都必须刷新统计信息,这代价很大,并且可能会在重新启动之间产生不稳定的查询计划。那有没有更好的办法呢?事实证明有。
可以通过 INNODB_SYS_TABLESPACES 查看表空间信息表以查看实际文件大小。与 index_length 和 data_length 不同, INNODB_SYS_TABLESPACES 实时更新,无需特殊配置:
mysql> select * from INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES where name='sbinnodb/sbtest1' G*************************** 1. row ***************************SPACE: 42NAME: sbinnodb/sbtest1FLAG: 33FILE_FORMAT: BarracudaROW_FORMAT: DynamicPAGE_SIZE: 16384ZIP_PAGE_SIZE: 0SPACE_TYPE: SingleFS_BLOCK_SIZE: 4096FILE_SIZE: 245937209344ALLOCATED_SIZE: 2459372666881 row in set (0.00 sec)
使用这个表的好处是,它还处理新功能 “InnoDB 页压缩”,正确显示了 file_size (磁盘上的逻辑文件大小)和 allocated_size(为此文件分配的空间,并且可以显着缩小)之间的区别。
最后,让我们看一下不同的 InnoDB 压缩方式如何影响 information_schema 中提供的信息。
mysql> select * from INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES where name='sbinnodb/testcomp' G*************************** 1. row ***************************SPACE: 48NAME: sbinnodb/testcompFLAG: 33FILE_FORMAT: BarracudaROW_FORMAT: DynamicPAGE_SIZE: 16384ZIP_PAGE_SIZE: 0SPACE_TYPE: SingleFS_BLOCK_SIZE: 4096FILE_SIZE: 285212672ALLOCATED_SIZE: 1130045441 row in set (0.00 sec)
如果您使用旧的 InnoDB 压缩(InnoDB 表压缩),您将看到 data_length 和 index_length 中显示的压缩数据大小作为结果。例如, avg_row_length 将远低于您的预期。
如果在 MySQL 5.7 中使用新的 InnoDB 压缩(InnoDB 页压缩),您将看到与文件大小相对应的值,而不是如 information_schema 中所示的分配大小。
结论
回答一个微不足道的问题“这个表在磁盘上占用了多少空间?” 在 MySQL 中真的不是一个简单的问题 - 显而易见的数据,可能会得到错误的答案。
查看 INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES 以获取 InnoDB 表的实际文件大小值。
原文来自:https://www.linuxprobe.com/?p=157858
-
安卓里面怎样实现可缩放标度的ScrollBar,具体描述请看下面
2014-10-16 00:43:43主要是我不知道怎样实现以下效果:这个东西叫时间轴,是用在一个叫“历史地图”的安卓App 上,实现的功能有 1,可拖动 2,这个轴可以通过手势操作进行标度改变,比如两点触控可导致这个时间轴上时间跨度放大和... -
减小iOS应用程序的大小
2019-09-30 11:10:24A: 本文收集了一些减小程序安装包大小的相关技巧(当第一次下载和安装程序时)。如果是针对升级程序的话,可以看这篇文章(减小iOS应用程序升级时所需下载的大小)(这与第一次安装使用的工作原理有所不同)。... -
如何减小iOS应用程序的大小?
2015-10-15 14:17:51A: 本文收集了一些减小程序安装包大小的相关技巧(当第一次下载和安装程序时)。如果是针对升级程序的话,可以看这篇文章(减小iOS应用程序升级时所需下载的大小)(这与第一次安装使用的工作原理有所不同)。 ... -
教程:如何减小iOS应用程序的大小?
2014-10-22 15:53:00A: 本文收集了一些减小程序安装包大小的相关技巧(当第一次下载和安装程序时)。如果是针对升级程序的话,可以看这篇文章(减小iOS应用程序升级时所需下载的大小)(这与第一次安装使用的工作原理有所不同)。 检查... -
SYN包TCP选项的设置
2013-12-16 19:57:58一个SYN可能包括这些内容:初始系列号、初始窗口大小、MSS、窗口扩大因子、时间戳。 那么是怎么决定是否设置某个选项,怎样设置的呢?例如窗口扩大因子有关传输的性能,我可以怎么样改动这个值呢? 下面来看看内核是... -
怎样自动分割一张图中的所有画框
2020-09-06 22:26:36类似这种图片,包含位置不定、数量不定、大小不定的多个子图,不过形状固定都是矩形。 有什么工具或者API能自动切割出来呢? 看了些python实现的边缘检测,有点头大。 还找到了百度的图像分割模型... -
电子书包,究竟要怎样革命?
2009-08-03 22:52:00我们不曾忘记,背着10来公斤重的书包压的弯腰驼背,脊椎变形去上学的记忆,我们眼角泛酸...纵观科技的发展,我们从砖头似得磁带机,到CD,再到手心大小的MP3,从书店租书,到用手机,PSP,MP3看电子书,这样的便利是否 -
求大佬看看Proteus仿真单片机电路为啥对输入没反应
2021-01-23 20:17:36无论怎样调整加、减、模式切换三个按键单片机都无反应,因为Proteus模拟人体感应很麻烦所以我直接在P3.6接了一个开关控制高低电平,也就是模拟有人/无人状况,但无人时单片机也并不反应,... -
java对象在内存中的结构
2019-02-20 16:21:00要知道一个对象的大小,那么必须需要知道对象在虚拟机中的结构是怎样的,来看看Hotsopt中对象在内存中的结构: 在上面这张图里面可以看出,对象在内存中的机构主要包含以下几个部分: Mark Word:对象... -
【MySQL(十一)】Innodb 页结构
2020-06-25 19:03:36一页是16kb大小。有多种类型的页,这里看下存储数据和索引的页,叫做index page。一个index page主要包含以下7部分信息: (本篇图片全部来自掘金小册中《MySQL是怎样运行的》一书) 数据部分都存在user records... -
贪心算法(01/26)
2021-01-26 22:18:50在高中学的时候就差不多是一个盗贼去偷东西,每个东西都有固定的价值和大小,而盗贼只有一个已知大小的包,问怎样才能使偷走的价值最高。这类题很明显的就是对它所含有的价值,也就是对它们的平均价值进行排序,选取... -
详解Android代码混淆实战
2021-01-06 01:10:15减小apk文件的大小,在混淆过程中会删除未使用过的类和成员 代码安全,使类、函数、变量名随机变成无意义的代号形如:a,b,c…之类。防止app被反编译之后能够很容易的看懂代码 怎样使用混淆 在app下面的build.... -
决策树——连续值处理
2019-10-06 20:51:48来看看到底是怎样划分的。给定数据集如下(数据集来自周志华《机器学习》 对于数据集中的属性“密度”,决策树开始学习时,根节点包含的17个训练样本在该属性上取值均不同。我们先把“密度”这些值从小到大排序: ... -
文件传输0.4版
2014-02-21 17:23:53实现了多文件的传输和MD5校验,还显示了文件传输过程中的信息,在这一篇文章中, 将介绍怎样实现传输文件的进度显示和实现选择保存文件路径。 首先 , 来实现一个显示文件传输过程信息的控件,它需要显示文件的图标... -
浅谈MVC模式下--动态计算并设置view的frame
2016-03-01 14:46:56但是真正理解的并不是很多,也包括我,通俗地说model是数据模型,view是视图模型(一般包含model模型),而controller就是控制model和view的桥梁,有传递数据(传给model)功能,也能控制view(包括大小及位置,展示... -
苹果iOS 14正式版发布,带给用户不一样的体验
2020-09-21 17:16:08从 iOS 13.7 升至 iOS 14 需要下载 2.75GB 大小的文件包。 iOS 14 更新了 iPhone 的核心使用体验,其中包括 App 重大更新和其他全新功能。 全新小组件 重新设计的小组件可直接置于主屏幕上 小、中、大三种尺寸的... -
如何更改socket的发送缓冲去,以及更改socket的发送缓冲区出现的问题
2019-06-26 20:22:29本来是想看看当发送缓冲区快满的时候,继续发包的话,滑动窗口是怎样,就写了一个测试的demo,测试了很多次感觉设置的发送缓冲去大小不生效似的,最后发现不是真的不生效,而是这样的一个结论: 在Linux系统中,不管你... -
你必须知道的495个C语言问题
2015-10-16 14:14:28怎样才能避免固定大小的数组? 6.15 我如何声明大小和传入的数组一样的局部数组? 6.16 如何动态分配多维数组? 6.17 有个很好的窍门,如果我这样写:intrealarray[10];int*array=&realarray[-1];我就可以把... -
扫地机器人划伤地板_扫地机器人自动扫地的原理是什么?
2020-12-18 17:50:54智能自动扫地机器人在给人们带来方便舒适生活的同时,人们也会有很多疑问,科技感十足的智能扫地机器人的工作原理是怎样的?和普通的清扫方式又有什么区别呢?下面我们就来看看自动扫地机工作原理。自动扫地机工作... -
QC10字体问题
2011-07-24 11:02:50在QC10打上QC10_Patch15_Windows.zip后,在中文操作系统上字体会变得很小,看起来很不舒服,怎样恢复为之前的字段呢?把这两个目录下的QCClientUI.xco替换为未打补丁包前的版本,即有22M大小,打补丁后只有4M多。1、... -
Codeforces #39C: Moon Craters 题解
2017-07-20 20:23:29这道题一看就是dp,但感觉不知道怎样dp 刚开始想了一个dp[i]表示在前i个圆里面选互不重叠的最多能选几个,把圆先按右端点排序。但是圆的大小的任意性使得dp不正确 后来想了一个非常复杂的dp 先按圆的右端点从小到...
-
xenon-reader:适用于macOS的新型EPUB阅读器,采用最新技术构建-源码
-
psCtrlplLEDTest.rar
-
2021-02-26
-
华为存储资料及模拟器百度网盘.txt
-
高阶函数实现传统的策略模式
-
4.嵌入式开发网络连接问题
-
HWIDGen.zip
-
Shader Forge 1.3.8 最新版
-
python爬虫(requests+beautifulsoup模块实现古诗搜索并保存到本地,保存为txt格式文件)
-
STM32F030F4P6核心板pdf原理图+ ALTIUM pcb布局+器件封装库文件库.zip
-
pdf2word.exe
-
python分析之androidX包差异
-
Python网络爬虫:下载小说的正确姿势
-
eMule系统托盘图标
-
spark大数据分析与实战
-
报错 -> 问题 -> 解决 ->原因
-
opengl实现的太阳系
-
FileOutputStream的使用
-
Unity开发Hololens 2混合现实增强现实应用开发工具包 MRTK 2.5.4
-
音效整理该资源为各种音效的集合.rar