Versión mínima del SDK de Android frente a la versión del SDK de destino

Resuelto Michael Novello asked hace 54 años • 9 respuestas

Cuando se trata de desarrollar aplicaciones para Android, ¿cuál es la diferencia entre la versión Min y Target SDK? ¡Eclipse no me permitirá crear un nuevo proyecto a menos que las versiones Min y Target sean las mismas!

Michael Novello avatar Jan 01 '70 08:01 Michael Novello
Aceptado

¡El comentario publicado por el OP a la pregunta (básicamente indica que targetSDK no afecta la compilación de una aplicación) es completamente incorrecto! Perdón por ser franco.

En resumen, este es el propósito de declarar un targetSDK diferente del minSDK: significa que está utilizando funciones de un SDK de nivel superior al mínimo, pero ha garantizado la compatibilidad con versiones anteriores . En otras palabras, imagine que desea utilizar una característica que se introdujo recientemente, pero que no es crítica para su aplicación. Luego, configuraría el targetSDK en la versión en la que se introdujo esta nueva característica y el mínimo en algo inferior para que todos puedan seguir usando su aplicación.

Para dar un ejemplo, digamos que estás escribiendo una aplicación que hace un uso extensivo de la detección de gestos. Sin embargo, cada comando que se puede reconocer mediante un gesto también se puede realizar mediante un botón o desde el menú. En este caso, los gestos son un "extra interesante" pero no son necesarios. Por lo tanto, establecería el SDK de destino en 7 ("Eclair" cuando se introdujo la biblioteca GestureDetection) y el SDK mínimo en el nivel 3 ("Cupcake") para que incluso las personas con teléfonos muy antiguos puedan usar su aplicación. Todo lo que tendrías que hacer es asegurarte de que tu aplicación verificó la versión de Android en la que se estaba ejecutando antes de intentar usar la biblioteca de gestos, para evitar intentar usarla si no existiera. (Es cierto que este es un ejemplo anticuado ya que casi nadie todavía tiene un teléfono con la versión 1.5, pero hubo un momento en que mantener la compatibilidad con la versión 1.5 era realmente importante).

Para dar otro ejemplo, podría usar esto si quisiera utilizar una función de Gingerbread o Honeycomb. Algunas personas recibirán las actualizaciones pronto, pero muchas otras, especialmente con hardware antiguo, podrían quedarse con Eclair hasta que compren un nuevo dispositivo. Esto le permitiría utilizar algunas de las nuevas funciones interesantes, pero sin excluir parte de su posible mercado.

Hay un artículo realmente bueno en el blog del desarrollador de Android sobre cómo usar esta función y, en particular, cómo diseñar el código "verificar que la función existe antes de usarla" que mencioné anteriormente.

Para el OP: He escrito esto principalmente para beneficio de cualquiera que se encuentre con esta pregunta en el futuro, ya que me doy cuenta de que su pregunta se formuló hace mucho tiempo.

Steve Haley avatar Feb 14 '2011 15:02 Steve Haley

Android: minSdkVersión

Un número entero que designa el nivel API mínimo requerido para que se ejecute la aplicación. El sistema Android impedirá que el usuario instale la aplicación si el nivel API del sistema es inferior al valor especificado en este atributo. Siempre debes declarar este atributo.

android: targetSdkVersión

Un número entero que designa el nivel de API al que se dirige la aplicación.

Con este atributo establecido, la aplicación dice que puede ejecutarse en versiones anteriores (hasta minSdkVersion), pero se probó explícitamente para que funcione con la versión especificada aquí. Especificar esta versión de destino permite a la plataforma deshabilitar configuraciones de compatibilidad que no son necesarias para la versión de destino (que de otro modo podrían activarse para mantener la compatibilidad futura) o habilitar funciones más nuevas que no están disponibles para aplicaciones más antiguas. Esto no significa que pueda programar diferentes funciones para diferentes versiones de la plataforma; simplemente informa a la plataforma que ha probado con la versión de destino y que la plataforma no debe realizar ningún trabajo adicional para mantener la compatibilidad futura con la versión de destino.

Para obtener más información, consulte esta URL:

http://developer.android.com/guide/topics/manifest/uses-sdk-element.html

Vikas Patidar avatar Dec 31 '2010 05:12 Vikas Patidar

Cuando configura targetSdkVersion="xx", certifica que su aplicación funciona correctamente (por ejemplo, ha sido probada exhaustiva y exitosamente) en el nivel API xx.

Una versión de Android que se ejecuta en un nivel de API superior a xx aplicará el código de compatibilidad automáticamente para admitir cualquier función en la que pueda confiar y que estaba disponible en el nivel de API xx o antes, pero que ahora está obsoleta en el nivel superior de esa versión de Android.

