Weitere Informationen finden Sie im Dokument Embedded VM Control (unformatiertes HTML aus dem Quellbaum oder eine gut formatierte Kopie).
Grundsätzlich ist die Dalvik-VM so eingestellt, dass Assertionsprüfungen standardmäßig ignoriert werden, obwohl der .dex-Bytecode den Code zur Durchführung der Prüfung enthält. Das Überprüfen von Zusicherungen kann auf zwei Arten aktiviert werden:
(1) durch Setzen der Systemeigenschaft "debug.assert" über:
adb shell setprop debug.assert 1
was ich überprüft habe, funktioniert wie beabsichtigt, solange Sie Ihre App danach neu installieren, oder
(2) indem Sie das Befehlszeilenargument "--enable-assert" an die dalvik VM senden, was App-Entwickler wahrscheinlich nicht können (jemand korrigiert mich, wenn ich mich hier irre).
Grundsätzlich gibt es ein Flag, das entweder global, auf Paketebene oder auf Klassenebene gesetzt werden kann, um Zusicherungen auf dieser jeweiligen Ebene zu ermöglichen. Das Flag ist standardmäßig deaktiviert, wodurch die Assertionsprüfungen übersprungen werden.
Ich habe den folgenden Code in meine Beispielaktivität geschrieben:
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;
}
}
Für diesen Code lautet der generierte Dalvik-Byte-Code (für 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
:
:
// onCreate()
00035c: |[00035c] com.example.asserttest.AssertActivity.onCreate:(Landroid/os/Bundle;)V
00036c: 6f20 0100 3200 |0000: invoke-super {v2, v3}, Landroid/app/Activity;.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/example/asserttest/AssertActivity;.setContentView:(I)V // method@0005
00037c: 1250 |0008: const/4 v0, #int 5 // #5
00037e: 6301 0000 |0009: sget-boolean v1, Lcom/example/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: new-instance v1, Ljava/lang/AssertionError; // class@000c
000390: 7010 0b00 0100 |0012: invoke-direct {v1}, Ljava/lang/AssertionError;.:()V // method@000b
000396: 2701 |0015: throw v1
000398: 0e00 |0016: return-void
Beachten Sie, wie der statische Konstruktor die gewünschte MethodeAssertionStatus für das Class-Objekt aufruft und die klassenweite Variable $ assertionsDisabled festlegt. Beachten Sie auch, dass in onCreate () der gesamte Code zum Auslösen von java.lang.AssertionError kompiliert wird, seine Ausführung jedoch vom Wert von $ assertionsDisabled abhängt, der für das Class-Objekt im statischen Konstruktor festgelegt ist.
Es scheint, dass die Assert-Klasse von JUnit überwiegend verwendet wird, daher ist es wahrscheinlich eine sichere Wette, dies zu verwenden. Die Flexibilität des Schlüsselworts assert besteht darin, dass Assertions zur Entwicklungszeit aktiviert und für den Versand von Bits deaktiviert werden können und stattdessen ordnungsgemäß fehlschlagen.
Hoffe das hilft.