89 votes

Puis-je utiliser assert sur les appareils Android ?

Je veux utiliser le mot clé assert dans mes applications android pour détruire mon application dans certains cas sur l’émulateur, ou mon appareil au cours des essais. Est-ce possible ?

Il semble que l’émulateur ignore tout mon soutient.

145voto

scorpiodawg Points 1774

Voir ceci: https://android.googlesource.com/platform/dalvik/+/master/docs/embedded-vm-control.html

Fondamentalement, le Dalvik VM est configuré pour ignorer affirmation des vérifications par défaut, même si l' .dex byte code inclut le code pour effectuer la vérification. La vérification des assertions est activée dans l'une des deux façons suivantes:

(1) par le réglage du système de la propriété "debug.affirmer" via:

adb shell setprop debug.assert 1

qui j'ai vérifié fonctionne comme prévu aussi longtemps que vous réinstallez votre application après avoir fait cela, ou

(2) par l'envoi de l'argument de ligne de commande "--enable-valoir" pour le dalvik VM qui pourraient ne pas être quelque chose que les développeurs d'applications sont susceptibles d'être en mesure de le faire (que quelqu'un me corrige si je me trompe).

Fondamentalement, il est un indicateur qui peut être réglé au niveau mondial, au niveau du package, ou un niveau de classe qui permet d'assertions à ce niveau. Le drapeau est désactivée par défaut, la suite de laquelle l'affirmation des contrôles sont ignorés.

J'ai écrit le code suivant dans mon exemple d'Activité:


public class AssertActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    int x = 2 + 3;
    assert x == 4;
  }
}

Pour ce code, le dalvik du byte-code qui est généré est (Android 2.3.3):


// Static constructor for the class
000318:                                        |[000318] com.example.asserttest.AssertActivity.:()V
000328: 1c00 0300                              |0000: const-class v0, Lcom/example/asserttest/AssertActivity; // class@0003
00032c: 6e10 0c00 0000                         |0002: invoke-virtual {v0}, Ljava/lang/Class;.desiredAssertionStatus:()Z // method@000c
000332: 0a00                                   |0005: move-result v0
000334: 3900 0600                              |0006: if-nez v0, 000c // +0006
000338: 1210                                   |0008: const/4 v0, #int 1 // #1
00033a: 6a00 0000                              |0009: sput-boolean v0, Lcom/example/asserttest/AssertActivity;.$assertionsDisabled:Z // field@0000
00033e: 0e00                                   |000b: return-void
000340: 1200                                   |000c: const/4 v0, #int 0 // #0
000342: 28fc                                   |000d: goto 0009 // -0004

Remarquez comment le constructeur statique appelle la méthode desiredAssertionStatus l'objet de Classe et définit la classe à l'échelle de la variable $assertionsDisabled; notez aussi que dans onCreate(), tout le code pour lancer java.lang.AssertionError est compilé, mais son exécution est subordonnée à la valeur de $assertionsDisabled qui est fixé pour la Classe de l'objet dans le constructeur statique.

Il semble que JUnit la classe Assert est ce qui est principalement utilisé, alors il est probablement un pari sûr à utiliser. La flexibilité de l'affirmer mot-clé est la capacité de tourner sur des assertions au temps de développement et de les désactiver pour l'expédition bits et au lieu d'échouer gracieusement.

Espérons que cette aide.

10voto

Dheeraj V.S. Points 6384

Lorsque les assertions sont activés, l' assert mot-clé tout simplement jette un AssertionError lorsque l'expression booléenne est - false.

Donc, IMO, la meilleure alternative, esp. si vous êtes opposé à dépendre sur junit, est de jeter un AssertionError explicitement comme indiqué ci-dessous:

assert x == 0 : "x = " + x;

Une alternative à la déclaration ci-dessus est:

Utils._assert(x == 0, "x = " + x);

Où la méthode est définie comme:

public static void _assert(boolean condition, String message) {
    if (!condition) {
        throw new AssertionError(message);
    }
}

L'Oracle java docs vous recommandons de jeter un AssertionError comme une alternative acceptable.

Je suppose que vous pouvez configurer Proguard à dépouiller ces appels pour la production de code.

8voto

marcin_j Points 12237

Dans « Android en pratique », il est conseillé d’utiliser :

Si ce paramètres n’est pas conservée sur votre téléphone, puis vous pouvez créer /data/local.prop fichier avec des propriétés telles que :

5voto

Ready4Android Points 1103

Il branchait l’enfer hors de moi, que mes affirmations n’a pas fonctionné, jusqu'à ce que j’ai vérifié le numéro sur google... J’ai abandonné sur de simples affirmations et ira avec junits méthodes d’assertion.

À des fins de commodité, j’utilise :

importation junit.framework.Assert.* statique ;

Je peux écrire plus tard en raison de l’importation statique :

assertTrue(...) ; au lieu de Assert.assertTrue(...) ;

4voto

Zulaxia Points 1572

Si vous êtes inquiet au sujet de code de la navigation avec JUnit affirme (ou toute autre catégorie de chemin d'accès), vous pouvez utiliser le ProGuard option de configuration 'assumenosideeffects", qui va priver une catégorie de chemin d'accès sur l'hypothèse que la suppression il ne fait rien pour le code.

Par exemple.

-assumenosideeffects junit.framework.Assert {
*;
}

J'ai une commune de débogage de la bibliothèque, j'ai mis tous mes méthodes d'essai, puis utilisez cette option pour supprimer à partir de mon libéré apps.

Cela supprime également les durs à repérer problème de cordes d'être manipulés qui ne sont jamais utilisés dans le code de libération. Par exemple, si vous écrivez un journal de débogage de la méthode, et cette méthode vous vérifiez le mode de débogage avant l'enregistrement de la chaîne, vous êtes toujours en train de construire la chaîne, de l'allocation de mémoire, l'appel de la méthode, mais alors en optant de ne rien faire. Le décapage de la classe puis supprime les appels entièrement, cela signifie aussi longtemps que votre chaîne est construite à l'intérieur de l'appel de méthode, il s'en va.

Assurez-vous qu'il est vraiment sûr de simplement enlever les lignes cependant, comme il est fait avec aucune vérification sur ProGuard. Retrait de tout espace vide de retour de la méthode sera très bien, cependant, si vous prenez des valeurs de retour de ce que vous êtes en train de supprimer, assurez-vous de ne pas les utiliser pour une réelle logique de fonctionnement.

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