Por el contrario, si está utilizando funciones que quedaron obsoletas en el nivel xx o antes , las versiones del sistema operativo en niveles API superiores (que ya no incluyen esas funciones) no aplicarán automáticamente el código de compatibilidad para admitir esos usos. En esa situación, su propio código debe tener cláusulas de casos especiales que prueben el nivel de API y, si el nivel del sistema operativo detectado es uno superior que ya no tiene la característica de API dada, su código debe usar características alternativas que estén disponibles en el sistema operativo en ejecución. Nivel API.

Si no lo hace, es posible que simplemente no aparezcan algunas características de la interfaz que normalmente desencadenarían eventos dentro de su código, y es posible que le falte una característica de interfaz crítica que el usuario necesita para desencadenar esos eventos y acceder a su funcionalidad (como en el ejemplo ejemplo siguiente).

Como se indica en otras respuestas, puede configurar targetSdkVersion en un valor superior a minSdkVersion si desea utilizar algunas funciones de API definidas inicialmente en niveles de API más altos que su minSdkVersion y ha tomado medidas para garantizar que su código pueda detectar y manejar la ausencia de esas funciones en niveles más bajos que targetSdkVersion.

Para advertir a los desarrolladores que prueben específicamente el nivel de API mínimo requerido para usar una característica, el compilador emitirá un error (no solo una advertencia) si el código contiene una llamada a cualquier método que se definió en un nivel de API posterior a minSdkVersion. incluso si targetSdkVersion es mayor o igual que el nivel de API en el que ese método estuvo disponible por primera vez. Para eliminar este error, la directiva del compilador

@TargetApi(nn)

le dice al compilador que el código dentro del alcance de esa directiva (que precederá a un método o una clase) se ha escrito para probar un nivel de API de al menos nn antes de llamar a cualquier método que dependa de tener al menos ese nivel de API. . Por ejemplo, el siguiente código define un método que se puede llamar desde el código dentro de una aplicación que tiene una minSdkVersion menor que 11 y una targetSdkVersion de 11 o superior:

@TargetApi(11)
    public void refreshActionBarIfApi11OrHigher() {
      //If the API is 11 or higher, set up the actionBar and display it
      if(Build.VERSION.SDK_INT >= 11) {
        //ActionBar only exists at API level 11 or higher
        ActionBar actionBar = getActionBar();

        //This should cause onPrepareOptionsMenu() to be called.
        // In versions of the API prior to 11, this only occurred when the user pressed 
        // the dedicated menu button, but at level 11 and above, the action bar is 
        // typically displayed continuously and so you will need to call this
        // each time the options on your menu change.
        invalidateOptionsMenu();

        //Show the bar
        actionBar.show();
    }
}

También es posible que desee declarar una targetSdkVersion superior si realizó la prueba en ese nivel superior y todo funcionó, incluso si no estaba utilizando ninguna característica de un nivel API superior a su minSdkVersion. Esto sería solo para evitar la sobrecarga de acceder al código de compatibilidad destinado a adaptarse desde el nivel objetivo hasta el nivel mínimo, ya que habría confirmado (mediante pruebas) que no se requería dicha adaptación.

Un ejemplo de una característica de la interfaz de usuario que depende de la targetSdkVersion declarada sería el botón de menú de tres puntos verticales que aparece en la barra de estado de las aplicaciones que tienen una targetSdkVersion inferior a 11, cuando esas aplicaciones se ejecutan con API 11 y superior. Si su aplicación tiene una versión targetSdkVersion de 10 o inferior, se supone que la interfaz de su aplicación depende de la existencia de un botón de menú dedicado, por lo que el botón de tres puntos parece reemplazar el hardware dedicado anterior y/o las versiones en pantalla. de ese botón (por ejemplo, como se ve en Gingerbread) cuando el sistema operativo tiene un nivel de API más alto para el cual ya no se asume un botón de menú dedicado en el dispositivo. Sin embargo, si configura targetSdkVersion de su aplicación en 11 o superior, se supone que ha aprovechado las funciones introducidas en ese nivel que reemplazan el botón de menú dedicado (por ejemplo, la barra de acción), o que de otra manera ha evitado la necesidad de tener un botón de menú del sistema; en consecuencia, el "botón de compatibilidad" del menú de tres puntos verticales desaparece. En ese caso, si el usuario no puede encontrar un botón de menú, no puede presionarlo y eso, a su vez, significa que es posible que nunca se invoque la anulación onCreateOptionsMenu(menu) de su actividad, lo que, nuevamente a su vez, significa que una parte importante de la funcionalidad de su aplicación podría verse privada de su interfaz de usuario. A menos, por supuesto, que haya implementado la Barra de Acción o algún otro medio alternativo para que el usuario acceda a estas funciones.

