在我们的一个方法中,我们在列表视图中使用smoothScrolling。由于此方法在API Level 8(FROYO)之前不可用,因此我们使用TargetApi注释来阻止在以前的SDK版本中调用该方法。
正如您所看到的,我们做在类定义和使用类对象的语句中都使用TargetApi注释。这不仅仅是需要的。
我们的问题是没有考虑TargetApi注释并使我们的模拟器在版本ECLAIR(SDK 7)中崩溃。通过跟踪,我们只是意识到应该只在版本8+中执行的代码也在版本7中执行。
我们错过了什么吗?
此代码位于监听器中:
@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(8)
private void allowSmothScrollIfSupported() {
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO ) {
//This if should not be necessary with annotation but it is not taken into account by emulator
Log.d( LOG_TAG, "Smooth scroll support installed." );
folderContentAdapter.setOnMenuExpandListener( new MyOnMenuExpandListener() );
}
}
顺便说一句,我们在调试模式下运行代码,因此问题与模糊删除注释无关。
答案 0 :(得分:51)
@TargetApi
不会阻止任何代码运行,它只是用于注释代码并在您知道只是有条件地调用它们时阻止新API的编译器错误。
你还需要添加一些
的内容if (Build.VERSION.SDK_INT > 7){
//...
}
答案 1 :(得分:5)
经过近一年的思考,我想在@Guykun的回答中添加一些补充:
@TargetApi只会被工具用来说开发者&#34;嘿,不要在XXX android SDK&#34;下面使用这个方法。通常是lint。
所以,如果你设计一个像:
这样的方法if (Build.VERSION.SDK_INT > 7){
//...
}
然后你应该将@TargetApi(7)添加到你方法的签名中。
但是,如果你添加一个else语句,并提供一个替代方案,使其适用于所有Android版本,如:
if (Build.VERSION.SDK_INT > 7){
//...
} else {
//...
}
然后你应该 不 将@TargetApi(7)添加到你方法的签名中。否则,其他开发人员会认为他们不能使用你的方法belw api level 7,但实际上,它也适用于他们。
因此,对于静态分析,必须使用此注释来指示方法支持的最小api级别。如:
@TargetApi( 7 )
public void foo() {
if (Build.VERSION.SDK_INT > 7){
//...
else if (Build.VERSION.SDK_INT > 10){
//...
}
}
甚至更好,使用android.Build.VERSION_CODES.*
中定义的常量。
答案 2 :(得分:1)
要在使用针对更高Api级别的方法时强制执行lint错误,您可以使用RequiresApi
代替TargetApi
,并且无论何时尝试使用该方法而不检查版本代码,您都可以我会得到编译错误。
这与旧的@TargetApi注释类似,但是 更清楚地表明这是调用者的要求, 而不是习惯于在方法中“抑制”警告 超过minSdkVersion。