Android支持库是如何工作的?

39
据我所知,支持库是因为旧设备没有新的API而使用的。例如,它们不知道什么是Fragment以及如何实现它。因此,这些行为在支持库中被定义。
所以,我的主要问题是:Fragment库在支持库中和在API 11(Android v3.0,蜂巢)引入的Fragment库之间有什么区别?
我的第二个问题是,如果可能把所有新的API都放在支持库中,为什么我们有两种类型的库?我的意思是,Android可以将所有API都发布在支持库下,而不是支持库和Android版本X.xx库。
6个回答

43
据我所了解,支持库可以作为内置API的替代品使用,但它们不应该被视为内置API,因为它们直接影响应用程序的大小。
例如,一个支持库的大小为2MB,为了使用它的功能,需要加载所有类、资源等(总共2MB)。现在我的应用程序的classes.dex(应用程序中所有类的Dalvik可执行文件)也包括该支持库的类,资源也是如此。因此,如果没有支持库,我的应用程序大小为1MB,现在加上支持库后,额外增加了2MB,总大小为3MB。
现在假设这个支持库功能非常常见,在单个设备上,如果我有10个应用程序,那么至少有9个应用程序都在使用这个相同的支持库,所以我的设备上有9* 2 = 18MB 的空间被相同的支持库占用,在每个应用程序中重复出现,这很糟糕,因为目前18MB可能还不算太多,但如果您有更多应用程序使用该支持库,则所需空间可能会增加。
因此,最好的选择是已经在操作系统中拥有该2MB支持库,供任何数量的应用程序使用,而不是为每个应用程序都添加一次。因此,当您真正想要在应用程序中支持旧版本的某些有效功能时,才需要使用支持库。
另一个问题是:为什么不将这个支持库作为自己的更新添加到操作系统中,以便所有没有空间问题的应用程序都可以访问该功能呢?
答案是会有很多错误。假设某个用户没有安装这个更新(支持库)...此外,它作为更新可能效率不如预期,或者在与操作系统集成时可能会出现问题,就像我们已经看到的每个操作系统(Windows、Linux、Mac)都带有新版本,而不是给出所有新功能的终身更新。

4
如果开发者不需要支持库提供的任何功能,那么可以不使用它。但是,在整个应用的构架中,2MB实际上并不算太大,与其因为担心APK文件过大而将应用简化到只有基础功能,我更愿意选择一个功能良好且向后兼容的应用程序。此外,你还可以使用Proguard来缩减/压缩应用程序的APK文件大小。 - Alex Lockwood
我不同意你的回答,认为用户没有支持库可能会导致许多错误。清单文件已经允许您仅限制应用程序在具有特定OpenGL版本的设备上运行。他们本可以对支持库做同样的事情,甚至可以扩展功能以允许对任何库进行动态依赖。这就是目前大多数基于Linux的操作系统所采用的方式。 - Jeroen

13

Android 4.0.x (ICS)相比于Android 2.3.x(Gingerbread)增加了许多功能。兼容性库的作用是为了弥补ICS中添加的一些更改,这些更改可能被Gingerbread支持。“可能”是关键词,因为对ICS进行了大量更改,其中很多更改不适用于Gingerbread,当然也不会有兼容性库。

例如,您提到的片段在ICS中与兼容性库中略有不同,因为ICS可以使用更多功能。如果您查看ICS的代码中的片段类,则与兼容性库中的不同。这是一整套代码,使ICS中的“类似”片段可以在旧版本(如Gingerbread)中使用,而程序员几乎看不到任何差异。

这就是兼容性库的目的,也是为什么它们不会广泛地修补Gingerbread以使用ICS中的所有功能(它们无法做到)。兼容性库的重点是将新版本Android(如ICS)可用的内容和方式接口化,以便将其用于较旧的版本,如GB,以GB的方式完成。