minSdkVersion, por el contrario, establece el requisito de que la versión del sistema operativo de un dispositivo tenga al menos ese nivel de API para poder ejecutar su aplicación. Esto afecta qué dispositivos pueden ver y descargar su aplicación cuando está en la tienda de aplicaciones Google Play (y posiblemente también en otras tiendas de aplicaciones). Es una forma de indicar que su aplicación depende de características del sistema operativo (API u otras) que se establecieron en ese nivel y no tiene una forma aceptable de lidiar con la ausencia de esas características.

Un ejemplo de uso de minSdkVersion para garantizar la presencia de una característica que no está relacionada con API sería configurar minSdkVersion en 8 para garantizar que su aplicación se ejecute solo en una versión habilitada para JIT del intérprete Dalvik (desde que se introdujo JIT al intérprete de Android en el nivel API 8). Dado que el rendimiento de un intérprete habilitado para JIT puede ser hasta cinco veces mayor que el de uno que carece de esa característica, si su aplicación hace un uso intensivo del procesador, es posible que desee requerir API de nivel 8 o superior para garantizar un rendimiento adecuado.

Carl avatar Jun 24 '2012 10:06 Carl

Un concepto se puede transmitir mejor con ejemplos, siempre . Tuve problemas para comprender estos conceptos hasta que profundicé en el código fuente del marco de Android y hice algunos experimentos, incluso después de leer todos los documentos en los sitios de desarrolladores de Android y los subprocesos de stackoverflow relacionados. Voy a compartir dos ejemplos que me ayudaron mucho a comprender completamente estos conceptos.

Un DatePickerDialog se verá diferente según el nivel que coloque en la versión targetSDK( <uses-sdk android:targetSdkVersion="INTEGER_VALUE"/>) del archivo AndroidManifest.xml. Si establece el valor 10 o menos, su DatePickerDialog se verá como a la izquierda. Por otro lado, si establece el valor 11 o superior, un DatePickerDialog se verá bien, con el mismo código .

Aspecto de DatePickerDialog con targetSDK versión 10 o inferior Aspecto de DatePickerDialog con targetSDK versión 11 o superior

El código que utilicé para crear este ejemplo es súper simple. MainActivity.javaaspecto :

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onClickButton(View v) {
        DatePickerDialog d = new DatePickerDialog(this, null, 2014, 5, 4);
        d.show();       
    }
}

Y activity_main.xmlmira:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="onClickButton"
    android:text="Button" />
</RelativeLayout>


Eso es todo. Esos son realmente todos los códigos que necesito para probar esto.

Y este cambio de apariencia queda muy claro cuando ves el código fuente del marco de trabajo de Android . Dice así:

public DatePickerDialog(Context context,
    OnDateSetListener callBack,
    int year,
    int monthOfYear,
    int dayOfMonth,
    boolean yearOptional) {
        this(context, context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
                ? com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert
                : com.android.internal.R.style.Theme_Dialog_Alert,
        callBack, year, monthOfYear, dayOfMonth, yearOptional);
}

As you can see, the framework gets current targetSDKversion and set different theme. This kind of code snippet(getApplicationInfo().targetSdkVersion >= SOME_VERSION) can be found here and there in Android framework.

Another example is about WebView class. Webview class's public methods should be called on main thread, and if not, runtime system throws a RuntimeException, when you set targetSDKversion 18 or higher. This behavior can be clearly delivered with its source code. It's just written like that.

sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
            Build.VERSION_CODES.JELLY_BEAN_MR2;

if (sEnforceThreadChecking) {
    throw new RuntimeException(throwable);
}


The Android doc says, "As Android evolves with each new version, some behaviors and even appearances might change." So, we've looked behavior and appearance change, and how that change is accomplished.

In summary, the Android doc says "This attribute(targetSdkVersion) informs the system that you have tested against the target version and the system should not enable any compatibility behaviors to maintain your app's forward-compatibility with the target version.". This is really clear with WebView case. It was OK until JELLY_BEAN_MR2 released to call WebView class's public method on not-main thread. It is nonsense if Android framework throws a RuntimeException on JELLY_BEAN_MR2 devices. It just should not enable newly introduced behaviors for its interest, which cause fatal result. So, what we have to do is to check whether everything is OK on certain targetSDKversions. We get benefit like appearance enhancement with setting higher targetSDKversion, but it comes with responsibility.

EDIT : disclaimer. The DatePickerDialog constructor that set different themes based on current targetSDKversion(that I showed above) actually has been changed in later commit. Nevertheless I used that example, because logic has not been changed, and those code snippet clearly shows targetSDKversion concept.

김준호 avatar Jul 21 '2014 14:07 김준호