¿Puedo usar assert en dispositivos Android?

Quiero utilizar la palabra clave Assert en mis aplicaciones Android para destruir mi aplicación en algunos casos en el emulador o en mi dispositivo durante la prueba. es posible?

Parece que el emulador ignora mis afirmaciones.

La API proporciona el JUnit Assert .

Tu puedes hacer

import static junit.framework.Assert.*; 

Ahora puede utilizar todas las funciones como assertTrue, assertEquals, assertNull que se proporcionan en el marco junit.

Tenga cuidado de no importar el framework Junit4 a través de eclipse, que sería el paquete org.junit. Tienes que usar el paquete junit.framework para que funcione en un dispositivo android o en el emulador.

Consulte el documento Embedded VM Control (código HTML en bruto del árbol de origen o una copia con formato bien ).

Básicamente, la VM Dalvik está configurada para ignorar las comprobaciones de aserción de forma predeterminada, aunque el código de byte .dex incluye el código para realizar la comprobación. Comprobación de aserciones se activa en una de dos maneras:

(1) estableciendo la propiedad del sistema "debug.assert" a través de:

 adb shell setprop debug.assert 1 

Que he verificado funciona según lo previsto, siempre y cuando reinstale su aplicación después de hacer esto, o

(2) enviando el argumento de línea de comandos "–enable-assert" a la VM de dalvik, que podría no ser algo que los desarrolladores de aplicaciones puedan hacer (alguien me corrija si estoy equivocado).

Básicamente, hay una bandera que se puede establecer ya sea a nivel global, a nivel de paquete o en un nivel de clase que permite aserciones en ese nivel respectivo. La bandera está desactivada de forma predeterminada, por lo que se omite la comprobación de aserción.

Escribí el siguiente código en mi muestra Actividad:

 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; } } 

