Gradle更小、更快構(gòu)建APP的奇淫技巧

本文已獲得原作者授權(quán)同意辫呻,翻譯以及轉(zhuǎn)載
原文鏈接:Build your Android app Faster and Smaller than ever
作者:Jirawatee
譯文鏈接:Gradle更小拌汇、更快構(gòu)建APP的奇淫技巧
翻譯人:MrTrying

Gradle

上個月,我有機會在 LINE DEVELOPER DAY 2018 發(fā)表演講屎债。對我來說是特殊的時刻,因為這是我第一次在日本演講垢油。在成為演講者之前盆驹,LINE 活動的工作人員必須向全球團隊提交他們的演講。

LINE DEVELOPER DAY 2018

我提交的主題是關(guān)于如何更快構(gòu)建 Android App滩愁,以及如何生成更小的 APK 的一些技巧躯喇。這些提示來自于我的經(jīng)驗和 Google I/O,特別是在 Developer Build Clinic 中收集到的惊楼。Developer Build Clinic 是 Android Studio 團隊為改進構(gòu)建性能方面提供的一對一咨詢玖瘸。

Developer Build Clinic by Android Studio team

在本文中秸讹,我想與你分享這些技巧和 app檀咙,給你帶來的 app 是 LINE MAN Driver。

LINE MAN

對于不知道 LINE MAN 是什么的人來說璃诀,它是一個按需助理提供專業(yè)服務(wù)的 app弧可,包括食物配送、便利店貨物配送劣欢、信使服務(wù)棕诵、包裹服務(wù)和出租車服務(wù),隨時滿足所有泰國用戶的需求凿将。

請注意校套,實際結(jié)果可能會有所不同,因為它取決于您的項目特征和構(gòu)建環(huán)境牧抵,例如項目規(guī)模笛匙、資源侨把、依賴關(guān)系和機器性能。

構(gòu)建更小App的技巧

APK 的大小將會影響 app 的加載速度妹孙、內(nèi)存占用以及電量消耗秋柄。我想大多數(shù)人都知道,APK 大小是用戶參與度的重要因素蠢正。讓我們來看看當(dāng)前在 LINE MAN Driver 中 app 的大小骇笔。

當(dāng)前app大小是9MB

優(yōu)化 APK,快速的建議是使用 Android Studio 的APK Analyzer嚣崭。打開 Android Studio 笨触,然后選擇Profile or debug APK,瀏覽你的 APK 文件有鹿。

APK Analyzer

Tip 1:移除無用的資源

大多數(shù)人都是在遺留項目中開發(fā)旭旭,有很多圖片、布局和string你從來沒有用過葱跋,但是你不知道也不想自己刪除它持寄,因為你害怕會讓你的 app 崩潰,對嗎娱俺?所以稍味,在 Android Studio 中,它提供了Remove Unused Resources的選項荠卷。

它對我們非常有幫助模庐,因為他能自動找到無用的資源,然后你能一鍵刪除它們油宜。

Tip 2:只添加需要的依賴

有些依賴內(nèi)部包含了一堆庫掂碱,像play-servicesFaceBook SDK。如果你沒有指定你需要的庫慎冤,那你將獲得全部的庫疼燥,讓你的 app 變胖。例如蚁堤,如果你想使用
Google 授權(quán)醉者,你應(yīng)該指定com.google.android.gms:play-services-auth:16.x.x代替com.google.android.gms:play-services:16.x.x

你可以通過下面的命令來細分項目的依賴

$ ./gradlew app:dependencies

你將看到在項目中用到的所有的依賴披诗,然后確保只用你所需要的撬即。

Tip 3:為屏幕密度構(gòu)建多個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構(gòu)建多個APK

這個技巧和前一個技巧相似温圆,但是此技巧是用于支持Application Binary Interfaces(ABIs)挨摸。今天,我認為 Android 市場中有7個 CPU 框架岁歉,其中3個很難找到(mips得运,mips64armeabi)锅移,以此你可以在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構(gòu)建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
    }
  }
}

根據(jù)我的經(jīng)驗肺素,我更喜歡這個技巧恨锚,因為我曾經(jīng)在多個APK的情況中在某些設(shè)備上發(fā)現(xiàn)了崩潰。

Tip 6:刪除未使用替代資源

有時倍靡,你創(chuàng)建一個本地的 app猴伶,你只想支持一些特殊的語言。但是塌西,有一些依賴包含全世界的很多語言他挎,你不需要所有的這些。因此捡需,你可以使用resConfigs屬性指定你想要的語言办桨,你的 app 將更小。

android {
  defaultConfig {
    resConfigs 'en', 'th'
    ...
  }
}

Tip 7:壓縮無用代碼和資源

默認情況下栖忠,Android Studio 的 minifyEnabledfalse崔挖,但我認為很多人為了更小和安全因素把它設(shè)置為true來縮小和混淆你的代碼贸街。我建議你在app/build.gradle中添加shrinkResources庵寞,在壓縮(minify)進程之后刪除無用的資源。因為在壓縮中薛匪,gradle將移除無用的代碼捐川,這些代碼可能會引用一些資源。

