一般Android新系统发布会有一些变更,例如限制某个api的访问,但是为了适配市面上绝大多数app,很多时候app的targetSdkVersion只要不变更,不受该变更影响。
那么问题来了,对于同一台设备安装不同的targetSdkVersion的app,访问某个API的行为不一致,系统是如何做到的?
更多问答 >>
-
每日一问 | Java线程栈的栈溢出(StackOverflowError)是如何检测的?
2024-02-19 18:30 -
2024-06-17 09:16
-
2024-06-06 11:06
-
2023-10-25 00:22
-
每日一问 | Android 模块化依赖中的资源冲突该如何规避?
2023-05-24 17:30 -
每日一问 | Android 默认开启硬件加速与设置hardwareAccelerated是一回事吗?
2023-05-24 17:30 -
每日一问 | 瘦身属性?对android:extractNativeLibs属性的探讨
2022-12-07 14:43 -
每日一问 | App在运行状态,可以动态安装apk,并且不重新启动吗?
2022-11-20 12:46 -
2022-11-08 21:50
我试着回答一下,如果有问题,请指正。
按照我们软件的开发传统,随着新版本的发布,必然会兼容老版本的,不能因为新版本的发布导致老版本不可用。基于这个原则咱们回到Android系统,Android系统也是一个软件系统,自然脱离不了这个原则。随着Android新版本的发布,系统api会有一些变更,官网上会有相应的行为变更说明,方便开发者进行适配,扯的有点远了了,回到问题中 targetSdkVersion,Android系统是通过运行时检查app的targetSdkVersion来决定是否允许某个API调用的当一个app调用一个Android API时,系统会先检查app的targetSdkVersion。如果调用的API在app目标平台版本中已经存在,那么系统会按目标平台版本的规则处理该调用。如果调用的API在app目标平台版本中不存在,系统会按最新平台版本的规则处理该调用。举个例子:假设系统最新版本是Android 10,它限制了某个API的访问。App A的targetSdkVersion 是28(Android 9),在它的目标平台上,那个API是允许访问的。那么App A调用那个API时,系统会按Android 9的规则允许其调用。App B的targetSdkVersion 是29(Android 10),在它的目标平台上,那个API是不允许访问的。那么App B调用那个API时,系统会按Android 10的规则拒绝其调用。所以同一台设备上,App A可以调用那个API,App B无法调用那个API,就是因为系统会根据每个app的targetSdkVersion来判断该如何处理对某个API的调用。这种机制可以很好地兼顾新老版本的兼容,旧app可以继续按旧规则运行,新app会自动采用新规则。开发者只需要在适当时候更新一下app的targetSdkVersion,就可以让app采用最新的系统功能和限制策略新人新办法,老人老办法?
targetSdk最初的想法确实是这样的,但是随着更新的越发频繁,对targetSdk的容忍度越来越低了。逐渐要求开发者适配更高的targetSdk,淘汰没有适配的apk。 ...查看更多
targetSdk最初的想法确实是这样的,但是随着更新的越发频繁,对targetSdk的容忍度越来越低了。逐渐要求开发者适配更高的targetSdk,淘汰没有适配的apk。
向后兼容和向前兼容的概念
向后兼容(Backwards compatibility):较高版本的程序能够处理较低版本程序产生的数据。
比如word2007版本的word软件可以打开word2003创建的文件。
windows也是一个系统软件,在这个平台上开发的程序,就相当于是程序产生的数据,比如说window7上可以正常运行在window xp上开发的大部分程序。向前兼容(Forwards Compatibility):比较老、比较低的版本的程序可以处理较高版本程序产生的数据。例如 word 2003版本可以在转换器的帮助下打开word2007版本创建的doc文档。
相对性的关系
backward和forward,可以大致理解成新和旧。而新旧是相对的,一个旧软件不能跑在新硬件上,既可以说是这个软件不向前兼容硬件,也可以说是这个硬件不向后兼容软件。
再如软件和协议的兼容,新软件不兼容旧协议,既可说是软件不向后兼容协议,也可以说协议不向前兼容软件。 所以搞清楚是什么对什么的兼容性,谁在前面,谁在后面,就能区分向前向后了。所以碰到兼容性的概念的问题时,是可以从新旧两个方向去考虑。Android 中的兼容性
Android的系统版本(比如 8.0、7.0、6.0、5.0、4.x等)与运行在其上的App就存在相对的关系。下面是针对App而言的兼容性
向后兼容:
比如很多app是支持到比较低的版本:2.3,4.x等,可以运行在低于targetSdk的系统上。这个是通过在开发中设置minSdk ,supportlibray,运行时版本的判断等来实现的。app具有了向后兼容的性质,也可以说Android系统具有了向前兼容性。
android 向后兼容很多情况是通过支持库(support library)来实现的。比如appcompat-v4、appcompat-v7使得低版本手机可以支持Material Design。
支持库的原理是这样的,如果应用调用其中一个支持类的方法,则支持库的行为将取决于运行应用的 Android 版本。如果框架提供必要的功能,则支持库将通过调用框架执行任务。如果应用在旧版本的 Android 上运行,且框架未显示所需的功能,则支持库自身可能会尝试提供功能或什么都不做。无论是哪一种情形,应用通常都不需要检查其在哪一版本的 Android 上运行,而是通过支持库执行检查并选择适当的行为。通常情况下,名称以 …Compat(如 ActivityCompat)结束的类即是如此。
对app 的向前兼容
比如说应用商店的很多app,targetSdk是低于android7.0,但是还是可以正常安装到android 7.0的设备上,似乎是app自动具有了向前兼容性,而系统具有向后兼容性。
targetSdkVersion的作用
那这就要说targetSdk这个参数的作用了,如果实际运行的android版本号高于targetSdkVersion,那么手机会按照targetSdkVersion设置的版本号来运行。当实际android版本号不高于targetSdkVersion时按照实际的手机版本号运行apk。
比如说在新版上android N删除了一些方法或者更改了一些方法的签名,App的targetSdkVersion 是android M,那么在运行到android N上也不会报出错误,因为是采用targetSdkversion的版本来跑的,这样调用的方法也是没有变化的,还是采用的Android M中的代码。那这个就带来一个问题,是Android系统需要做更多的兼容性代码,系统会越来越膨胀。
这个作用机制还有一层含义是: 如果targetversion 低于android N,那么也不可以采用android N新的方法和特性。