目录
在前两章我们分别从图片资源和jni动态库这两个方面来分析apk瘦身的优化点
Android App 瘦身总结 第一章 图片资源的优化处理
Android App 瘦身总结 第二章 jni动态库及cpu兼容
本章我们从代码角度来继续进行分析。
代码是一个app的核心,但是实际上一款应用真正自有的代码在空间占有率并不多(当然像淘宝微信这样的航母级自有代码也一定十分庞大),更多的是各种依赖引用的框架、lib和第三方sdk等。所以这部分的优化可能效果没有那么显著,但是十分必要,可以通过优化发现代码习惯问题、深入了解业务。
代码优化主要有一下几点:
一、代码混淆proguard
老生常谈的问题,代码混淆主要目的是增加反编译解读源码的难度,提高应用安全性。但是它同时的确带来了代码量的减少,虽然减少的可能不是特别显著。
代码混淆是android apk的常态,建议大家在应用中使用。关于混淆怎么用网上也有太多的文章了,就不列举了大家可以自行搜索。
但是要注意几点:
(1)引入第三方库时,一定要按照官方文档添加混淆,否则很容易出错
(2)引入jar包时(没有官方文档或者官方未给出),尽量不进行混淆。一个是大部分正规的jar包其实已经混淆过了;而是混淆后容易引起问题。
(3)在不完全了解proguard语法时,不要盲目复制粘贴网上提供一个proguard样本,尽量弄清除每一行语法的作用在使用。
(4)在每次发布版本后,一定要保存好对应的mapping文件,可以用于错误统计分析时将堆栈信息反解析回源码。
二、调整第三方库
这个于动态库类似,很多时候我们为了实现一些功能,会利用已有的轮子——第三方库。但是实际上大部分人对轮子没有全面了解,这就造成了一种情况的出现:举例来说就是我们只是想用一个简单计算功能,但我们引入的却是一台超级电脑。
拿我们的App来说,前期疯狂迭代期没有太多时间去考虑这些,当我们回过头来看的时候发现居然用到了二十多个第三方库。其中很多库都是巨无霸级别,是一套完整健全的某个功能的解决方案,但是我们可能只用其中一个组件、一套工具类等等,这就造成了大量的浪费。
所以这时候我们要注意几点:
(1)以最小的代价实现功能:尽量去寻找那些精准的贴合你的需求的第三方库;如果引入的是一个庞大的库而只用极少的功能,可以考虑将使用的功能部分源码直接拿出来使用。
(2)尽量使用同一家平台的服务:比如友盟、百度等,因为很多服务sdk会依赖一些基础jar包,一般同一家平台的都会用同一套基础jar包。如果不同的功能用不同平台的服务,很容易造成同一种基础功能存在多中解决方案的jar包。比如网络请求就存在volley、okhttp等多种解决方案,如果在一个app中使用了太多家平台的服务,就会出现在应用中同时存在volley、okhttp...,功能重复而且浪费。
(3)自己动手丰衣足食:有时候可能我们需要的是一个没有特别复杂的功能,但是可能由于时间紧张等情况使用了第三方库;另外一种情况是前期需要一个复杂的功能,经过几轮迭代后功能简化了。这时候我们就可以考虑抛开第三方库自己来实现,这样也会提高自身的能力。
(4)不要盲目跟风:现今还有一种现象,部分开发者很喜欢跟风新的框架、新的解决方案。关注新技术固然无错,但是要考虑实际应用场景。我面试过一家公司,两个开发者将时下最新最潮的全都塞入了他们的app,但其实那只是一个有十几个页面功能单一的应用。甚至有个框架只用在了一处地方,最大的功效是减少几行代码而已。而apk大小却接近航母级应用了。
这部分需要我们重新审视应用,更好的办法是严格把关第三方库的引入,虽然这样会比较麻烦,但是以后会受益匪浅。
三、环境差异依赖
有时候我们会为应用引入一些监控、校验等帮助测试的第三方库,但是这些其实正式包中没有必要存在。
这时可以考虑只在debug版本的时候依赖即可, 如:
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
但是就会出现一个问题,在我们的代码里需要有一些初始化之类的代码。如果只是debugCompile,编译release版本时就会出错,因为找不到对应的类。
解决方法很简单,android studio允许我们创建不同环境的包,如图
我们在main目录的同级别上创建类release和debug两个环境的目录,在包下各有一个Application。这样编译不同环境的时候,编译器会自动将对应环境的目录中的java文件和mian目录下的java文件一起编译。
这样我们就可以在不同的Application中编写不同的代码,比如在debug目录下的Application中添加leakcancanary的初始化代码,而在release目录下的则没有。这样就不会出现release版本编译问题了。
要注意几点:
(1)在main目录下不能有同样的java文件(如上面的Application)
(2)Application只是个例子,在实际开发中,有差异的java代码尽量保证最少,最好只将不一致的部分封装到不同的环境目录中。比如上面的例子,如果Application代码较多,可以保留在main下,在debug和release下分别创建个LeakManager类,Applicaiton来调用LeakManager的方法即可。
通过这些操作就可以在打release版本是不加入这些与debug有关的第三方库,减少一定的应用大小。
四、代码习惯
另外要养成良好的代码习惯,尽量去写一些高复用的代码,减少应用中的重复代码。定期对代码进行review,小规模的进行代码重构,封装一些频繁使用的工具类等。养成用最少代码完成功能的习惯和能力。这样不仅会让代码结构清晰,也会让代码量大大的减少。
五、插件化
瘦身不是插件化的主要目的,但是一款app发展到航母级别的时候就必须考虑插件化了。关于插件化有很多开源框架,而且IT大佬们也陆续开源了自己的插件化框架,这个框架各有优缺,根据自身应用的特点去选择。
六、总结
本章主要从代码角度分析优化点,其中代码这方面对app瘦身影响没有那么大,因为代码编译打包时都会经过压缩,本身占用空间不会太大。
但是追求极致的目的不是极致,而是在追求极致的过程中提升自己的能力和思维高度。
经过这三章的讲解,关于app瘦身这部分就告一段落了,我相信自己会有理解不到位的情况,而且还有很多未了解未探索的部分,希望大家多提宝贵意见!!谢谢!!