当代码需要某个 API 级别时,为啥 Build.Version 的检查必须是相同的要求,而不是达到或高于要求的级别?
Posted
技术标签:
【中文标题】当代码需要某个 API 级别时,为啥 Build.Version 的检查必须是相同的要求,而不是达到或高于要求的级别?【英文标题】:When code requires an certain API level, why must the check for Build.Version be the same required rather than at or above the required level?当代码需要某个 API 级别时,为什么 Build.Version 的检查必须是相同的要求,而不是达到或高于要求的级别? 【发布时间】:2014-11-29 10:19:03 【问题描述】:我在观看关于属性动画的 android 开发者视频 (https://www.youtube.com/watch?v=3UbJhmkeSig) 时遇到了一个很容易解决但我很难理解的问题,并希望有人能帮我解释一下。..
我有一个项目在清单中以 API 级别 8 为目标,因此当我使用下面的代码时,我收到一条错误消息,指出所使用的代码需要比当前目标 API 级别更高的 API 级别。作为一种解决方法,我在运行时检查了构建版本 (http://developer.android.com/training/basics/supporting-devices/platforms.html),并且仅在 API 级别足够时才运行代码段。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
ObjectAnimator rotateAnimation = ObjectAnimator.ofFloat(resp1, View.ROTATION, 270);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
rotateAnimation.setRepeatCount(0);
当我添加第一个最外层的 if 语句时,我产生了困惑。代码行
ObjectAnimator rotateAnimation = ObjectAnimator.ofFloat(resp1, View.ROTATION, 270);
需要 API 级别 14,因此我检查 Build.Version.ICS 的原因。但是,代码行中的“setRepeatCout()”方法
rotateAnimation.setRepeatCount(0);
需要 API 11,虽然放在第一个最外面的 if 语句中,用括号确保一个块而不是一行,但我的 IDE (IntelliJ IDEA) 仍然向我显示错误,指出代码行需要 API 11 和我的项目针对 API 8。我的两个解决方案是将代码放入两个嵌套的 if 语句中,一个检查 API 14,另一个检查 API 11,或者使用
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
方法开头的注解。但是,我不完全理解关于它如何影响旧设备的注释,也不理解为什么我需要两个 if 语句来检查构建版本。
-@TargetAPI 是简单地摆脱 lint 检查还是以某种方式影响整个方法以及它是否编译/运行?
-为什么我需要使用两个 if 语句?为什么第一条 if 语句不能满足两行代码?
-是否有理由需要同时使用两个 if 语句来检查构建,或者这可能是一个错误?我尝试在https://youtrack.jetbrains.com/issues/IDEA 搜索已知错误并在谷歌上搜索结果。
非常感谢
【问题讨论】:
【参考方案1】:
@TargetAPI
是简单地摆脱 lint 检查还是以某种方式影响整个方法以及它是否编译/运行?
它向 Lint 表明,对于注解(方法或类)的范围,Lint 应该将 minSdkVersion
视为注解中提供的值(例如,HONEYCOMB
),而不是您拥有的任何值在您的清单或build.gradle
文件中指定。
当您作为开发人员验证您正在针对指定的 API 级别正确处理向后兼容性时,您可以申请 @TargetApi
。然后,在未来的某个时间,如果您向高于此 API 级别的类或方法添加更多代码,Lint 应该再次对您大喊大叫,因此您意识到您需要添加更多向后兼容性检查。
在这种情况下,正确的解决方案是 @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
,因为您的代码设置为处理从当前 minSdkVersion
到 API 级别 14 的向后兼容性,但不会更高(因为您没有使用任何有问题的更高)。
为什么我需要使用两个 if 语句?为什么第一个 if 语句不足以满足两行代码?
可能是因为您为 @TargetApi
注释选择了 HONEYCOMB
。如果我们在运行 API 级别 14 或更高级别的设备上,我们在定义上运行 API 级别 11 或更高级别的设备上。你不需要内部的if
检查。
是否有理由需要在两个位置检查构建,或者这可能是一个错误?
我不知道您认为“两个位置”是什么。你需要@TargetApi
注解和外部if
检查吗?是的。你需要两个if
支票吗?不会。而且,如果您将 @TargetApi
设置为 ICE_CREAM_SANDWICH
,删除内部的 if
检查并收到 Lint 投诉,这可能是 Android 插件中的错误。
【讨论】:
在使用两个 if 语句时,我没有使用 targetapi 注释。我会使用最外层的 if 语句和 targetAPI 注释或两个 if 语句,但不会同时使用两个 if 语句和注释。我假设外部 if 语句将适用于 if 块内的所有内容..?抱歉,“两个位置”是指两个 if 语句,而不是 if 语句和注释。 @cjayem13:“我假设外部 if 语句将适用于 if 块内的所有内容..?” -- 确实如此。 好的,很好。至少我不会发疯,哈哈。如果一个代码段需要 api 11 而另一个代码段需要 api 14,我想这一定是某种错误,检查 api 14 或更高版本应该对两者都足够了。在验证用户使用 api 14 后我必须检查 api 11 的事实对我来说绝对是荒谬的.. idk,我想我会向 Intellij 报告错误,看看会发生什么.. 感谢您的帮助以上是关于当代码需要某个 API 级别时,为啥 Build.Version 的检查必须是相同的要求,而不是达到或高于要求的级别?的主要内容,如果未能解决你的问题,请参考以下文章
在下面的代码中,当点击按钮时,为啥不能调用[print("BBB's build function.")]?