理解Android Support Library

甘西岭
2023-12-01

原作者Josh Hight
原文

Android平台的最大优势之一就在于它支持各种类型的设备。从你的手机、平板、智能手表到你的电视、汽车等等,不一而足。Android希望自己可以成为全能的移动终端操作系统。从用户数字上来看,Android在完成这一目标的路上走得相当成功——在我写这篇文章时,有超过两万种不同的设备正在使用Android系统。我们可以说,这一成就已经超过了以往的任何一种操作系统。

当然,支持如此众多的设备就意味着一系列的挑战。因为尽管不同设备在硬件及软件上有极大的不同,用户们却还是希望apps可以在每一种设备上都能够可靠地运行。与此同时,Android的不断更新还给应用开发者们带来了一种特别的麻烦——用户们往往用着过时的Android系统。实际上在开发应用时,开发者们都应该预设他们的用户正在使用着18个月前的Android版本。

我们不妨设想一下,在这样一种情况下,为了让自己的产品适应大多数用户,应用开发者们将会被迫做出一些令人懊恼的让步,比如放弃新功能以兼容老版本的Android。幸运的是,Android开发团队将兼容老的系统版本及硬件设备视为极为重要的任务,他们站出来为开发者们提供了帮助以使得开发者们并不用那么大费周章的自己去解决兼容问题。然而,这种帮助听起来有些不切实际,因为想要在将来发布的Android版本中兼容老版本这种事情并不那么容易,毕竟Android的API总是要随着时间而不断更新的。这些新的API又怎样能同时兼顾老的Android系统呢?

答案就是“Android Support Library

Android Support Library是什么?

Android Support Library在2011年被最早发布时被称为 Android Compatibility Library。在那时它是被使用的最为广泛的Android Library。应用开发者们在那时已经知道 Android Support Library为老的系统版本提供了新的API。然而这只是故事的开始。
Android Support Library并不是一个单独的Library,而是一系列Library的合集。我们可以简单地将这些合计分为两个部分:兼容库和组件库(compatibility and component libraries)。

每一个Library都使用一种命名规范来指定向下兼容的最低版本SDK,开发者们在自己的项目中必须导入Library的名字。Library的命名规范有时看起来会令人困惑,因为人们总是自然而然的认为高版本号的Library兼容着低版本号Library的内容(比如你会认为v7-appcompat改进并兼容着v4的内容)。可惜在大多数情况下,这种脑补出的兼容情况是不存在的。而似乎是为了增加这种困惑一样,Library有一个自己的“修订编号”。举例来说,“AppCompat v21”实际上指的是支持 v7-appcompat的修订版本21。

兼容库 Compatibility Libraries

Compatibility Libraries致力于将新的Android的特性向后提供给老的Android版本。如此一来人们就可以在老设备上享受到新版本API所带来的便利。其中,最主要的Compatibility Librariesv4v7-appcompat

v4

身躯庞大的v4库是这类Library的始祖。如其名称所示,它将众多的新特性提供给古老的API 4.
除了支持常见类如FragmentLoader(两者在API 11中被引入),你还能再v4库里见到一些在其他地方找不到的常用类,比如ViewPagerDrawerLayout

别被他的名字给忽悠了,尽管是一个直通Android1.6的老古董,它却还是一个在当前版本中被广泛使用的的重要Library。在开发过程中,我们总会用到它。

v7-appcompat

这个Library常被人简称为AppCompat,它让API 7可以实现在API 11中被引入的ActionBar以及在API 21中才被引入的Toolbar。这个Library需要v4库的支持,却并不包含v4库的内容。所以,任何需要v7库支持的特性都必须得到v4库的支持。

底层

Compatibility Libraries大量的使用了垫片(shims)来将新特性兼容到老版本中。如果用户使用的系统版本支持程序调用的API,那么这些垫片就仅仅像一个薄薄的表层覆盖在被调用的组件上,你不会感觉到它的存在。而如果用户使用了陈旧的系统版本,这些垫片就会调用某些轻量级的支持,以代替组件自己来实现Android系统框架接口或传递参数。
当然,在某些情况下这些兼容性的垫片并不会被使用,或者说程序并不去实现Android系统框架接口。因为Library往往更倾向于实现自己的接口来取代Android提供的框架接口。即使设备的当前系统版本支持那些框架接口。比如,v4中的Fragment

这种处理方式颇有些趣味,它会产生某种连锁反应,这就仿佛在平静的Android系统框架中丢进了一颗石子,激起层层涟漪。为了实现这一机制,谷歌为Android的重要的特性开发了不止一种的实现接口,他们重复创建了各种函数,然后把这些东西封装成不同的类和资源包,做成了API。所有这些API并行存在于Android里,它们拥有各自自己的继承关系,版本,以及bug