Para este código, el código de byte dalvik que se genera es (para 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 

// 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

:
:

// onCreate ()
00035c: | [00035c] com.example.asserttest.AssertActivity.onCreate: (Landroid / os / Bundle;) V
00036c: 6f20 0100 3200 | 0000: invoke-super {v2, v3}, Landroid / app / Actividad; .onCreate: (Landroid / os / Bundle;) V // method @ 0001
000372: 1501 037f | 0003: const / high16 v1, #int 2130903040 // # 7f03
000376: 6e20 0500 1200 | 0005: invoke-virtual {v2, v1}, Lcom / ejemplo / asserttest / AssertActivity; .setContentView: (I) V // method @ 0005
00037c: 1250 | 0008: const / 4 v0, #int 5 // # 5
00037e: 6301 0000 | 0009: sget-boolean v1, Lcom / ejemplo / asserttest / AssertActivity;. $ AssertionsDisabled: Z // field @ 0000
000382: 3901 0b00 | 000b: if-nez v1, 0016 // + 000b
000386: 1251 | 000d: const / 4 v1, #int 5 // # 5
000388: 3210 0800 | 000e: if-eq v0, v1, 0016 // +0008
00038c: 2201 0c00 | 0010: nueva instancia v1, Ljava / lang / AssertionError; // class @ 000c
000390: 7010 0b00 0100 | 0012: invoke-direct {v1}, Ljava / lang / AssertionError;; :() V // método @ 000b
000396: 2701 | 0015: throw v1
000398: 0e00 | 0016: return-void

Observe cómo el constructor estático invoca el método desiredAssertionStatus en el objeto Class y establece la variable de clase $ assertionsDisabled; También notar que en onCreate (), todo el código para lanzar java.lang.AssertionError se compila en, pero su ejecución depende del valor de $ assertionsDisabled que se establece para el objeto Class en el constructor estático.

Parece que la clase Assert de JUnit es lo que se utiliza predominantemente, por lo que es probable que sea una apuesta segura usarlo. La flexibilidad de la palabra clave asert es la capacidad de activar las aserciones en el momento del desarrollo y desactivarlas para enviar los bits y, en su lugar, fallan con gracia.

Espero que esto ayude.

Cuando las aserciones están habilitadas, la palabra clave assert simplemente lanza un AssertionError cuando la expresión booleana es false .

Así que la OMI, la mejor alternativa, esp. Si eres reacio a depender de junit, es lanzar un AssertionError explícitamente como se muestra a continuación:

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

Una alternativa a la declaración anterior es:

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

Cuando el método se define como:

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

Los documentos de Oracle java recomiendan lanzar un AssertionError como una alternativa aceptable.

Supongo que puede configurar Proguard para eliminar estas llamadas para el código de producción.

En "Android en la práctica" se sugiere utilizar:

 $adb shell setprop dalvik.vm.enableassertions all 

Si esta configuración no se mantiene en el teléfono, entonces puede crear el archivo /data/local.prop con propiedades como:

 dalvik.vm.enableassertions=all 

Estaba escuchando el infierno de mí, que mis afirmaciones no funcionaron, hasta que revisé el problema en google … Dejé en aserciones simples e iré con los métodos de aserción junits.

Para fines de conveniencia estoy usando:

Import static junit.framework.Assert. *;

Debido a la importación estática que puedo escribir más tarde:

AssertTrue (…); En lugar de Assert.assertTrue (…);

Si le preocupa el código de envío con el JUnit afirma en (o cualquier otra ruta de clase), puede usar la opción de configuración de ProGuard 'assumenosideeffects', que eliminará una ruta de clase suponiendo que su eliminación no hace nada al código .

P.ej.

 -assumenosideeffects junit.framework.Assert { *; } 

Tengo una biblioteca de depuración común en la que pongo todos mis métodos de prueba, y luego usar esta opción para despojarla de mis aplicaciones liberadas.

Esto también elimina el problema difícil de detectar de las cadenas manipuladas que nunca se utilizan en el código de liberación. Por ejemplo, si escribe un método de registro de depuración y, en ese método, comprueba el modo de depuración antes de registrar la cadena, sigue construyendo la cadena, asignando memoria, llamando al método, pero optando por no hacer nada. Despojando a la clase fuera entonces elimina las llamadas por completo, es decir, siempre y cuando la cadena se construye dentro de la llamada al método, se va también.

Asegúrese de que es realmente seguro para sólo desnudar las líneas, sin embargo, ya que se hace sin comprobar la parte de ProGuard. La eliminación de cualquier método de retorno de void estará bien, sin embargo, si está tomando valores de retorno de lo que está eliminando, asegúrese de no utilizarlos para la lógica operacional real.

Para agregar a la respuesta de Zulaxia en la eliminación de Junit – Proguard ya forma parte de Android SDK / Eclipse y la siguiente página le explica cómo habilitarlo.

http://developer.android.com/guide/developing/tools/proguard.html

Además, el anterior no funcionará con la última configuración predeterminada de proguard porque utiliza el indicador -dontoptimize que debe eliminarse y algunas de las optimizaciones activadas.

Utilice la palabra clave Java asert , por ejemplo:

 assert a==b; 

Para que esto funcione, debe agregar una línea a /system/build.prop y reiniciar el teléfono:

 debug.assert=1 

Esto funcionaría en el teléfono enraizado. Utilice algún administrador de archivos capaz de editar build.prop (por ejemplo, X-plore).

Ventajas: la mayoría (todos?) Los teléfonos Android se envían con aserciones desactivadas. Incluso si su código afirma accidentalmente falsa, la aplicación no interrumpirá ni se bloqueará. Sin embargo, en su dispositivo de desarrollo obtendrá una excepción de aserción.

Puede utilizar aserciones, pero se necesita cierto trabajo para utilizarlas de forma fiable. La propiedad de sistema debug.assert no es confiable. Véanse los números 175697 , 65183 , 36786 y 17324 .

Para hacer confiables las afirmaciones en Android, debe traducir cada sentencia assert a algo que todos los tiempos de ejecución pueden resolver. Esto se puede hacer con un preprocesador de origen frente al compilador de Java. Por ejemplo, considere esta afirmación:

 assert x == 0: "Failure message"; 

En una compilación de depuración, el preprocesador traduciría esto a una instrucción if :

 { if( !(x == 0) ) throw new AssertionError( "Failure message" ); } 

En una compilación de producción, a una declaración vacía:

 ; 

Tenga en cuenta que tales aserciones están necesariamente habilitadas o deshabilitadas en el tiempo de compilación por el preprocesador de origen, no en tiempo de ejecución por la máquina virtual. Esto difiere de la práctica convencional de Java.

No pude encontrar un preprocesador ya hecho, así que tuve que escribir mi propio (ver la parte que trata de afirmaciones). La licencia para copiar está aquí .

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.