Android Jetpack開庭
Jetpack 一定好麼
說別人不好時,要先給與肯定,所以先談下它的優勢
- 谷歌爸爸推出並維護
- 最佳實踐
- 向後相容
- 減少bug率
- 輕鬆實現MVVM架構
其實就第一條就足夠打動很多人用了,但發展至今,對於國內的程式設計師而言,這些新的框架,既熟悉又陌生,就本人而言,我除了熟悉並使用過Lifecycle,AppCompat,Multidex之外,一概沒用過,可能是因為我做業務少了的原因,即便我用的不多,但從元件的角度上講,我還是有一些不滿的,對於Jetpack不好的點,我總結如下:
- 框架複雜
- 易用性也就那樣
- 庫依賴樹也很恐怖,每依賴一個庫,就會帶很多子庫
- 學習成本高,有大佬專門賣Jetpack課程,可見學習成本之高
其實我最想知道的是,如果每個應用都依賴這些庫,打包到自己的apk中,那豈不是存在大量的重複的程式碼?你是不是覺得這些無所謂呢?那我們就算下它的大小,來看看他到底佔了我們多少的空間
Jetpack 有多大
所有的庫都在這裡:
https://developer.android.google.cn/jetpack/androidx/explorer?hl=zh-cn
我們只統計大家常用的庫,來看看到底能有多大,兩個緯度,一個是jar包大小,一個是apk大小,為什麼這樣區分呢?因為Android在打包過程中,會將jar包打包成Dex格式,而Dex對於jar包的合併是有一定的壓縮的,jar和dex前後肯定是有區別的,所以分兩個緯度來看,我們先來建立一個空專案,如下:
一行程式碼沒有,什麼都不引用,來看下專案大小
如何統計專案依賴的Jar包呢?
歷經九九八十一難,我為你找到了合適的方法(相容Gradle 7.0),如下:
它可以將專案中依賴的jar包及aar統統給你找出來,並乖乖的放到專案的build/output/libs 下。
task copyAllDependencies(type: Copy) {
configurations.implementation.setCanBeResolved(true)
configurations.api.setCanBeResolved(true)
from project.configurations.implementation
from project.configurations.api
into "${buildDir}/output/libs"
}
空專案-Jar包統計
指令碼執行完後,如上,jar包總量 1.8MB
空專案-APK包統計
打完包1.2M,下面我們將Jetpack引入,且慢,突然想到,Apk只是使用者下載時的感受,但其實它落盤後有多大呢?這才是佔滿你記憶體的元凶,安裝後如下:
嘿,還變小了
Jetpack專案-Jar包統計
我們將常用的引入,如下:
``` implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.3.0'
def fragment_version = "1.5.0"
// Java language implementation
implementation "androidx.fragment:fragment:$fragment_version"
// Kotlin
implementation "androidx.fragment:fragment-ktx:$fragment_version"
def lifecycle_version = "2.5.0-rc02"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// ViewModel utilities for Compose
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
def nav_version = "2.5.0"
// Java language implementation
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
// Kotlin
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
def paging_version = "3.1.1"
implementation "androidx.paging:paging-runtime:$paging_version"
def room_version = "2.4.2"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "androidx.datastore:datastore-preferences:1.0.0"
implementation "androidx.startup:startup-runtime:1.1.1"
def work_version = "2.7.1"
// (Java only)
implementation "androidx.work:work-runtime:$work_version"
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
```
加這些不過分吧,大小如何,來揭曉
28 - 1.8 ,多了 26.2 MB,不恐怖麼?
Jetpack專案-APK包統計
7.5 - 1.2 ,多了6.3MB,再看安裝完如下:
嘿,多了比之前20k左右
小結一下
| jetpack | jar包 | apk包安裝前 | apk安裝後 | | --------- | ---- | ------- | ------ | | 非Jetpack | 1.8 | 1.2 | 0.755 | | 引入Jetpack | 28 | 7.5 | 7.52 | | 差值 | 26.2 | 6.3 | 6.765 |
通過如上統計,我們假設一種場景,你的應用安裝100款這樣的應用,再假如Android不轉Dex,直接打包執行Jar包,則需要2620/1024≈2.56G,這也是Dex的優勢,而轉Dex後安裝後,則需要676.5M,對於現在的手機而言,真的是小牛一毛,不值一提,所以我的擔心是多餘的,但如果再算上三方庫呢?好吧,我不掙扎了,你們贏了。其實通過這件事我只想表明一個觀點,那就是jetpack隨著時間的推移越來越大,對我的感覺它就像 Framework的升級版,那為什麼不在將來合併到Framework中呢,這樣豈不是兩全其美呢,一來每個應用的包可以在下載時就減少幾M,安裝時又可以少幾M,這樣不好麼?有的人說了,如果合入Framework中,咋用新版本呢?豈不是又造成了另一種困擾呢?其實不用擔心,因為你現在用的Framework,不就有很多基於Framework封裝開源的庫麼,其實就是提供基於Framework版本的增量版本就行了,然後在不久的將來再合併到Framework中。但由於這樣做的成本大於收益,所以谷歌爸爸選擇不作為。
宣判
法官:
Jetpack由於對手機的傷害不足以構成犯罪,現無罪當場釋放。
Jetpack:
這時的心情:又可以自由的玩耍了,繼續猥瑣發育。
我正在參與掘金技術社群創作者簽約計劃招募活動,點選連結報名投稿。
- Android效能優化的底層邏輯
- 程式設計師也適用的人生商業模式
- Android Jetpack開庭
- 深入理解MMAP原理,大廠愛不釋手的技術手段
- 使用mmap實現一個輕量級的跨程序通訊元件
- 騰訊Matrix Gradle 6.5升級適配
- 2020年總結篇
- RecyclerView Adapter系列之整合Lifecycle
- 一個資深程式設計師應該學會用kotlin寫一點執行緒安全的程式碼
- 重學RecyclerView Adapter封裝的深度思考和實現
- 一個資深的Android是不是應該學會自己做一個超級的RecyclerView.Adapter
- Flutter State Management狀態管理全面分析