Snicolas Snicolas - 1 month ago 9
Android Question

TargetApi not taken into account

in one of our methods, we use smoothScrolling in a list view. As this method is not available before API Level 8 (FROYO), we used the TargetApi annotation to prevent the method from being called in previous SDK versions.

As you can see, we do use TargetApi annotation both in class definition and in statements that use the objects of the class. This is more than needed.

Our problem is that the TargetApi annotation is not taken into account and make our emulator crash in version ECLAIR (SDK 7). By tracing, we just realize that the code that should only be executed in versions 8+ is also executed in version 7.

Are we missing something ??

This code is in a listener :

@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 );
}
}
}


And the listener is registered this way :

@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() );
}
}


BTW, we run the code in debug mode, so the issue is not related to obfuscation removing annotations.

Thx in advance !

Answer

@TargetApi does not prevent any code from being run, it is merely for annotating code and preventing compiler errors for new APIs once you know you are only conditionally calling them.

You still need to add something along the lines of

if (Build.VERSION.SDK_INT > 7){
    //...
}