从Preference组件的更迭看Jetpack的前世今生

简介: 从Preference组件的更迭看Jetpack的前世今生

谈到Jetpack,大家都以为是一堆框架,事实上它的内容要大的多。本文以大家熟知的Preference组件为切入点,逐步探究它的前世今生。

Preference作为设置画面的标准实现,大家都不陌生。这个组件跟随Android系统一同诞生,之后便不断地变更。先是Support库中出现了独立版本,接着整合到了AndroidX中,最后在Android 10的时候完全废弃了SDK版本。

1832b220aa754cd18c504acc7686a560.png

1. Preference的设计

Preference组件的API设计得非常简单、清晰。

  • PreferenceActivity或PreferenceFragment管理画面的生命周期和事件交互
  • PreferenceScreen构建整个设置列表
  • PreferenceCategory和Preference展示一组或单个设置条目

1832b220aa754cd18c504acc7686a560.png

1672149925052.png

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);
    }
}

1832b220aa754cd18c504acc7686a560.png

原理也不复杂:


PreferenceManager和PreferenceInflater负责解析Preference布局构建Preference实例树

PreferenceScreen采用Preference实例树创建PreferenceGroupAdapter实例,并绑定到ListView视图

Adatper#getView()回调到各Preference组件的onBindView()去准备相应的View视图

ListView的性能欠佳,不再适应复杂的设置画面,尤其是内容众多的系统设置App。

3. 混战的Support库

Support库是为新API提供向后兼容性的支持库,包含大量应用组件、视图、Material Design等功能类。重新改写的Preference组件也包含其中。

依据兼容API版本的不同,Support库的分支众多且凌乱,使用起来也愈发繁琐和呆板。

V7包

Preference组件的变更首次出现在Support库的V7包,主要是将SDK版本的Preference组件拷贝过来进行了重写。


对外的API只是微调,区别大体集中在内部的实现细节上:


不再提供专用的PreferenceActivity,只提供面向Fragment的专用类

构建设置列表的PreferenceScreen改为性能更加优秀的RecyclerView来实现

新增PreferenceViewHolder类,用以复用设置条目的视图

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模式进行了跟进,新增了一系列新组件。

1672150022677.png

4. 一统江湖的AndroidX

1832b220aa754cd18c504acc7686a560.png

Support库愈加臃肿的分支和呆板的管理方法困扰着开发者。Google同样不胜其烦,终于推出了`AndroidX`,期望采用全新的包名和版本管理方法彻底解决这个困境。

比如Support库各分支下Preference组件在AndroidX下的对应关系:

1672150061053.png

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

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类进行对比,可以发现:除了格式、书写风格的差异以外,代码逻辑几乎完全一致。

1832b220aa754cd18c504acc7686a560.png

再比如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:Menu → Refactor → Migrate to AndroidX。


更详细的迁移细节可以参考如下这篇文章:


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

AndroidX的构成

依照官方提供的AndroidX构成列表,我概括并制作了一张AndroidX的构成图。

1832b220aa754cd18c504acc7686a560.png

可以看到,实际上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

其他的还有Paging、Navigation和WorkManager

同时Google还给Android开发者展示了推荐的应用架构,随着Jetpack家族的日益壮大,先在看来这个架构图略显简单。

1832b220aa754cd18c504acc7686a560.png

AAC库在完善的过程中,和Support库一起,也逐步往AndroidX中迁移,并孕育出一个更大更强的概念Jetpack。

6. Jetpack又是何方神圣

短短一年后,Android Architecture Components就退出了舞台,Google IO 2018上发布了全新的Jetpack开发套件。

1832b220aa754cd18c504acc7686a560.png

