主頁 > 移動端開發 > 從Preference組件的更迭看Jetpack的前世今生

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

2021-06-16 08:01:33 移動端開發

談到Jetpack,大家都以為是一堆框架,事實上它的內容要大的多,本文以大家熟知的Preference組件為切入點,逐步探究它的前世今生,

Preference作為設定畫面的標準實作,大家都不陌生,這個組件跟隨Android系統一同誕生,之后便不斷地變更,先是Support庫中出現了獨立版本,接著整合到了AndroidX中,最后在Android 10的時候完全廢棄了SDK版本,

12-widget

1. Preference的設計

Preference組件的API設計得非常簡單、清晰,

  • 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構建整個設定串列,

使用起來非常簡單,跟普通視圖的寫法并無二致,

<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,

3. 混戰的Support庫

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

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

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-v7androidx.preference:preference
com.android.support:preference-v14androidx.legacy:legacy-preference-v14
com.android.support:preference-leanback-v17androidx.leanback:leanback-preference

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

    def preference_version = "1.1.1"
    implementation "androidx.preference:preference:$preference_version"

AndroidX和原有Support庫的API對應關系,可以到官方的映射表里進行查詢:

  • 包的關系:https://developer.android.com/jetpack/androidx/migrate/artifact-mappings

  • 類的映射關系:https://developer.android.google.cn/jetpack/androidx/migrate/class-mappings

和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

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

https://www.jianshu.com/p/41de8689615d

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功能

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/287629.html

標籤:其他

上一篇:Android開發 Button筆記

下一篇:Android 11.0原始碼系列之IMS(四)InputChannel

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more