TargetApi no se tiene en cuenta
En uno de nuestros métodos, usamos smoothScrolling en una vista de lista. Dado que este método no está disponible antes de API Level 8 (FROYO), utilizamos la anotación TargetApi para evitar que el método se llame en versiones anteriores de SDK.
Como puede ver, usamos la anotación de TargetApi tanto en la definición de clase como en sentencias que usan los objetos de la clase. Esto es más de lo necesario.
- Coreógrafo (639): Omitido 50 cuadros
- Android Studio y Visual Studio Emulator para Android depuración
- Cómo instalar Android Market en el emulador para todos los api
- Varios emuladores de Android
- Sensores en el emulador de Android?
Nuestro problema es que la anotación TargetApi no se tiene en cuenta y hacer que nuestro emulador se bloquee en la versión ECLAIR (SDK 7). Al rastrear, sólo nos damos cuenta de que el código que sólo se debe ejecutar en las versiones 8+ también se ejecuta en la versión 7.
¿Estamos perdiendo algo?
Este código está en un oyente:
@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 ); } } }
Y el oyente se registra de esta manera:
@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, ejecutar el código en el modo de depuración, por lo que el problema no está relacionado con la obfuscación quitar las anotaciones.
Thx por adelantado!
- Detectar cuándo se arranca completamente el emulador de Android
- Cómo sacudir el dispositivo virtual creado por Genymotion (Android Emulator)
- Emulador de Genymotion sin conexión a Internet
- Android se niega a escribir / crear archivos de preferencias compartidas
- ¿Cómo puedo ver la información de mi base de datos de aplicaciones de Android?
- Tamaño de fuente pequeño en el emulador de Android
- Configuración de varios emuladores en Android Eclipse
- ¿Cómo puedo tomar una instantánea del estado del emulador de Android?
@TargetApi
no impide que se ejecute ningún código, es sólo para anotar el código y evitar errores de compilador para las nuevas API una vez que sepa que sólo las llaman condicionalmente.
Aún es necesario agregar algo a lo largo de las líneas de
if (Build.VERSION.SDK_INT > 7){ //... }
Con casi un año de pensar más en esto, quisiera añadir un pequeño complemento a la respuesta de @Guykun:
El @TargetApi solo será utilizado por las herramientas para decir a los desarrolladores "Oye, no uses este método debajo de XXX android SDK". Normalmente pelusa.
Por lo tanto, si diseña un método como:
if (Build.VERSION.SDK_INT > 7){ //... }
Entonces debe agregar @TargetApi (7) a la firma de su método.
PERO , si agrega una declaración else y proporciona una alternativa que hace que funcione para todas las versiones de Android como:
if (Build.VERSION.SDK_INT > 7){ //... } else { //... }
Entonces no debe agregar @TargetApi (7) a la firma de su método. De lo contrario, otros desarrolladores piensan que no pueden usar su método de api nivel 7, pero de hecho, que funcionaría para ellos también.
Así que esta anotación tiene que ser utilizada, para el análisis estático, para indicar el nivel mínimo de api soportado por el método. Como en :
@TargetApi( 7 ) public void foo() { if (Build.VERSION.SDK_INT > 7){ //... else if (Build.VERSION.SDK_INT > 10){ //... } }
Y aún mejor, utilizar constantes definidas en android.Build.VERSION_CODES.*
.
BTW, usted habría notado que esto es inútil para los métodos privados de hecho, excepto para obtener un código más limpio y ayudar a promover el método público en el futuro.
Para reforzar el error de pelusas cuando se utiliza un método orientado hacia un nivel de Api superior, puede utilizar RequiresApi
lugar de TargetApi
y siempre que intente utilizar el método sin comprobar el código de versión, obtendrá error de compilación.
Esto es lo que dice la documentación sobre RequiresApi
Esto es similar en propósito a la anotación más antigua de @TargetApi, pero expresa más claramente que esto es un requisito en la persona que llama, en lugar de ser utilizado para "suprimir" las advertencias dentro del método que exceden a la minSdkVersion.
- Android Asyntask: Usar referencia débil para el contexto para evitar la rotación del dispositivo de pantalla
- DialogFragment: Utilizar AlertDialog con diseño personalizado