среда, 2 апреля 2014 г.

Отключение junit.framework.Assert в релизе Android-приложения

Как я уже писал, стандартные директивы assert по умолчанию отключены на Android-девайсах. Их необходимо включать (например командой adb shell setprop debug.assert 1, после чего assert будет работать до перезагрузки девайса).

Альтернатива - junit.framework.Assert. И по функционалу побогаче, и работает на девайсах сразу, без дополнительных включений. При Null-анализе компилятор eclipse учитывает junit.framework.Assert точно так же, как обычный assert. Вроде бы, одни плюсы. Но: в релизе ассерты следует отключить. И вот тут требуются дополнительные телодвижения.

Далее предполагается, что используется Eclipse + ADT plugin.

Все что нужно сделать - это заставить ProGuard удалить все вызовы junit.framework.Assert.* из кода. Для это существует директива ProGuard -assumenosideeffects. В файл proguard-project.txt в корне проекта добавляем строчку:
-assumenosideeffects class junit.framework.Assert {
 <methods>
}
Все? Не все. Для того, чтобы ProGuard смог исключать вызовы методов в коде, необходимо включить оптимизацию, которая, отключена по-умолчанию. В файлах ant.properties (сборка из командной строки через Ant) и project.properties (сборка из Eclipse через export) смотрим строчку
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
и меняем ее на
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
Загляните в директорию ${sdk.dir}/tools/proguard/, посмотрите, чем отличаются файлы proguard-android.txt и proguard-android-optimize.txt. В первом оптимизация отключена, во втором - включена. В файле proguard-android-optimize.txt кратко написано, почему оптимизация по умолчанию отключена и в каких случаях ее включение может приводить к проблемам.

На StackOverflow предлагают так же явно прописывать параметры оптимизации через команду -optimizations. Поэкспериментировав я пришел к выводу, что это лишнее обнаружил, что подобное ограничение в оптимизации действительно может быть необходимо. Код, работающий с Android Facebook SDK падал в моем приложении до тех пор, пока я не отредактировал proguard-project.txt следующим образом
-optimizations code/removal/simple,code/removal/advanced
-assumenosideeffects class junit.framework.Assert {
 <methods>
}

1 комментарий: