Могу ли я использовать assert на устройствах Android?

Я хочу использовать ключевое слово Assert в своих приложениях для Android, чтобы уничтожить мое приложение в некоторых случаях на эмуляторе или на моем устройстве во время тестирования. Это возможно?

Кажется, что эмулятор просто игнорирует мои утверждения.

Solutions Collecting From Web of "Могу ли я использовать assert на устройствах Android?"

API предоставляет JUnit Assert .

Ты можешь сделать

import static junit.framework.Assert.*; 

Теперь вы можете использовать все функции, такие как assertTrue, assertEquals, assertNull, которые предусмотрены в структуре junit.

Будьте осторожны, чтобы не импортировать среду Junit4 через eclipse, это будет пакет org.junit. Вы должны использовать пакет junit.framework, чтобы заставить его работать на устройстве Android или эмуляторе.

См. Документ Embedded VM Control (необработанный HTML из исходного дерева или красиво отформатированная копия).

В принципе, Dalvik VM настроен на игнорирование утверждений по умолчанию, хотя код байта .dex содержит код для выполнения проверки. Проверка утверждений включается одним из двух способов:

(1), установив системное свойство «debug.assert» через:

 adb shell setprop debug.assert 1 

Который я проверил, работает по назначению, пока вы переустанавливаете свое приложение после этого, или

(2), отправив аргумент командной строки «–enable-assert» в виртуальную машину dalvik, которая может быть не такой, какой могут быть разработчики приложений (кто-то меня исправит, если я ошибаюсь здесь).

В принципе, существует флаг, который может быть установлен либо глобально, либо на уровне пакета, либо на уровне класса, который позволяет утверждать на соответствующем уровне. Флаг отключен по умолчанию, в результате чего проверки утверждения пропущены.

В моем примере я написал следующий код:

 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):

 // 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 / Activity; .onCreate: (Landroid / os / Bundle;) V // метод @ 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 // метод @ 000b
000396: 2701 | 0015: throw v1
000398: 0e00 | 0016: return-void

Обратите внимание на то, как статический конструктор вызывает метод, требуемый для объекта класса AssassinStatus, и задает переменную класса $ assertionsDisabled; Также обратите внимание, что в onCreate () весь код для броска java.lang.AssertionError скомпилирован, но его выполнение зависит от значения $ assertionsDisabled, которое установлено для объекта Class в статическом конструкторе.

Похоже, что класс Assert JUnit – это то, что используется преимущественно, поэтому, скорее всего, это будет безопасная ставка. Гибкость ключевого слова assert – это возможность включить утверждения во время разработки и отключить их для отправки бит, а вместо этого – изящно.

Надеюсь это поможет.

Когда утверждения разрешены, ключевое слово assert просто выдает AssertionError когда логическое выражение false .

Таким образом, ИМО, лучшая альтернатива, особенно. Если вы не склонны зависеть от junit, нужно явно выбросить AssertionError как показано ниже:

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

Альтернативой приведенному выше утверждению является:

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

Где метод определяется как:

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

Документы Oracle java рекомендуют бросать AssertionError в качестве приемлемой альтернативы.

Я думаю, вы можете настроить Proguard, чтобы отключить эти вызовы для производственного кода.

В «Android on Practice» предлагается использовать:

 $adb shell setprop dalvik.vm.enableassertions all 

Если эти настройки не сохраняются на вашем телефоне, вы можете создать файл /data/local.prop со свойствами, такими как:

 dalvik.vm.enableassertions=all 

Это извинило меня, что мои утверждения не работали, пока я не проверил проблему на google … Я отказался от простых утверждений и поеду с методами утверждения юнитов.

Для удобства я использую:

Import static junit.framework.Assert. *;

Из-за статического импорта я могу позже написать:

assertTrue (…); Вместо Assert.assertTrue (…);

Если вы беспокоитесь о доставке кода с утверждением JUnit в (или любом другом пути к классу), вы можете использовать опцию конфигурации ProGuard «precenosideeffects», которая будет вытеснять путь класса в предположении, что удаление его ничего не делает для кода ,

Например.

 -assumenosideeffects junit.framework.Assert { *; } 

У меня есть общая библиотека отладки, в которую я помещаю все свои методы тестирования, а затем использую эту опцию, чтобы удалить ее из моих выпущенных приложений.

Это также устраняет сложную проблему с манипуляциями строк, которые никогда не используются в коде выпуска. Например, если вы пишете метод журнала отладки, и в этом методе вы проверяете режим отладки перед записью строки, вы все равно строите строку, выделяете память, вызывая метод, но затем выбираете ничего не делать. Зачищая класс, он полностью удаляет вызовы, что означает, что если строка построена внутри вызова метода, она также исчезает.

Удостоверьтесь, что действительно безопасно просто линять линии, однако, как это делается без проверки на стороне ProGuard. Удаление любого метода возврата void будет прекрасным, однако, если вы принимаете какие-либо возвращаемые значения из того, что вы удаляете, убедитесь, что вы не используете их для реальной операционной логики.

Чтобы добавить к ответу Zulaxia об удалении Junit – Proguard уже входит в Android SDK / Eclipse, и на следующей странице рассказывается, как включить его.

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

Кроме того, вышеупомянутое не работает с последней конфигурацией proguard по умолчанию, поскольку использует флаг -dontoptimize, который необходимо удалить, а некоторые из оптимизаций включены.

Используйте стандартное ключевое слово Java assert , например:

 assert a==b; 

Для этого вам нужно добавить одну строку в /system/build.prop и перезагрузить телефон:

 debug.assert=1 

Это будет работать на корневом телефоне. Используйте некоторый файловый менеджер, способный редактировать build.prop (например, X-plore).

Плюсы: большинство (все?) Android-телефоны поставляются с отключенными утверждениями. Даже если ваш код случайно утверждает false, приложение не будет прерывать или терпеть крах. Однако на вашем устройстве разработки вы получите исключение утверждения.

Вы можете использовать утверждения, но для их надежной работы требуется определенная работа. Системное свойство debug.assert не является надежным. См. Вопросы 175697 , 65183 , 36786 и 17324 .

Чтобы сделать утверждения надежными на Android, вы должны перевести каждый оператор утверждения на что-то, с чем могут справиться все время автономной работы. Это можно сделать с помощью исходного препроцессора перед компилятором Java. Например, рассмотрим это утверждение:

 assert x == 0: "Failure message"; 

В сборке отладки препроцессор переводил бы это в оператор if :

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

В производственной сборке, в пустой оператор:

 ; 

Обратите внимание, что такие утверждения обязательно включены или отключены во время сборки исходным препроцессором, а не во время выполнения виртуальной машиной. Это отличается от обычной практики Java.

Я не смог найти готовый препроцессор, поэтому мне пришлось писать сценарий самостоятельно (см. Часть, посвященную утверждениям). Лицензия на копирование здесь .