從Preference組件的更迭看Jetpack的前世此生

談到Jetpack,你們都覺得是一堆框架,事實上它的內容要大的多。本文以你們熟知的Preference組件爲切入點,逐步探究它的前世此生。java

Preference做爲設置畫面的標準實現,你們都不陌生。這個組件跟隨Android系統一同誕生,以後便不斷地變動。先是Support庫中出現了獨立版本,接着整合到了AndroidX中,最後在Android 10的時候徹底廢棄了SDK版本。android

12-widget

1. Preference的設計

Preference組件的API設計得很是簡單、清晰。markdown

  • PreferenceActivity或PreferenceFragment管理畫面的生命週期和事件交互
  • PreferenceScreen構建整個設置列表
  • PreferenceCategory和Preference展現一組或單個設置條目
12-widget
做用
PreferenceActivity 提供了Preference佈局設置和查找的ListActivity
PreferenceFragment 展現Preference佈局的專屬Fragment
Preference 全部Preference組件的基類,預設了Preference處理的基本API
PreferenceGroup 擴展自Preference,用以嵌套Preference組件並內置List進行管理
PreferenceScreen 擴展自PreferenceGroup,嵌套Preference組件的根佈局,內部將管理列表View和對應的Adapter
PreferenceCategory 擴展自PreferenceGroup,展現設置條目分組的小標題,不可點擊、不可得到焦點
SwitchPreference 內置了Switch控件的Preference組件,相似的擴展組件還有ListPreference、EditTextPreference等
...

2. 落寞的SDK

Preference組件是Android 1.0發佈就引入的元老級組件,那會RecyclerView還未推出,天然採用經典的ListView構建整個設置列表。架構

使用起來很是簡單,跟普通視圖的寫法並沒有二致。app

<PreferenceScreen android:title="@string/my_preference_settings">
    <PreferenceCategory android:title="@string/my_preference_general" >
        <Preference android:fragment="com.android.settings.applications.ManageApplications" android:key="app" android:title="@string/my_preference_general_apps" />
    </PreferenceCategory>
    ...
</PreferenceScreen>
複製代碼
public class SettingsActivity extends PreferenceActivity {
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        addPreferencesFromResource(R.xml.my_preference_layout);
    }
}
複製代碼
12-widget

原理也不復雜:框架

  1. PreferenceManager和PreferenceInflater負責解析Preference佈局構建Preference實例樹
  2. PreferenceScreen採用Preference實例樹建立PreferenceGroupAdapter實例,並綁定到ListView視圖
  3. Adatper#getView()回調到各Preference組件的onBindView()去準備相應的View視圖

ListView的性能欠佳,再也不適應複雜的設置畫面,尤爲是內容衆多的系統設置App。ide

3. 混戰的Support庫

Support庫是爲新API提供向後兼容性的支持庫,包含大量應用組件、視圖、Material Design等功能類。從新改寫的Preference組件也包含其中。工具

依據兼容API版本的不一樣,Support庫的分支衆多且凌亂,使用起來也愈發繁瑣和呆板。oop

V7包

Preference組件的變動首次出如今Support庫的V7包,主要是將SDK版本的Preference組件拷貝過來進行了重寫。佈局

對外的API只是微調,區別大致集中在內部的實現細節上:

  1. 再也不提供專用的PreferenceActivity,只提供面向Fragment的專用類
  2. 構建設置列表的PreferenceScreen改成性能更加優秀的RecyclerView來實現
  3. 新增PreferenceViewHolder類,用以複用設置條目的視圖
  4. Preference移除onBindView() API,新增onBindViewHolder()來向RecyclerView提供條目的視圖

另外,針對實現變化較大的API,在原有命名上增長Compat字樣,好比PreferenceFragment改成PreferenceFragmentCompat

使用的話需導入額外依賴:

implementation 'com.android.support:preference-v7:28.0.0'
複製代碼

另外要注意的是Fragment里加載佈局的API由addPreferencesFromResource()改成setPreferencesFromResource()。因爲API只是微調,其餘使用起來幾乎沒有變化。

public static class PrefsFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.preferences, rootKey);
    }
}
複製代碼

V14包

第二次變動發生在V14包,區別只是將命名裏的Compat字樣去掉了,弱化了和SDK版本的API差別。

好比:

  • PreferenceFragmentCompat → PreferenceFragment
  • SwitchPreferenceCompat → SwitchPreference
  • PreferenceDialogFragmentCompat → PreferenceDialogFragment

導入只須要細微調整便可:

implementation 'com.android.support:preference-v14:28.0.0'
複製代碼

V17包

隨着Android系統逐漸流行到TV等大屏設備,Google推出了Leanback導航模式,並引入到了V17中。Preference組件也針對Leanback模式進行了跟進,新增了一系列新組件。

新的類 做用
BaseLeanbackPreferenceFragment 相似瑞士軍刀風格的PreferenceFragment抽象基類,內部集成了VerticalGridView控件
LeanbackPreferenceFragment 外層包裹了標題的BaseLeanbackPreferenceFragment子類
LeanbackSettingsFragment 根佈局爲LeanbackSettingsRootView的Fragment組件,主要和LeanbackPreferenceFragment配合使用
LeanbackPreferenceDialogFragment 帶DialogPreference的Leanback Fragment組件
LeanbackListPreferenceDialogFragment 帶ListPreference的LeanbackPreferenceDialogFragment組件

4. 一統江湖的AndroidX

12-widget
Support庫越發臃腫的分支和呆板的管理方法困擾着開發者。Google一樣不勝其煩,終於推出了`AndroidX`,指望採用全新的包名和版本管理方法完全解決這個困境。

好比Support庫各分支下Preference組件在AndroidX下的對應關係:

Support庫 AndroidX
com.android.support:preference-v7 androidx.preference:preference
com.android.support:preference-v14 androidx.legacy:legacy-preference-v14
com.android.support:preference-leanback-v17 androidx.leanback:leanback-preference

​ 使用也很方便,只需指定對應的包名和版本便可:

def preference_version = "1.1.1"
    implementation "androidx.preference:preference:$preference_version"
複製代碼

AndroidX和原有Support庫的API對應關係,能夠到官方的映射表裏進行查詢:

和Support庫到底有無區別?

將最核心的Preference類進行對比,能夠發現:除了格式、書寫風格的差別之外,代碼邏輯幾乎徹底一致。

12-widget

再好比AndroidX裏提供的PreferenceFragment類,其實現和Support庫的版本幾乎是同樣的。

AndroidX replaces the original support library APIs with packages in the androidx namespace. Only the package and Maven artifact names changed; class, method, and field names did not change.

像官方描述的那樣,AndroidX是針對Support庫的整合和替代,區別僅僅體如今倉庫的地址和包名。正由於此,AndroidX擁有清晰統一的版本管理,開發者能便捷和靈活地使用。

ROM開發需留意

以前,Preference組件等新API分散在Support庫的各個分支包裏,源文件也會集成到AOSP源碼,ROM廠商能夠修改。

好比V14包的Preference組件在AOSP源碼的對應位置以下。

​ /frameworks/support/v14/preference/src/android/support/v14/preference/

Android 9開始整合到了AndroidX裏,但爲了過渡,源文件在AOSP源碼裏仍然保留。也就是咱們仍然能夠修改其源碼。

​ /frameworks/support/preference/src/main/java/androidx/preference/

Android 10開始全面轉向AndroidX,完全廢棄Support庫的使用。AOSP源碼裏也再也不集成源文件,只提供了對應的AAR包,這也使得ROM廠商更改實現變得困難,須要額外留意。

​ /prebuilts/sdk/current/androidx/m2repository/androidx/preference/

如何遷移至AndroidX

爲了簡化向後兼容的開發工做,將Support庫全面遷移至AndroidX極爲必要,設置以下的Gradle 插件標誌便可。

  • android.useAndroidX:Android 插件會使用對應的 AndroidX 替代Support庫
  • android.enableJetifier:Android 插件會經過重寫其二進制文件來自動遷移現有的第三方庫,以使用 AndroidX 依賴項

固然在AndroidStudio菜單裏也能夠手動地遷移至AndroidX:MenuRefactorMigrate to AndroidX

更詳細的遷移細節能夠參考以下這篇文章:

www.jianshu.com/p/41de86896…

AndroidX的構成

依照官方提供的AndroidX構成列表,我歸納並製做了一張AndroidX的構成圖。

12-widget

能夠看到,實際上AndroidX在集成了Support庫的之外,還涵蓋了衆多知名的Jetpack框架,這些框架實際上來源於2017年發佈的Android Architecture Components(AAC)。

5. 短暫的AAC庫

Android App開發有不少痛點,包括Activity/Fragment生命週期的管理較爲呆板,線程間數據傳遞的複雜,SQLite封裝的繁瑣等等。爲了改善這些情況並對App架構進行指導,Google IO 2017上發佈了Android Architecture Components,簡稱AAC

它包含了幾個較爲經典的框架:

  • Lifecycle
  • LiveData
  • ViewModel
  • Room
  • 其餘的還有PagingNavigationWorkManager

同時Google還給Android開發者展現了推薦的應用架構,隨着Jetpack家族的日益壯大,先在看來這個架構圖略顯簡單。

12-widget

AAC庫在完善的過程當中,和Support庫一塊兒,也逐步往AndroidX中遷移,並孕育出一個更大更強的概念Jetpack。

6. Jetpack又是何方神聖

短短一年後,Android Architecture Components就退出了舞臺,Google IO 2018上發佈了全新的Jetpack開發套件。

12-widget
`Jetpack`的官方構成圖能夠看出來:
  • 核心的Architecture模塊涵蓋了熟知的框架,前身就是去年發佈的AAC庫

  • 以及從Support庫整合過來的包,好比PreferenceFramgentAppCompat

  • 除此以外,還包括KTXTest工具包等

Android Jetpack is a set of libraries, tools and architectural guidance to help make it quick and easy to build great Android apps. It provides common infrastructure code so you can focus on what makes your app unique.

因此說,將Jetpack理解爲一系列框架不夠準確。實際上它是包含了框架、KTX、開發工具和開發嚮導的開發套件,指望在多個層面提高與Android開發的效率。

  • 提供Android App開發的最佳實踐
  • 消除大量的樣板代碼,幫助開發者更輕鬆地編寫優質應用
  • 提供向後兼容性,在不一樣版本、不一樣配置的設備上提供一致性的開發體驗
  • 改變混亂的散碎的版本管理

和AndroidX到底啥關係?

Jetpack開發套件的源碼管理在AndroidX內,包括以前的Support庫,還有後來吸取的AAC庫等等。簡要繪製了一下Jetpack的演變圖。(畫着畫着,竟畫成了Android機器人的形象,哈哈)

12-widget

非要總結下Jetpack和AndroidX關係的話,像fundroid大神描述的那樣比較貼切。

AndroidX是對SDK之外API的內部管理包,Jetpack則是對外宣傳的開發套件。

12-widget

「AndroidX」的名字也很酷啊,那爲何不直接用它來進行宣傳? 我的的一些理解:

  • 「AndroidX」的命名過於抽象、不易理解,也沒有特別的含義
  • 「Jetpack」本意是噴氣揹包、助推器的意思,它更能傳達助力開發效率騰飛的設計初衷,也易於理解和傳頌。再搭配上Android Logo塑造一個火箭機器人的形象,很是有趣和具有辨識度

7. Jetpack大事記

  • 2011年3月,Support庫 V4包發佈首個版本
  • 2014年10月,Support庫新增RecyclerView,AppCompat支持
  • 2015年8月,Support庫新增Preference支持
  • 2016年2月,Support庫新增VectorDrawable支持
  • 2017年5月17日,Google IO 2017 宣佈推出Android Architecture Components
  • 2017年9月21日,Android Architecture Components 1.0.0 beta版正式發佈
  • 2018年3月,Support庫代碼逐步整合至AndroidX
  • 2018年5月8日,Android Architecture Components的代碼逐步遷至AndroidX
  • 2018年9月21日,Google IO 2018 推出AndroidXJetpack開發套件一同發佈,Support庫終結並轉向AndroidX
  • 2019年5月7日,Jetpack CameraX 1.0.0 alpha版發佈
  • 2020年7月22日,Jetpack Hilt 1.0.0 alpha版發佈
  • 2021年3月10日,Compose 1.0.0 beta版發佈
12-widget

8. Googleの野望

Android的分支衆多、迭代太快,開發者疲於應對。Google一直在試圖改變這種混亂局面,從經典的Support庫,到變革的AAC庫,再到持續火爆的Jetpack套件

與此同時,隨着Android系統越發完善,SDK也趨於穩定,一年一度的OSV終將是小修小補。但行業的持續發展必將催生層出不窮的新理念、新技術。Google天然不會停下腳步,它將以更高頻次、更大範圍的動做去變革和應對,而這多將聚焦在SDK之外的領域,好比Jetpack、MAD等。

MAD,全稱Modern Android Development,是Google針對Android平臺的全新開發理念。它站在比Jetpack更高的視野,旨在經過語言、工具、發行格式、框架等多個層面去指導新型的Android開發。

12-widget

在Jetpack套件之外MAD還囊括了諸多內容,包括:

  • 持續改進的官方IDE,Android Studio
  • Android平臺首推的Kotlin開發語言
  • 先進的Android App Bundle發行格式
  • 將來的UI開發方式Compose工具包

能夠說,MAD是每一個Android開發者都應瞭解和掌握的重要技術,後續我將解讀這個全新的開發理念。

參考資料

AndroidX的版本說明

Support庫的說明

Jetpack的組成

基於Android Architecture Components的應用架構指南

Jetpack與AndroidX的關係

推薦閱讀

Android 12上面目一新的小組件:美觀、便捷和實用

Android 12上全新的應用啓動畫面,還不適配一下?

全面覆盤Android開發者容易忽視的Backup功能

相關文章
相關標籤/搜索