当然,谷歌声称除了封装包的名字以及少数“不重要的”方法名不同以外,这些重复的API往往都是相同的。然而在实践中,我们总能发现一些并不是那么“不重要的”API之间的不同。而随着时间的推移,这些区别会慢慢扩大。

问题还不仅如此,应用开发者们往往会认为他们在Android框架接口和Support Library接口中拥有选择的余地。结果却发现这些Library的相互依赖关系会代替开发者们做出选择。举例来说,v7-appcompat library为开发者们提供了Material Design UIAPI 21引入) 。然而其中的所有Activity都继承自 v4 libraryFragmentActivity。于是在项目中,所有针对低于API 21的开发工作都必须使用v4 library里的Fragments,而不是Android框架所提供的Fragments

即使有的时候并不需要support libraries的支持,谷歌仍然认为使用它们是很好的开发习惯。在为开发者们提供的大多数开发范例和开发模板中,谷歌都使用了v7-appcompatv4
谷歌在开发这些support libraries上投入了相当大的精力。同时,谷歌也希望开发者们能够真正的依赖这些support libraries。

组件库 Component Libraries

除了兼容库compatibility librariesAndroid Support Library 还提供了一些更小的更模块化的组件库Component Libraries来帮助开发者实现某些Android框架本身并不提供的功能。因为这些轻量级Library互相之间不存在依赖关系,所以开发者们可以很轻松的将它们的添加进或删除出自己的工程,而不必担心产生什么不良影响。下面举出的是一些极有价值的组件库:

v7-recyclerview:支持 RecyclerView 组件,这一被设计来代替ListView的组件可以有效地展示或以动画形式表现大批数据。

v7-cardview: 支持 CardView 组件,使得cards UI设计模式得以实现。

v7-gridlayout: 支持 GridLayout 类,使开发者们可以将界面元素整合进一个Grid。

v7-mediarouter: 支持MediaRouter及相关类,让开发者可以使用Google的媒体路由服务。

v7-palette: 支持Palette类,开发者可以通过它来突出图片中的颜色效果。

在基于gradle的安卓项目中添加以上的任何一个组件库对你来说都是易如反掌的。

这些组件库将功能模块化并给开发者提供了相当大的便利,而且还让谷歌可以再不改动Android框架的前提下提供新的API。这些新的API在被最终加入Android框架之前将被开发者们不断的使用和测试,这些实际使用的信息会被谷歌收集并加以利用。所以对这些新的API的修正将在庞大和复杂的Android框架之外进行,而不是之内,感谢上帝。

其他库 Other Libraries

Android Support Library 里还有一些并不常用但却依然很价值的库:

v8:API 11 引入的RenderScript提供给API 8

v13:v4库中的Fragment UI 提供额外的兼容支持。

v17: 支持电视界面开发。

multidex: 当你的一个Dex文件里包含太多函数时会用的上它。

annotations: 支持注释功能,比如@NonNull@IntDef

常见问题 Common Questions

我什么时候用这些Android Support Library?

当你开发的应用所面向的最低版本Sdk(minSdkVersion)并不提供你所使用的现有功能时,或是Android基础框架并未提供此功能,而你仅能从Support Library中获取支持时,你就该使用Android Support Library了。

当然,按照谷歌的说法,你不必在意这些细节,只要Android Support Library里有你要的东西,你尽量去用就好了。

我该使用哪个版本的Android Support Library?

简单来说,哪个用得上就用哪个。对于把功能模块化的组件库来说,该用哪个就用哪个。比如当你想使用RecyclerView时,把 v7-recyclerview 导进工程就好。

由于v13库捆绑了v4库,所以只要你的应用面向的最低版本Sdk(minSdkVersion)支持v13库,那么你就可以使用v13来代替 v4。当然,如果想支持低于API 13的Android系统,你还是得使用v4

值得注意的是。各种包之间的相互依赖关系会指明哪些库会被用到。

结论 Conclusion

为了让Android在谷歌的标准下保持成功,它还需要不断成长。为了实现这一目标,它的其中一个主要任务就是扩大它所支持的设备种类。而这些品种繁多的设备中的相当一部分是永远也不会更新到最新版本的Android系统的。

尽管看起来并不总是那么优雅,也并不总是那么便利,Android Support Library还是成功的担负起了它的责任。应用开发者们在它的帮助下得以在陈旧的系统版本上使用新的特性和功能,或在Android基础框架外使用新的API。它是Android开发当中重要的一部分,我们作为应用开发者们有义务去理解并使用它。

 类似资料: