53 votes

Écrire du code Android compatible en amont

Je suis en train d'écrire une application qui utilise des fonctions et des classes uniquement disponible dans la dernière API de niveau 16, mais je veux marcher avec pas d'erreurs sur les appareils avec l'API de niveau 15.

Prenons quelques exemples. Une nouvelle classe: Android.widget.Advanceable, et une nouvelle/renommé méthode: View.setBackground():

Je peux faire quelque chose comme ceci:

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 j'ai mis un minSdk de 15, mais une cible de génération de 16 ans (c'est à dire dans les Propriétés du Projet->Android), il va compiler sans erreurs. Au moins de temps en temps. Eclipse est un peu stochastique sur les erreurs et parfois de dire "setBackground() n'est disponible dans l'API de niveau >= 16" ou similaire, mais si je viens de nettoyer le projet de ces erreurs magie disparaître.

Donc ma question est, suis-je autorisé à faire cela? Ne sera pas le code de crash si je le lance sur une API de niveau 15 de l'appareil? Sera-ce seulement en panne si elle est pour le 16 du code? Pourquoi ne pas Eclipse m'empêcher de le construire?

Edit 1

Merci pour les réponses, je suppose que la question devrait vraiment être: Pourquoi ne pas en faire de la charpie me mettent en garde sur l'utilisation de la nouvelle Api?

J'ai ceci dans mon manifeste, et je suis l'aide de l'API de niveau 16 fonctions, mais elle n'est pas toujours m'avertir:

<uses-sdk android:minSdkVersion="15"
    android:targetSdkVersion="16"/>

Aussi je suis toujours pas sûr de savoir quand des classes entières sont de nouveau à un niveau API, comme Advanceable. Spécifiquement si je les utiliser comme variables de membre.

Edit 2

La réponse s'est avéré être "Eclipse est buggé comme l'enfer", mais Nico réponse a également été très utile.

74voto

Nico Points 359

Inline les erreurs de l'Api sont de nouveau à l'ADT, Eclipse exécuter les Peluches (et je suppose que quelque chose d'autre peut-être) à l'analyse de votre code et de mettre ces erreurs / warnigns en ligne. Le même s'applique à xml mise en page lorsque vous avez des avertissements ou des conseils au sujet des optimisations ou des meilleures pratiques. Vous pouvez utiliser les 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 niveau de l'api de vérifier si vous avez une instance de Advanceable dans le code qui ne fonctionne pas dans l'api < 16, donc la vérification de l'api de niveau n'est utile que lorsque vous appelez de nouvelles méthodes, mais vous ne pouvez pas faire référence à de nouvelles classes de l'api à l'extérieur du bloc if.

Une approche que j'ai trouvé aceptable est de créer une classe abstraite et deux implémentations, puis instancier la mise en œuvre correcte, vous pouvez utiliser une usine de classe avec des méthodes statiques.

Par exemple, pour créer une vue que l'usage d'une nouvelle api de classes et de méthodes en interne vous avez besoin:

1 - Créer une classe abstraite:

public abstract class CustomView {
    public abstract void doSomething();
}
  • Commune de mise en œuvre compatible avec toutes les api
  • Définir la méthode abstraite ici pour split mise en œuvre

2 - l'Héritage de la mise en œuvre

public class CustomLegacyView extends CustomView {
    public void doSomething(){
        //implement api < 16
    }
}
  • mettre en œuvre la méthode abstraite pour api < 16

3 - API 16 mise en œuvre

@TargetApi(16)
public class CustomL16View extends CustomView {

    Advanceable myAdvanceable;

    public void doSomething(){
        //implement api >= 16
    }
}
  • L'utilisation de l'annotation @TargetApi(16)
  • mettre en œuvre la méthode abstraite pour api >= 16
  • Vous pouvez le niveau de référence de 16 classes ici (mais pas dans CustomView)

4 - l'Usine de la classe

public class ViewFactory {

    public static CustomView getCustomView(Context context) {

        if (android.os.Build.VERSION.SDK_INT >= 16) {
            return new CustomL16View(context);
        }else{
            return new CustomLegacyView(context);
        }

    }
}

3voto

biegleux Points 6422

Il est courant d'utiliser une cible de construction plus récente et de garantir que les nouvelles API seront appelées dans les bonnes circonstances. Google a même ajouté des annotations @TargetApi() depuis ADT 17 pour spécifier des remplacements locaux pour le code chargé sous condition.

Voir Vérification de l'API Lint pour plus de détails.

-2voto

Kumar Vivek Mitra Points 19369

1. Vous avez Target Api et Minimum SDK des attributs pour définir quel type d'appareil vous sont ciblage et qui sera la moins la version de l'Api sur laquelle il sera exécuté.

2. Target Api sera celui sur lequel l' Application s'exécute avec des fonctionnalités Complètes, alors que Minimum SDK feront l' Application de fonctionner sur elle avec quelques Compromis comme il peut y avoir des chances que le bas de la version de l'API ne pas disposer de toutes les fonctions qui sont dans ses versions supérieures.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X