Gradle更小、更快构建APP的奇淫技巧

androidstarjacksky · · 1828 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

> **本文已获得原作者授权同意,翻译以及转载** > 原文链接:[Build your Android app Faster and Smaller than ever](https://medium.com/linedevth/build-your-android-app-faster-and-smaller-than-ever-25f53fdd3cdc) > 作者:[Jirawatee](https://medium.com/@jirawatee) > 译文链接:[Gradle更小、更快构建APP的奇淫技巧](https://www.jianshu.com/p/5dd1d8db8f2c) > 翻译人:[MrTrying](https://www.jianshu.com/u/70bd9fefe61f) ![ ](//upload-images.jianshu.io/upload_images/595349-cca57384753d61d4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/800/format/webp) 上个月,我有机会在 LINE DEVELOPER DAY 2018 发表演讲。对我来说是特殊的时刻,因为这是我第一次在日本演讲。在成为演讲者之前,LINE 活动的工作人员必须向全球团队提交他们的演讲。 ![ ](//upload-images.jianshu.io/upload_images/595349-8c3716ddd30341e8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/800/format/webp) 我提交的主题是关于如何更快构建 Android App,以及如何生成更小的 APK 的一些技巧。这些提示来自于我的经验和 Google I/O,特别是在 Developer Build Clinic 中收集到的。Developer Build Clinic 是 Android Studio 团队为改进构建性能方面提供的一对一咨询。 ![ ](//upload-images.jianshu.io/upload_images/595349-e6dfc26843a8c493.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/800/format/webp) 在本文中,我想与你分享这些技巧和 app,给你带来的 app 是 LINE MAN Driver。 ![ ](//upload-images.jianshu.io/upload_images/595349-ca0360b05a6295ec.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/800/format/webp) 对于不知道 LINE MAN 是什么的人来说,它是一个按需助理提供专业服务的 app,包括食物配送、便利店货物配送、信使服务、包裹服务和出租车服务,随时满足所有泰国用户的需求。 > 请注意,实际结果可能会有所不同,因为它取决于您的项目特征和构建环境,例如项目规模、资源、依赖关系和机器性能。 ### 构建更小App的技巧 APK 的大小将会影响 app 的加载速度、内存占用以及电量消耗。我想大多数人都知道,APK 大小是用户参与度的重要因素。让我们来看看当前在 LINE MAN Driver 中 app 的大小。 ![ ](//upload-images.jianshu.io/upload_images/595349-bd11326e37781aba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/438/format/webp) 优化 APK,快速的建议是使用 Android Studio 的APK Analyzer。打开 Android Studio ,然后选择Profile or debug APK,浏览你的 APK 文件。 ![ ](//upload-images.jianshu.io/upload_images/595349-7df46c3d9bfd6263.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp) ##### Tip 1:移除无用的资源 大多数人都是在遗留项目中开发,有很多图片、布局和string你从来没有用过,但是你不知道也不想自己删除它,因为你害怕会让你的 app 崩溃,对吗?所以,在 Android Studio 中,它提供了Remove Unused Resources的选项。 ![ ](//upload-images.jianshu.io/upload_images/595349-c0964f191279931a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp) 它对我们非常有帮助,因为他能自动找到无用的资源,然后你能一键删除它们。 ##### Tip 2:只添加需要的依赖 有些依赖内部包含了一堆库,像play-services和FaceBook SDK。如果你没有指定你需要的库,那你将获得全部的库,让你的 app 变胖。例如,如果你想使用 Google 授权,你应该指定com.google.android.gms:play-services-auth:16.x.x代替com.google.android.gms:play-services:16.x.x。 你可以通过下面的命令来细分项目的依赖 ``` $ ./gradlew app:dependencies ``` 你将看到在项目中用到的所有的依赖,然后确保只用你所需要的。 ![ ](//upload-images.jianshu.io/upload_images/595349-298388170d58f151.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/949/format/webp) ##### Tip 3:为屏幕密度构建多个APK 默认情况下,Android Studio 将会生成一个包含所有屏幕密度的通用 APK。在此技能中,你能专门排除或包含你想要在app/build.gradle支持的屏幕密度,Android Studio 将会为你生成多个 APK。 ``` android { splits { density { enable true // Specify a list of screen densities which Gradle won't create multiple APKs for exclude 'ldpi', 'mdpi' // Specify a list of compatible screen size for the manifest compatibleScreens 'small', 'normal', 'large', 'xlarge' } } } ``` 所以,你需要将他们所有都上传到 Google Play,最终你的用户将会下载与他们屏幕密度匹配的 APK。 ##### Tip 4:为ABI构建多个APK 这个技巧和前一个技巧相似,但是此技巧是用于支持Application Binary Interfaces(ABIs)。今天,我认为 Android 市场中有7个 CPU 框架,其中3个很难找到(mips,mips64,armeabi),以此你可以在app/build.gradle指定你想要支持的 ABI,Android Studio 将会为你生成多个 APK。 ``` android { splits { abi { enable true reset() // Specify a list of ABIs that Gradle should create APKs for include 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a' // If you don’t want to generate a universal APK that includes all ABIs. universalApk false } } } ``` 然后,你需要将他们所有都上传到 Google Play,最后你的用户将会下载与他们 CPU 匹配的 APK。 ##### Tip 5:使用特定的ABI构建APK 这个技巧不同于多个 APK。你能指定你想要支持的 CPU 框架,Android Studio 将只生成一个 APK。 ``` android { defaultConfig { ... ndk { abiFilters 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a' // armeabi, mips and mips64 has removed since NDK r17 } } } ``` 根据我的经验,我更喜欢这个技巧,因为我曾经在多个APK的情况中在某些设备上发现了崩溃。 ##### Tip 6:删除未使用替代资源 有时,你创建一个本地的 app,你只想支持一些特殊的语言。但是,有一些依赖包含全世界的很多语言,你不需要所有的这些。因此,你可以使用`resConfigs`属性指定你想要的语言,你的 app 将更小。 ``` android { defaultConfig { resConfigs 'en', 'th' ... } } ``` ##### Tip 7:压缩无用代码和资源 默认情况下,Android Studio 的 minifyEnabled为false,但我认为很多人为了更小和安全因素把它设置为true来缩小和混淆你的代码。我建议你在app/build.gradle中添加shrinkResources,在压缩(minify)进程之后删除无用的资源。因为在压缩中,gradle将移除无用的代码,这些代码可能会引用一些资源。 最后,我想大多数人都不知道-optimize。你能在proguard-android之后添加-optimize,它将为你构建 app 做更多的优化,你的 app 将会更小。 ``` android { buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } ``` > 请注意,此过程将花很多时间,所以你应该只在发布快中使用`-optimize`。 ##### Tip 8:使用Shape Drawable 有时候,我看到开发者使用Bitmap的渐变背景或者圆角图。实际上,bitmap图比 Android Studio 提供的Shape Drawable更大,因为在Shape Drawable中,你可以以`xml`的格式绘制矩形、椭圆、圆、圆角和其他。 ![ ](//upload-images.jianshu.io/upload_images/595349-2c0d9bda6ab5e1dd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp) ##### Tip 9:使用Webp ![ ](//upload-images.jianshu.io/upload_images/595349-5660546127d46032.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp) 相同质量下 Webp 更小,最多30%。唯一需要注意的是操作系统的要求。如果你使用不透明的背景,Webp 的 API 等级是API 15及以上支持。但是如果你想在 Webp 中支持透明背景,你需要支持API 18或者更高,Android Studio 还为您提供了一种将图像转换为 WebP 格式的简便方法。你可以右击你想要的图片,选择Convert to WebP,然后你会看到下图。 ![ ](//upload-images.jianshu.io/upload_images/595349-30745fbd531e05a7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp) 因此,让我们看一个示例结果,图像尺寸减小到原始尺寸的15%,质量为90%。 ##### Tip 10:使用VectorDrawable 从API 21起,确保vector比bitmap更小,你能使用vector代替bitmap图片。因为VectorDrawable能以相同质量的图,降低大小到不同屏幕密度。 ![ ](//upload-images.jianshu.io/upload_images/595349-d63e82a404ace803.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/997/format/webp) 如果你正在支持minSdkVersion 20或者更低。别担心,你可以用它。因为 Android 团队提供了一个库。因此你只需要使用23.2及其以上支持库。 ##### 累积改进 这是在应用这些技巧后所累积的改进 ![ ](//upload-images.jianshu.io/upload_images/595349-d2732c321b90008f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/434/format/webp) ##### 还有一件事 从 Android Studeio 3.2 开始,Android App Bundle是一种新的 app 发布格式,可以让你的 app 小的更轻松。你不需要添加一行代码,只需要使用新方法导出即可。因此,当你下载你的 app 时,Google Play 动态传输指定设备需要的代码和资源。 通过这种方式你不需要自己构建多个 APK 了。 > 请注意,文件扩展名师.aab,你需要花更多的时间来构建,但这是值得的。 ![ ](//upload-images.jianshu.io/upload_images/595349-540c87ad9d744476.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/960/format/webp) ### 更快构建app的技术 和 Android 开发者想要改进的一样,构建速度对工作效率至关重要。从这个问题我有10个技术可以更快的构建 LINE MAN Driver app。 优化之前,我想让你看看 LINE MAN Driver app 现在在 Android Studio 3.2.1 的完整构建速度。 ![](//upload-images.jianshu.io/upload_images/595349-19fb23dcffa568a1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp) 现在构建 LINE MAN Driver 的时间是3分钟。 ##### Technique 1:使用最新的Android plugin 第一个技术,确保你的 Android Gradle plugin 是最新的。因为有很多错误修复和性能问题被修复。 ``` buildscript { repositories { jcenter() google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0' + classpath 'com.android.tools.build:gradle:3.2.1' } ... } ``` ##### Technique 2:避免Legacy Multidex 第二个技术是避免 Legacy Multidex。如你所知,如果你的 app 超过64k方法限制,你需要使用 Multidex。如果你的的minSdkVersion是21或更低,你也是用 Multidex,那么你将使用 Legacy Multidex,这会使你在构建时变慢。 要避免 Legacy Multidex,你可以定义新的flavor,并在app/build.gradle中指定minSdkVersion为21或更高。 ``` productFlavors { development { minSdkVersion 21 ... } } ``` ##### Technique 3:禁用Multi APK 第三个技术,你应该在开发构建环境禁用多个 APK 生成,因为打包和创建这些 APK 需要时间。所以,你能在app/build.gradle的 debug 代码块中添加以下两行代码禁用它。 ``` buildTypes { ... debug { splits.abi.enable = false splits.density.enable = false } } ``` ##### Technique 4:包含最少的资源 在你开发构建中最小化打包的资源。默认情况下,构建系统包含 app 和库使用的所有语言和屏幕密度。开发期间你不需要用到所有的这些资源,你能通过添加resConfigs来使用这些资源中的一组,并指定开发构建所需的语言和屏幕密度。 ``` productFlavors { dev { resConfigs('en', 'xhdpi') ... } } ``` ##### Technique 5:禁用PNG缩紧 默认情况AAPT将会缩进PNG来减小它们的大小,对于你发布 APK 是一件好事,但是它对于你开发构建并不重要。要避免`PNG`缩紧,你可以使用下面的属性并将其设置为false。 ``` buildTypes { ... debug { aaptOptions.cruncherEnabled = false ... } } ``` ##### Technipue 6:使用Instant Run 默认情况下,当你点击 RUN按钮时,系统将会尝试冷切换,app 需要重启,但是当你点击 Apply Changes按钮时,系统将先尝试热交换,这会将更改直接推送到实时进程。 ![ ](//upload-images.jianshu.io/upload_images/595349-57bfa74b420f69e3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp) ##### Technipue 7:禁用更新构建ID 下一个技能是在 Firebase Crashlytyics 中禁用更新构建ID。我想很多人使用 Crashlytics,每次构建 Crashlytics 将默认生成一个唯一的构建ID。你可能不知道他们为你提供了一个关闭它的方式,如下 ``` buildTypes { debug { ext.alwaysUpdateBuildId = false ... } } ``` 你需要注意,只在 debug 块中设置为false。 ##### Technipue 8:不要使用动态版本 Gradle 通过在依赖行末尾添加+,提供一种非常方便获取每个依赖的最新版本。它将使 Gradle 每24小时检查库的新版本,并增加构建时间。 ``` android { dependencies { implementation 'com.android.support:appcompat-v7:+' ... } } ``` ##### Technipue 9:配置gradle.properties 这里的代码是我从 Android 开发经验中收集的配置。对我而言,它们就像一种魔法,可以帮助你更快地构建 app。 例如,默认情况下,Android Studio 会为你提供1.5GB的内存,这可能是好事或坏事,因为它实际上取决于你项目的特征。 ``` org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 org.gradle.daemon=true org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.caching=true android.enableBuildScriptClasspathCheck=false ``` 因此,我鼓励你尝试这些配置,我保证你将节省大量的建设时间。 ##### Technipue 10:使用R8新代码shrinker 下一步是什么?在即将推出的 Android Studio 3.3 中可以使用R8的下一代代码`shrinker`。它将减少无用的代码和资源,并缩小您的源代码。因此 Android Studio 声称构建时间和 APK 大小会更小。 ![image](//upload-images.jianshu.io/upload_images/595349-d63d639103ef3a6d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/800/format/webp) ##### 累积改进 让我们看看,在使用这些技巧之后新的完整建筑速度。现在我花了大约1分钟完成建设。所以这次累积改进,完整版本现在快3倍。 ![image](//upload-images.jianshu.io/upload_images/595349-e6f73de76c2f9fb1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/800/format/webp) ![ ](https://upload-images.jianshu.io/upload_images/14371339-a715421e5d90ec64.gif?imageMogr2/auto-orient/strip) ### 总结 你想象一下,如果你的旧项目比 LINE MAN Driver 程序应用程序更大,你可以减少多少大小以及可以节省多少时间。 以下是我在 LINE DEVELOPER DAY 2018 的演讲中的幻灯片和视频 * [Slide](https://www.slideshare.net/linecorp/build-your-android-app-faster-and-smaller-than-ever) * [Youtube](https://www.youtube.com/watch?v=tfBIkBbQBbE) 所以我希望这些技巧和技巧可以帮助你提高生产力。 **Enjoy coding,Thank you!** ### 阅读更多 [**在Java中如何优雅地判空**](http://mp.weixin.qq.com/s?__biz=MzI3OTU0MzI4MQ==&mid=2247486892&idx=1&sn=9fa1b52415a2236d3b737693b4d6aba2&chksm=eb476132dc30e824287a4889fb87640f62edca5a34bd104b451de8396511e20302968a0cc7b9&scene=21#wechat_redirect) [**我为什么主张反对使用Android Fragment**](http://mp.weixin.qq.com/s?__biz=MzI3OTU0MzI4MQ==&mid=2247486895&idx=1&sn=b13dfa7e8d8f93b265256fca5868c01e&chksm=eb476131dc30e8278342b9b0749502558e7049d50f4a1795e565bb467d7e305daa7bb2b36842&scene=21#wechat_redirect) [**NDK项目实战—高仿360手机助手之卸载监听**](http://mp.weixin.qq.com/s?__biz=MzI3OTU0MzI4MQ==&mid=2247485690&idx=1&sn=44537ca3fcfb5347df3dde1a388cc4dc&chksm=eb476464dc30ed72a0a9f1cabd86375a0a18bd1478e8ca7e17bb7bcc81bc9ebc553b5f24c1f5&scene=21#wechat_redirect) [**(Android)面试题级答案(精选版)**](http://mp.weixin.qq.com/s?__biz=MzI3OTU0MzI4MQ==&mid=2247485690&idx=1&sn=44537ca3fcfb5347df3dde1a388cc4dc&chksm=eb476464dc30ed72a0a9f1cabd86375a0a18bd1478e8ca7e17bb7bcc81bc9ebc553b5f24c1f5&scene=21#wechat_redirect) [**又撸一年的代码!尽管我秃头还白发,我还是坚持了**](http://mp.weixin.qq.com/s?__biz=MzI3OTU0MzI4MQ==&mid=2247486901&idx=1&sn=9d9beb8925fa1dfaf87f1ba843ee3f6d&chksm=eb47612bdc30e83dd4e41bd0301fb642e872a2f0309ced346a7f94125cf496ef690d6047e0dd&scene=21#wechat_redirect) #### 相信自己,没有做不到的,只有想不到的 在这里获得的不仅仅是技术!如果您觉得不错,欢迎关注和交流! ![ ](http://upload-images.jianshu.io/upload_images/14371339-bef5adcd20423627?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1828 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传