Android 未考虑TargetApi
在我们的一种方法中,我们在列表视图中使用平滑滚动。由于此方法在API级别8(FROYO)之前不可用,因此我们使用TargetApi注释来防止在以前的SDK版本中调用此方法 如您所见,我们在类定义和使用类对象的语句中都使用了TargetApi注释。这超出了需要 我们的问题是没有考虑TargetApi注释,这使得我们的emulator在版本ECLAIR(SDK 7)中崩溃。通过跟踪,我们才意识到应该只在版本8+中执行的代码也在版本7中执行 我们错过什么了吗 此代码位于侦听器中:Android 未考虑TargetApi,android,annotations,emulation,Android,Annotations,Emulation,在我们的一种方法中,我们在列表视图中使用平滑滚动。由于此方法在API级别8(FROYO)之前不可用,因此我们使用TargetApi注释来防止在以前的SDK版本中调用此方法 如您所见,我们在类定义和使用类对象的语句中都使用了TargetApi注释。这超出了需要 我们的问题是没有考虑TargetApi注释,这使得我们的emulator在版本ECLAIR(SDK 7)中崩溃。通过跟踪,我们才意识到应该只在版本8+中执行的代码也在版本7中执行 我们错过什么了吗 此代码位于侦听器中: @TargetApi
@TargetApi(8)
private final class MyOnMenuExpandListener implements OnMenuExpandListener {
@Override
public void onMenuExpanded( int position ) {
doScrollIfNeeded( position );
}
@Override
public void onMenuCollapsed( int position ) {
doScrollIfNeeded( position );
}
protected void doScrollIfNeeded( int position ) {
if ( mListViewDocuments.getLastVisiblePosition() - 2 < position ) {
mListViewDocuments.smoothScrollToPosition( position + 1 );
}
}
}
顺便说一句,我们在调试模式下运行代码,因此问题与消除注释的混淆无关。
@TargetApi
不会阻止任何代码运行,它仅用于注释代码和防止新API的编译器错误,一旦您知道您只是有条件地调用它们
您仍然需要添加一些与
if (Build.VERSION.SDK_INT > 7){
//...
}
经过将近一年的思考,我想补充一下@Guykun的答案: @TargetApi只会被工具用来告诉开发者“嘿,不要在XXX android SDK下面使用这个方法”。通常是皮棉 因此,如果您设计的方法如下:
if (Build.VERSION.SDK_INT > 7){
//...
}
然后您应该将@TargetApi(7)添加到方法的签名中
但是,如果您添加一个else语句,并提供一个替代方案,使其适用于所有Android版本,如:
if (Build.VERSION.SDK_INT > 7){
//...
} else {
//...
}
然后您应该而不是将@TargetApi(7)添加到方法的签名中。否则,其他开发人员会认为他们不能使用api级别7的方法,但事实上,它也适用于他们
因此,对于静态分析,必须使用此注释来指示该方法支持的最低api级别。例如:
@TargetApi( 7 )
public void foo() {
if (Build.VERSION.SDK_INT > 7){
//...
else if (Build.VERSION.SDK_INT > 10){
//...
}
}
更好的是,使用android.Build.VERSION\u code.*中定义的常量
顺便说一句,您可能已经注意到,这对于私有方法来说确实是无用的,除非获得更干净的代码并帮助将来将该方法推广到公共方法。要在使用针对更高Api级别的方法时强制执行lint错误,您可以使用而不是,并且只要您尝试使用该方法而不检查版本代码,您将得到编译错误 这就是《圣经》所说的 这在用途上与旧的@TargetApi注释类似,但是 更明确地表示这是对调用方的要求, 而不是用于在 超过标准版本
它所做的只是删除lint错误。真的吗?!似乎是这样。但是,使用不同的系统而不是像我们通常所做的那样使用@SuppressWarnings来避免lint错误似乎真的很奇怪。事实上,这只是另一种注释形式,编程方法允许对运行的内容进行精细控制。不仅是@TargetApi redundent,但是仍然没有办法正确地注释您给出的示例:两个注释都不能附加到有问题的行,因此它们必须附加到整个函数(或者if语句中的代码必须转换为fn)。谷歌为什么要添加@TargetApi?顺便说一句,你可以编写
@TargetApi(Build.VERSION\u CODES.FROYO)
而不是@TargetApi(8)
。你是对的。为此,你的targetSDK必须尽可能高。这是对@Tom问题的回答。我想你也一样,但这里有一段从Android Studio的LoginActivity向导生成的代码摘录:@TargetApi(Build.VERSION\u CODES.HONEYCOMB\MR2)private void showProgress(final boolean show){if(Build.VERSION.SDK_INT>=Build.VERSION_code.HONEYCOMB_MR2){/..}否则{/..}
@TargetApi( 7 )
public void foo() {
if (Build.VERSION.SDK_INT > 7){
//...
else if (Build.VERSION.SDK_INT > 10){
//...
}
}