1.我怎么看这个?APK是Android系统安装包的文件格式。这个话题其实是一个常见的话题,不管是在公司内部,还是在外网,前辈们总结了很多方法和规律。但是,随着近两年移动技术的飞速发展,一些新的思路和优化方法也逐渐出现和成熟。笔者在实践过程中踩过一些坑,也获得了一些经验。在这里我会做一个反思和总结,所以我给大家写一篇作文。希望对您从事相关工作有所帮助和参考。这个开放的话题。至于为什么要把APK瘦身,我就不多说了。我就从三个方面来说吧。对于用户(或客户)来说,APK越大,在下载安装过程中消耗的流量就越多,安装等待时间也会越长;对于产品本身来说,意味着下载转化率会更低(因为在竞品中,用户有更多机会选择体验最好、功能最多、性能最好、封装最小的);对于研发来说,是一个优化和改进技术的机会。减肥,我们首先要寻找肥胖的原因和问题。按照目标-路径-资源的思维模式,查找原因和问题有几种路径。一种是拍脑袋,根据自己的经验判断,甚至是主观想象;另一种是去搜索引擎找关键词,浏览各种技术。论坛听技术大牛讲,看各种技术文章提炼提炼;三是使用可衡量的工具或方法来发现问题。前两种方法我就不细说了,这里只说第三种方法。用可衡量的工具或方法来分析,所谓工欲善其事必先利其器。这件器物可以自己锻造,也可以用现成的。这里推荐一款在线apk分析工具。因为它是一个外部工具,请不要在使用过程中上传未发布的产品。为了数据安全,笔者这里以github上的一个开源Android项目作为瘦身示例。2、发现问题NimbleDroid是一个博士开发的Androidapp性能指标分析系统,各种知名SDK的大小和占整体代码的比例,各类文件的大小和排名,方法的数量各种知名的SDK以及方法数量在所有dex中所占的比例,废话不多说,下面放一张高清无码大图看看颜值。如果您想使用分析功能分析自己的产品,请先登录并上传自己产品的apk包。所有功能目前都是免费提供的。如果要分析已在GooglePlay上架的产品,可以直接点击“PlayApps”查看。您还可以使用搜索功能根据应用名称和包名称查看结果。再次强调,请不要上传任何未发布的产品。登录上传apk文件分析结果汇总,可以看到一些概览信息,apk文件大小,方法总数,文件大小分析详情页,大文件列表,这里是apk文件中超过100k的文件排名,这里是文件size指的是apk文件的大小,各种知名SDK的大小以及占整体代码的比例。目前AndroidSupport,JacksonJSONparser,GooglePlayServices,Paypal,Glide,OkHttp,FacebookSDK,Fabric,Gson等,Application表示App编写的代码部分中各类文件的大小,以及排名各种知名的SDK。方法在所有dex中的占比各种知名SDK的方法数量。倒不是有种耳目一新的感觉!我把这个分析工具比作我们家里买的智能体重秤,可以测量体重、脂肪含量、骨重量、骨密度、肌肉含量等。以前的?基于经验的理由和拍脑袋可以逻辑地联系起来。然后,我们可以通过分析数据来梳理出我们的优化目标。在大文件列表中,超过100k的png文件有11个。请记住,这是压缩后的;在大文件、资源列表中。arsc的大小接近2M,也是一个优化点;在大文件排行榜中,classes.dex接近3M,classes.dex是代码的载体。这一块的优化需要细分,再看细分SDK的排行榜;在组件占比环状图中,AndroidSupport、JacksonJSONParser和GooglePlayServices是前三名的三方库;文件类型排行榜中,png、dex、arsc分列前三;3、梳理优化目标所以我们的目标是Notoothday,不,是以下几个目标:1.PNG图片优化;2、resources.arsc文件优化;3.代码优化3.1图片优化尝试首先是第一个目标,图片优化,慢着,我们来看看为什么这些图这么大。准确的说,为什么这些图片在apk(其实是zip文件)里这么大,好吧,还是上工具分析吧。这次用了一些简单的工具组合,系统自带的cmd就可以了。命令执行结果如下。那么,所有的png文件其实都是以STORE的形式存储在apk中的。zip中STORE和DEFLATE的详细信息见)一般来说,当文件以STORED的形式存储在zip中时,说明这个文件还没有被压缩。如果是Defl:N,说明是用DEFLATEDnormal压缩成zip存储的。这样好像有点不合理,png会原封不动的放到zip里面,当然***输出的apk会比较大。那么,如何解决呢?笔者首先尝试使用androidgradle插件,发现aaptOptions和packagingOptions都无法解决问题。在github上找到一个开源项目AndResGuard,尝试将其集成到项目中,结果如下:优化前:10536027字节优化后:正常zip压缩:8786265字节(压缩近17%)使用7zip压缩:8567150字节(压缩了将近19%)下面我们来看看这个工具做了什么,对比前后资源(png、xml、jpg等)名称混淆、资源路径名称混淆、名称长度启用资源混淆。压缩;以STORED形式存储在zip中的png文件已更改为DEFLATED(普通压缩存储);意外发现resources.arsc、META-INF/*.SF和META-INF/*.MF都变小了,而且解压后的文件大小也变小了。使用apk反编译神器jadx,深入apk内部寻找真相。原始apk中的资源(png、xml、properties文件)的相对路径会存储在META-INF/*.SF和META-INF/*.MF中,并为每个资源文件计算SHA1值和存放在这两个文件中。至于为什么要这样做,以及两种SHA1的区别和作用,可以参考网上关于这方面知识的文章,这超出了本文的主题,这里不再赘述。对于resources.arsc这个文件,很容易看出是一个资源文件索引表,所以大家看到这里应该明白为什么这三个文件变小了。3.2意外发现。往下看resources.arsc,发现一个有意思的东西,会成为一个优化点,去掉那些没用的翻译资源,引入一些第三方SDK。往往这些SDK都带有很多翻译资源在里面,比如android的supportlibrary。去掉之后,我们来看看效果。假设我们只保留英文,当然这只是一个实验。实际上,这取决于具体情况。使用7zip压缩:8220738字节(压缩近22%,加3分)。当然,这在实际项目中是不可能的,但蚊子的肉也是肉!其实我想说的是,这提供了一个优化思路,就是用gradleconfiguration来干掉无用的资源,同样可以用在so本地库和resolutions上(gradleconfiguration已经弃用)。gradle配置示例如下:记得把它包在android{}中间。那么,有人要问了,为什么abi中没有x86呢?据说Intel提供了一个解决方案,叫做Houdini,这是一个运行在x86设备上的中间件。可以将arm转成x86指令,但是效率很低。有些计算,比如计算MD5、SHA1,甚至还不如java,笔者做过测试对比,这是另外一个话题,这里不再赘述,有兴趣的读者可以往下看。至此,我们已经在朝着第一个目标迈进了,无意中发现了第一个目标和第二个目标之间的关系,所以我们使用资源混淆工具来实现第二个目标。使用7zip压缩,我们将整个包压缩了2个点,这是一个超出预期的结果。3.3图像优化方法关于第一个目标,我们的路径还没有结束。我们想到的路径是压缩png,将非alpha图像转换为jpg,还有什么?于是就去各种技术论坛,请教各种技术高手。整理路径如下:1.手动lint检查,手动删除代码中没有引用的资源,实际效果不同。在AndroidStudio中打开“Analyze”,选择“InspectCode...”,选择整个项目,然后点击“OK”进行配置,如图2所示。在gradle脚本中打开shrinkResources脚本。请参阅以下shrinkResources以更好地使用minifyEnabled。详细看shrinkResources的用法,注意7zip压缩的使用:8115283字节(压缩了近23%,加1分)3.使用图片压缩工具压缩png图片的大小,将non-alpha图片转换为格式.jpg关于这个,网上的同事和专家都已经详细整理过了。我在这里做一个简单的总结。更多详细信息,请参阅附录中的参考资料。使用tinypng,我只想说我们是在公司做产品。请谨慎使用此解决方案。将任何未发布的产品内容上传到外网可能会导致数据泄露,请谨慎使用该方案。这是替代方案。WASTEDpngquantImageAlphaImageOptim上面的工具太散了。有集成工具吗?答案是“是”。4.***大杀器,将png转webp。关于webp的更多细节,请参考谷歌官方文档和Android开发者在线参考。再加30分)你没看错,是30分,现在的apk大小还不到原来apk大小的一半,而我所做的,一行代码没有变化,只是用了一些工具!用人来说,我没有吃减肥药,没有绝食,体重却减了一半!!!不过目前在项目中还没有用到,因为三星部分机型上有两个坑,有些有alpha背景部分的图片会有很明显的黑线,这里就不放图了。这个问题目前不要通过白名单制作webp图片;在小米2刷到4.xx的手机上,没有正确识别xml文件中描述的webp图片,导致界面up后加载xml布局文件,加载文件webp失败,以及报告错误说找不到资源文件,导致应用程序崩溃。跟踪发现小米机器将类Resource代理为MIUIResource,但是这个MIUIResource未能正确识别webp,所以加载资源文件失败。初步判断,暂时没有解决方案,只能无奈放弃这个优化方案。关于第一个目标,图片资源的优化,我就不说了。3.4代码优化第二个目标已经实现,剩下的第三个目标,代码优化,梳理优化路径如下:1.启用proguard代码优化将proguardFilesgetDefaultProguardFile('proguard-android.txt'),'proguard-project。txt'改为proguardFilesgetDefaultProguardFile('proguard-android-optimize.txt'),'proguard-project.txt',开启代码优化后的注意事项请参考附件。2.去除无用库如果apk支持的最新版本是API14,代码中没有使用高于api14的API,可以考虑去除整个android支持库。3.使用更小的库替代方案如果你只使用谷歌统计,那么不要集成整个googleplay服务,只集成需要的部分。4、定期清理废弃代码定期删除无用逻辑和过时的业务功能模块,以及废弃的A/B测试代码。5、业务模块采用插件化框架,代码动态从云端拉取插件。这是另外一个话题,这里不再赘述。apk瘦身的最终结果是10536027字节压缩到4926912字节,压缩了近53%。在摘要脚本中,启用资源混淆和资源压缩。使用7zip而不是zip。在gradle脚本中开启代码混淆优化和无用资源删除。对于小图片,使用压缩工具压缩图片大小。去除无用的资源、语言、本地so库、二方第三方库和解析。使用较小的库。尝试将android支持库完全踢出您的项目。定期清理代码,尝试使用H5编写界面,从云端获取图片,尝试插件业务模块,找到所有以STORE形式存储在zip文件夹中的文件(不限于raw目录),尝试压缩,加载这些资源的替代方案尝试webp图片加载方案寻求突破***,继续学习和尝试新的优化方案。本文档献给“只减肥,产品不负众望”的技术人员!!!
