Лучший способ сделать Debug only assert code

Я пишу свое первое приложение для Android, и я свободно использую asserts () из junit.framework.Assert

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

Я знаю, как запросить атрибут android: debuggable из манифеста, чтобы я мог создать переменную и выполнить это в следующем fashon:

Static final boolean mDebug = …

If (mDebug) Assert.assertNotNull (просмотр);

Есть лучший способ сделать это? Т.е. я бы предпочел не использовать if () с каждым утверждением.

благодаря

Solutions Collecting From Web of "Лучший способ сделать Debug only assert code"

Я думаю, что ключевое слово assert Java-языка, скорее всего, вы хотите. Под обложками ключевое слово assert существу компилируется в байт-код Dalvik, который выполняет две функции:

  1. Проверяет, является ли статическая переменная assertionsDisabled (установлена ​​в статическом конструкторе класса через вызов java.lang.Class.desiredAssertionStatus() ) равна! = 0, и если да, то ничего не делает
  2. Если это 0, то он проверяет выражение утверждения и выдает java.lang.AssertionError если выражение разрешает false , эффективно прекращая ваше приложение.

Время выполнения Dalvik по умолчанию имеет утверждения, которые были отключены, и поэтому desiredAssertionStatus всегда возвращал 1 (или, точнее, некоторое ненулевое значение). Это похоже на работу в «розничном» режиме. Чтобы включить режим «отладки», вы можете запустить следующую команду против эмулятора или устройства:

 adb shell setprop debug.assert 1 

И это должно сделать трюк (должно работать на эмуляторе или на любом корневом устройстве для отладки).

Обратите внимание, однако, что вышеупомянутый код Dalvik, который проверяет значение assertionsDisabled и выбрасывает AssertionError если выражение является ложным, всегда включается в ваш байт-код, и либеральное разбрызгивание assert s в вашем коде может привести к раздуванию байтового кода.

Пожалуйста, посмотрите немного подробнее: могу ли я использовать assert на устройствах Android?

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

Например.

 -assumenosideeffects class junit.framework.Assert { *; } 

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

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

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

Я имею в виду, если вы используете функцию языка, например assert (), компилятор должен уметь это исключить. Но это фактический класс, и если класс ссылается на исполняемый код, он будет включен или предполагается включенным в конечный продукт компилятором.

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

Другим подходом было бы сделать тестовый проект, который нацелен на ваше приложение, и в тестах JUnit фактически называет Assert в областях, которые вы хотите, чтобы убедиться, что они работают. Мне лично нравится этот подход, потому что это хорошее и чистое разделение теста и приложения.

Если вы просто беспокоитесь о том, что везде есть оператор if, то просто заверните Assert своим собственным классом DebuggableAssert, который выполняет эту проверку перед каждым вызовом Assert.X. Это будет выглядеть менее результативно из-за ввода / выхода метода и условных выражений, но если вы сможете лучше поддерживать код, это может стоить того.