См. Документ Embedded VM Control (необработанный HTML-код из исходного дерева или красиво отформатированной копии).
По сути, виртуальная машина Dalvik настроена на игнорирование проверок утверждений по умолчанию, хотя байт-код .dex содержит код для выполнения проверки. Проверка утверждений включена одним из двух способов:
(1), установив системное свойство "debug.assert" через:
adb shell setprop debug.assert 1
, который я проверил, работает так, как задумано, если вы переустановите свое приложение после этого, или
(2) отправив аргумент командной строки «--enable-assert» на виртуальную машину dalvik, что, возможно, не то, что разработчики приложений могут сделать (кто-то поправит меня, если я здесь не прав).
По сути, существует флаг, который может быть установлен либо глобально, на уровне пакета или на уровне класса, который разрешает утверждения на этом соответствующем уровне. По умолчанию этот флаг отключен, в результате чего проверки утверждений пропускаются.
Я написал следующий код в моем примере Activity:
<code>
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;
}
}
Для этого кода генерируется байт-код dalvik (для Android 2.3.3):
<code>
// 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</p>
<p>:
:</p>
<p>// 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</p>
<p>
Обратите внимание, как статический конструктор вызывает метод selectedAssertionStatus для объекта Class и устанавливает общеклассовую переменную $ assertionsDisabled; также обратите внимание, что в onCreate () весь код для выброса java.lang.AssertionError компилируется, но его выполнение зависит от значения $ assertionsDisabled, которое установлено для объекта Class в статическом конструкторе.
Похоже, что класс JUnit Assert используется преимущественно, поэтому, вероятно, это безопасная ставка. Гибкость ключевого слова assert заключается в возможности включения утверждений во время разработки и отключения их для доставки битов, а вместо этого изящного сбоя.
Надеюсь, это поможет.