至于为什么他们不保持支持库增长并保留相同的基本操作系统 - 这是兼容性问题的答案。如果用户只有v4,而v12已经发布,会发生什么?Android现在使用操作系统的Android API版本作为应用程序兼容性的基础,并且开发人员可以选择包含支持库(增加其应用程序的文件大小,但提供新功能)。每个使用支持库的应用程序都单独包含它们(意味着4个应用程序= 4倍的包含量)。

这个想法是,您只能下载受当前操作系统API版本支持的应用程序(就谷歌Play而言),并且您可以选择包括支持库,以便为不具备您选择对这些用户可用的新API特性的旧API提供支持。这实际上只是一个外观和感觉的考虑,而不是其他方面的任何东西。

希望这解决了疑问 :)


所以支持库已经包含在操作系统中了,对吗? - Clocker
1
并非如此。新版本的操作系统具有一些功能,您可以在没有支持库的情况下实现这些功能,但如果您想让旧手机起作用,则必须手动添加支持库并使用其中的类(它们只是.jar文件,您将其添加到构建路径中)。如果您的目标最小API版本较低,则ADT现在会自动将支持库添加到您的项目中,因此您仍然可以获得这些高级功能,但它们会使您的项目占用更多空间。有时,将目标定为更高的API会更好,以便使用本机代码,但这取决于您和您能够放弃哪些兼容性。 - CompEng88

8
已经说过的是正确的。虽然有些细节缺失。事实上,我有机会参加了最后一次Google IO的一个专门讨论这个问题的会议。令我惊讶的是,支持库并不托管所有可能的API版本的代码,而是新功能的适应,他们认为这些功能足够重要,可以使它们在旧平台上可用。所以它的工作方式通常如下:
- 假设我们需要使用全新的(从API 16可用)ConnectivityManager来跟踪网络变化 - 我们包括支持库v4并使用该类 - 之后的工作方式是,系统将检查我们的API版本,并在我们处于API 16时运行内置本地代码,在任何其他情况下运行支持库的代码。
所以它就像某种路由网关。原因是通常使用最后一个针对最后一个操作系统和最后一个系统改进的优化代码更有效率(和执行)。
尽管如此,仍有一些元素没有转换为兼容库,因为它们在本地内置代码中。例如,片段不应该被重新编写为API13以来它们是一个需要在系统和设备的广泛范围内运行的巨大组件,而这些设备具有较少的功能。
最终,由于所有这些,建议使用兼容库,这被认为是一种良好的实践,特别是如果您打算使您的应用程序/代码可用于旧版本(这应该是理想的方式)。

1
请提供有关此会话的更多信息。是否有在线视频或脚本? - OneWorld
很抱歉,我记不得具体的会话了,但这里是来自IO'12的所有视频。https://developers.google.com/events/io/2012/ 希望能有所帮助。 - Jose L Ugia

3

支持库实际上并没有包含所有新的API。它确实支持Fragment API的部分内容,但尚不支持ActionBar。为此,您需要另一个类似于ActionBar Sherlock的库。

为什么会有两个库?

这是因为问题的一部分是Google只回溯了其中一些内容,但我的理解是,由于Android UI框架核心中存在限制和缺失API,一些新功能无法进行回溯。


1

Android在最近的版本中推出了碎片和操作栏的很酷的功能。

现在,如果我们想要使用这些功能并支持旧版Android,则必须编写高度混乱的版本相关代码,这是不好的。

为了使我们免受所有这些混乱的困扰,Android推出了支持库,该库虽然不提供新功能的完全支持,但足以让开发人员编写整洁的代码,并支持所有设备。

回答你的第二个问题非常简单,碎片是v3.0的集成部分,如果你希望你的应用程序仅在v3.0+上运行,那么你真的不需要包含外部库。


-3

Support库中的片段相当于Honeycomb+的片段。

根据文档的第二个问题:

v13是v4的超集,包括额外的支持类来处理v13 API

即相同的功能,只是适应于v13 API。

我使用修改后的v4支持库 - 带有地图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接