最后逸尖,我想大多數(shù)人都不知道-optimize古沥。你能在proguard-android之后添加-optimize瘸右,它將為你構(gòu)建 app 做更多的優(yōu)化,你的 app 將會更小岩齿。

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

請注意太颤,此過程將花很多時間,所以你應(yīng)該只在發(fā)布快中使用-optimize盹沈。

Tip 8:使用Shape Drawable

有時候龄章,我看到開發(fā)者使用Bitmap的漸變背景或者圓角圖。實際上乞封,bitmap圖比 Android Studio 提供的Shape Drawable更大做裙,因為在Shape Drawable中,你可以以xml的格式繪制矩形肃晚、橢圓锚贱、圓、圓角和其他关串。

Tip 9:使用Webp

相同質(zhì)量下 Webp 更小拧廊,最多30%。唯一需要注意的是操作系統(tǒng)的要求晋修。如果你使用不透明的背景卦绣,Webp 的 API 等級是API 15及以上支持。但是如果你想在 Webp 中支持透明背景飞蚓,你需要支持API 18或者更高滤港,Android Studio 還為您提供了一種將圖像轉(zhuǎn)換為 WebP 格式的簡便方法。你可以右擊你想要的圖片趴拧,選擇Convert to WebP溅漾,然后你會看到下圖。

因此著榴,讓我們看一個示例結(jié)果添履,圖像尺寸減小到原始尺寸的15%,質(zhì)量為90%脑又。

Tip 10:使用VectorDrawable

API 21起暮胧,確保vectorbitmap更小,你能使用vector代替bitmap圖片问麸。因為VectorDrawable能以相同質(zhì)量的圖往衷,降低大小到不同屏幕密度。

如果你正在支持minSdkVersion 20或者更低严卖。別擔(dān)心席舍,你可以用它。因為 Android 團隊提供了一個庫哮笆。因此你只需要使用23.2及其以上支持庫来颤。

累積改進

這是在應(yīng)用這些技巧后所累積的改進

還有一件事

從 Android Studeio 3.2 開始汰扭,Android App Bundle是一種新的 app 發(fā)布格式,可以讓你的 app 小的更輕松福铅。你不需要添加一行代碼萝毛,只需要使用新方法導(dǎo)出即可。因此滑黔,當(dāng)你下載你的 app 時珊泳,Google Play 動態(tài)傳輸指定設(shè)備需要的代碼和資源。

通過這種方式你不需要自己構(gòu)建多個 APK 了拷沸。

請注意色查,文件擴展名師.aab,你需要花更多的時間來構(gòu)建撞芍,但這是值得的秧了。

更快構(gòu)建app的技術(shù)

和 Android 開發(fā)者想要改進的一樣,構(gòu)建速度對工作效率至關(guān)重要序无。從這個問題我有10個技術(shù)可以更快的構(gòu)建 LINE MAN Driver app验毡。

優(yōu)化之前,我想讓你看看 LINE MAN Driver app 現(xiàn)在在 Android Studio 3.2.1 的完整構(gòu)建速度帝嗡。

現(xiàn)在構(gòu)建 LINE MAN Driver 的時間是3分鐘晶通。

Technique 1:使用最新的Android plugin

第一個技術(shù),確保你的 Android Gradle plugin 是最新的哟玷。因為有很多錯誤修復(fù)和性能問題被修復(fù)狮辽。

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

第二個技術(shù)是避免 Legacy Multidex。如你所知巢寡,如果你的 app 超過64k方法限制喉脖,你需要使用 Multidex。如果你的的minSdkVersion是21或更低抑月,你也是用 Multidex树叽,那么你將使用 Legacy Multidex,這會使你在構(gòu)建時變慢谦絮。

要避免 Legacy Multidex题诵,你可以定義新的flavor,并在app/build.gradle中指定minSdkVersion21或更高层皱。

productFlavors {
  development {
    minSdkVersion 21
    ...
  }
}

Technique 3:禁用Multi APK

第三個技術(shù)性锭,你應(yīng)該在開發(fā)構(gòu)建環(huán)境禁用多個 APK 生成,因為打包和創(chuàng)建這些 APK 需要時間奶甘。所以篷店,你能在app/build.gradle的 debug 代碼塊中添加以下兩行代碼禁用它祭椰。

buildTypes {
  ...
  debug {
    splits.abi.enable = false
    splits.density.enable = false
  }
}

Technique 4:包含最少的資源

在你開發(fā)構(gòu)建中最小化打包的資源臭家。默認情況下疲陕,構(gòu)建系統(tǒng)包含 app 和庫使用的所有語言和屏幕密度。開發(fā)期間你不需要用到所有的這些資源钉赁,你能通過添加resConfigs來使用這些資源中的一組蹄殃,并指定開發(fā)構(gòu)建所需的語言和屏幕密度。

productFlavors {
  dev {
    resConfigs('en', 'xhdpi')
    ...
  }
}

Technique 5:禁用PNG縮緊

默認情況AAPT將會縮進PNG來減小它們的大小你踩,對于你發(fā)布 APK 是一件好事诅岩,但是它對于你開發(fā)構(gòu)建并不重要。要避免PNG縮緊带膜,你可以使用下面的屬性并將其設(shè)置為false吩谦。

buildTypes {
  ...
  debug {
    aaptOptions.cruncherEnabled = false
    ...
  }
}

Technipue 6:使用Instant Run

默認情況下,當(dāng)你點擊 RUN 按鈕時膝藕,系統(tǒng)將會嘗試冷切換式廷,app 需要重啟,但是當(dāng)你點擊 Apply Changes 按鈕時芭挽,系統(tǒng)將先嘗試熱交換滑废,這會將更改直接推送到實時進程。

Technipue 7:禁用更新構(gòu)建ID

下一個技能是在 Firebase Crashlytyics 中禁用更新構(gòu)建ID袜爪。我想很多人使用 Crashlytics蠕趁,每次構(gòu)建 Crashlytics 將默認生成一個唯一的構(gòu)建ID。你可能不知道他們?yōu)槟闾峁┝艘粋€關(guān)閉它的方式辛馆,如下

buildTypes {
  debug {
    ext.alwaysUpdateBuildId = false
    ...
  }
}

你需要注意俺陋,只在 debug 塊中設(shè)置為false

Technipue 8:不要使用動態(tài)版本

Gradle 通過在依賴行末尾添加+昙篙,提供一種非常方便獲取每個依賴的最新版本倔韭。它將使 Gradle 每24小時檢查庫的新版本,并增加構(gòu)建時間瓢对。

android {
  dependencies {
    implementation 'com.android.support:appcompat-v7:+'
    ...
  }
}

Technipue 9:配置gradle.properties

這里的代碼是我從 Android 開發(fā)經(jīng)驗中收集的配置寿酌。對我而言,它們就像一種魔法硕蛹,可以幫助你更快地構(gòu)建 app醇疼。

例如,默認情況下法焰,Android Studio 會為你提供1.5GB的內(nèi)存秧荆,這可能是好事或壞事,因為它實際上取決于你項目的特征埃仪。

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

因此乙濒,我鼓勵你嘗試這些配置,我保證你將節(jié)省大量的建設(shè)時間。

Technipue 10:使用R8新代碼shrinker

下一步是什么颁股?在即將推出的 Android Studio 3.3 中可以使用R8的下一代代碼shrinker么库。它將減少無用的代碼和資源,并縮小您的源代碼甘有。因此 Android Studio 聲稱構(gòu)建時間和 APK 大小會更小诉儒。

image.png

累積改進

讓我們看看,在使用這些技巧之后新的完整建筑速度】飨疲現(xiàn)在我花了大約1分鐘完成建設(shè)忱反。所以這次累積改進,完整版本現(xiàn)在快3倍滤愕。

總結(jié)

你想象一下温算,如果你的舊項目比 LINE MAN Driver 程序應(yīng)用程序更大,你可以減少多少大小以及可以節(jié)省多少時間间影。

以下是我在 LINE DEVELOPER DAY 2018 的演講中的幻燈片和視頻

所以我希望這些技巧和技巧可以幫助你提高生產(chǎn)力米者。

Enjoy coding,Thank you宇智!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蔓搞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子随橘,更是在濱河造成了極大的恐慌喂分,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件机蔗,死亡現(xiàn)場離奇詭異蒲祈,居然都是意外死亡,警方通過查閱死者的電腦和手機萝嘁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門梆掸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人牙言,你說我怎么就攤上這事酸钦。” “怎么了咱枉?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵卑硫,是天一觀的道長。 經(jīng)常有香客問我蚕断,道長欢伏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任亿乳,我火速辦了婚禮硝拧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己障陶,他們只是感情好滋恬,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咸这,像睡著了一般夷恍。 火紅的嫁衣襯著肌膚如雪魔眨。 梳的紋絲不亂的頭發(fā)上媳维,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天,我揣著相機與錄音遏暴,去河邊找鬼侄刽。 笑死,一個胖子當(dāng)著我的面吹牛朋凉,可吹牛的內(nèi)容都是我干的州丹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼杂彭,長吁一口氣:“原來是場噩夢啊……” “哼墓毒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起亲怠,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤所计,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后团秽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體主胧,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年习勤,在試婚紗的時候發(fā)現(xiàn)自己被綠了踪栋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡图毕,死狀恐怖夷都,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情予颤,我是刑警寧澤损肛,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站荣瑟,受9級特大地震影響治拿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜笆焰,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一劫谅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦捏检、人聲如沸荞驴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熊楼。三九已至,卻和暖如春能犯,著一層夾襖步出監(jiān)牢的瞬間鲫骗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工踩晶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留执泰,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓渡蜻,卻偏偏與公主長得像术吝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子茸苇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359