`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机器人的形象,哈哈)

1832b220aa754cd18c504acc7686a560.png

非要总结下Jetpack和AndroidX关系的话,像fundroid大神描述的那样比较贴切。

AndroidX是对SDK以外API的内部管理包,Jetpack则是对外宣传的开发套件。

1832b220aa754cd18c504acc7686a560.png


“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 推出AndroidX,Jetpack开发套件一同发布,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版发布

1832b220aa754cd18c504acc7686a560.png

8. Googleの野望

Android的分支众多、迭代太快,开发者疲于应对。Google一直在试图改变这种混乱局面,从经典的Support库,到变革的AAC库,再到持续火爆的Jetpack套件。


与此同时,随着Android系统愈加完善,SDK也趋于稳定,一年一度的OSV终将是小修小补。但行业的持续发展必将催生层出不穷的新理念、新技术。Google自然不会停下脚步,它将以更高频次、更大范围的动作去变革和应对,而这多将聚焦在SDK以外的领域,比如Jetpack、MAD等。


MAD,全称Modern Android Development,是Google针对Android平台的全新开发理念。它站在比Jetpack更高的视野,旨在通过语言、工具、发行格式、框架等多个层面去指导新型的Android开发。

1832b220aa754cd18c504acc7686a560.png

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



相关文章
|
3月前
|
存储 设计模式 数据库
构建高效的安卓应用:探究Android Jetpack架构组件
【4月更文挑战第20天】 在移动开发的世界中,构建一个既高效又可维护的安卓应用是每个开发者追求的目标。随着Android Jetpack的推出,Google为开发者提供了一套高质量的库、工具和指南,以简化应用程序开发流程。本文将深入探讨Jetpack的核心组件之一——架构组件,并展示如何将其应用于实际项目中,以提升应用的响应性和稳定性。我们将通过分析这些组件的设计原则,以及它们如何协同工作,来揭示它们对于构建现代化安卓应用的重要性。
|
3月前
|
Android开发 开发者
什么是Android Jetpack,它包括哪些组件?
什么是Android Jetpack,它包括哪些组件?
88 0
|
3月前
|
XML 前端开发 IDE
在 Compose 中使用 Jetpack 组件库
在 Compose 中使用 Jetpack 组件库
247 0
|
2月前
|
JavaScript Java Android开发
kotlin安卓在Jetpack Compose 框架下跨组件通讯EventBus
**EventBus** 是一个Android事件总线库,简化组件间通信。要使用它,首先在Gradle中添加依赖`implementation &#39;org.greenrobot:eventbus:3.3.1&#39;`。然后,可选地定义事件类如`MessageEvent`。在活动或Fragment的`onCreate`中注册订阅者,在`onDestroy`中反注册。通过`@Subscribe`注解方法处理事件,如`onMessageEvent`。发送事件使用`EventBus.getDefault().post()`。
171 2
|
3月前
|
前端开发 Android开发
Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)
Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)
Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)
|
3月前
|
存储 数据库 Android开发
构建高效安卓应用:采用Jetpack架构组件优化用户体验
【4月更文挑战第12天】 在当今快速发展的数字时代,Android 应用程序的流畅性与响应速度对用户满意度至关重要。为提高应用性能并降低维护成本,开发者需寻求先进的技术解决方案。本文将探讨如何利用 Android Jetpack 中的架构组件 — 如 LiveData、ViewModel 和 Room — 来构建高质量的安卓应用。通过具体实施案例分析,我们将展示这些组件如何协同工作以实现数据持久化、界面与逻辑分离,以及确保数据的即时更新,从而优化用户体验并提升应用的可维护性和可测试性。
|
3月前
|
存储 数据库 Android开发
使用Android Jetpack组件加速开发流程
【4月更文挑战第14天】Android Jetpack是为提升开发速度和代码质量而生的组件集合,包括`ViewModel`、`LiveData`、`RecyclerView`、`Room`、`WorkManager`等,它们遵循最新设计原则和最佳实践。例如,`RecyclerView`优化列表显示,`Room`简化数据库操作,`WorkManager`处理后台任务,`ViewModel`和`LiveData`分离业务和UI逻辑。此外,`Navigation`和`Paging`分别优化用户导航和数据加载。通过这些组件,开发者能更高效地构建高性能应用,值得学习和使用。
29 2
|
3月前
|
设计模式 前端开发 数据库
构建高效Android应用:使用Jetpack架构组件实现MVVM模式
【4月更文挑战第21天】 在移动开发领域,构建一个既健壮又易于维护的Android应用是每个开发者的目标。随着项目复杂度的增加,传统的MVP或MVC架构往往难以应对快速变化的市场需求和复杂的业务逻辑。本文将探讨如何利用Android Jetpack中的架构组件来实施MVVM(Model-View-ViewModel)设计模式,旨在提供一个更加模块化、可测试且易于管理的代码结构。通过具体案例分析,我们将展示如何使用LiveData, ViewModel, 和Repository来实现界面与业务逻辑的分离,以及如何利用Room数据库进行持久化存储。最终,你将获得一个响应迅速、可扩展且符合现代软件工
54 0
|
3月前
|
Android开发 开发者
什么是Android Jetpack,它包括哪些组件?
【4月更文挑战第17天】Android Jetpack是Google提供的一套工具集,助力开发者高效、稳定地开发Android应用。它包含架构、UI、行为和基础组件,简化了后台任务、导航和生命周期管理,使开发者能专注于创新。随着不断更新,如CameraX的推出,掌握Jetpack对开发者面试和工作至关重要。
46 0
|
3月前
|
存储 SQL 数据库
构建高效Android应用:采用Jetpack架构组件的实践之路
【4月更文挑战第7天】 在快速迭代的移动开发领域,构建一个既健壮又易于维护的Android应用至关重要。本文将深入探讨如何利用Google推出的Jetpack架构组件,实现Android应用的模块化和组件化,从而提升开发效率和应用性能。我们将通过具体实例分析生命周期管理、UI控制器、数据存储等核心组件,展示其在真实应用中的运用,以及如何借助这些组件简化日常开发任务,确保代码的可扩展性和可测试性。