working warning studio oreo notification not for failed example developer channel_id android annotations emulation

android - warning - TargetApi no se tiene en cuenta



failed to post notification on channel android (3)

En uno de nuestros métodos, usamos smoothScrolling en una vista de lista. Como este método no está disponible antes del nivel de API 8 (FROYO), usamos la anotación TargetApi para evitar que se llame al método en versiones anteriores del SDK.

Como puede ver, usamos la anotación TargetApi tanto en la definición de clase como en las declaraciones que usan los objetos de la clase. Esto es más de lo necesario.

Nuestro problema es que la anotación de TargetApi no se tiene en cuenta y hace que nuestro emulador se bloquee en la versión ECLAIR (SDK 7). Al rastrear, nos damos cuenta de que el código que solo debería ejecutarse en las versiones 8+ también se ejecuta en la versión 7.

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

Por cierto, ejecutamos el código en modo de depuración, por lo que el problema no está relacionado con la ofuscación que elimina las anotaciones.


Con casi un año pensando más en esto, me gustaría agregar 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 a continuación del XXX SDK de Android". Típicamente la pelusa.

Entonces, si diseñas 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 pensarán que no pueden usar su método belw api nivel 7, pero de hecho, también funcionaría para ellos.

Por lo tanto, esta anotación debe usarse, 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, use las constantes definidas en android.Build.VERSION_CODES.* .

Por cierto, habrías notado que esto es inútil para los métodos privados, excepto para obtener un código más limpio y ayudar a promover el método público en el futuro.


Para imponer un error de pelusa cuando se usa un método dirigido a un nivel de Api más alto, puede usar RequiresApi lugar de TargetApi y cada vez que intente usar el método sin verificar el código de la versión, obtendrá un error de compilación.

Esto es lo RequiresApi dice la RequiresApi sobre RequiresApi

Su propósito es similar al de la antigua anotación @TargetApi, pero expresa más claramente que este es un requisito para el llamante, en lugar de ser usado para "suprimir" las advertencias dentro del método que exceden la minSdkVersion.


@TargetApi no evita que se ejecute ningún código, es solo para anotar el código y evitar errores de compilación para nuevas API una vez que sepa que solo los está llamando condicionalmente.

Aún necesita agregar algo a lo largo de las líneas de

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