J'écris une application qui utilise certaines fonctions et classes uniquement disponibles dans le dernier niveau d'API - 16, mais je veux qu'elle s'exécute sans erreur sur les appareils avec le niveau d'API 15.
Prenons quelques exemples. Une nouvelle classe: Android.widget.Advanceable
, Et une nouvelle méthode/renommée: View.setBackground()
:
Je peux faire quelque chose comme ça:
Advanceable myAdvanceable = ...;
if (Android.os.Build.VERSION.SDK_INT >= 16)
{
myView.setBackground(...);
myAdvanceable.advance();
}
else
{
myView.setBackgroundDrawable(...); // The old function name.
// Don't bother advancing advanceables.
}
Et si je définit un minSdk de 15 mais une cible de construction de 16 (c'est-à-dire dans Propriétés du projet-> Android), il se compilera en fait sans erreur. Au moins une partie du temps. Eclipse est un peu stochastique à propos des erreurs et dit parfois que "setBackground () n'est disponible qu'au niveau API> = 16" ou similaire, mais si je nettoie simplement le projet, ces erreurs disparaissent comme par magie.
Donc ma question est, suis-je autorisé à faire cela? Le code ne se bloquera-t-il pas si je l'exécute sur un périphérique API de niveau 15? Est-ce que cela ne plantera que s'il atteint le code 16? Pourquoi Eclipse ne m'empêche-t-il pas de le construire?
Merci pour les réponses, je suppose que la question devrait vraiment être: pourquoi les peluches ne m'avertiront-elles pas d'utiliser de nouvelles API?
J'ai ceci dans mon manifeste et j'utilise des fonctions API niveau 16 mais cela ne m'avertit toujours pas:
<uses-sdk Android:minSdkVersion="15"
Android:targetSdkVersion="16"/>
De plus, je ne sais toujours pas quand des classes entières sont nouvelles à un niveau API, comme Advanceable
. Plus précisément si je les utilise comme variables membres.
La réponse s'est avérée être "Eclipse est un buggy comme l'enfer", mais la réponse de Nico a également été très utile.
Les erreurs Api en ligne sont nouvelles pour ADT, Eclipse exécute Lint (et je suppose que quelque chose d'autre peut-être) pour analyser votre code et mettre ces erreurs/avertissements en ligne. La même chose s'applique à la mise en page XML lorsque vous avez des avertissements ou des conseils sur les optimisations ou les meilleures pratiques. Vous pouvez utiliser des annotations pour supprimer ces erreurs dans la classe ou dans une méthode particulière.
@TargetApi (16)
@ SuppressLint ("NewApi")
Il y a un problème dans l'exemple de code que vous mettez ici, à côté de la vérification du niveau d'API, vous avez une instance d'Advanceable dans le code qui ne fonctionnera pas dans l'API <16, donc la vérification du niveau d'API n'est utile que lorsque vous appelez de nouvelles méthodes mais vous ne pouvez pas référencer de nouvelles classes d'API en dehors du bloc IF.
Une approche que j'ai trouvée acceptable consiste à créer une classe abstraite et deux implémentations, puis pour instancier l'implémentation correcte, vous pouvez utiliser une classe d'usine avec des méthodes statiques.
Par exemple, pour créer une vue qui utilise en interne de nouvelles classes et méthodes d'API, vous avez besoin:
1 - Créer une classe abstraite:
public abstract class CustomView {
public abstract void doSomething();
}
2 - Implémentation héritée
public class CustomLegacyView extends CustomView {
public void doSomething(){
//implement api < 16
}
}
3 - Implémentation de l'API 16
@TargetApi(16)
public class CustomL16View extends CustomView {
Advanceable myAdvanceable;
public void doSomething(){
//implement api >= 16
}
}
4 - Classe d'usine
public class ViewFactory {
public static CustomView getCustomView(Context context) {
if (Android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return new CustomL16View(context);
}else{
return new CustomLegacyView(context);
}
}
}
Il est courant d'utiliser une cible de génération plus récente et de garantir que de nouvelles API seront appelées dans les bonnes circonstances. Google a même ajouté @TargetApi()
annotation depuis ADT 17 pour spécifier les remplacements locaux pour le code chargé sous condition.
Voir Vérification de l'API Lint pour plus de détails.