Android, ProGuard и keepclasses с именами членов
Распространенный шаблон в конфигах ProGuard для приложений Android - сохранение пользовательских View
классы, поскольку на них, вероятно, ссылаются только из разметки XML, а не из кода приложения.
Поэтому при создании проекта ADT добавляет эти правила в proguard.cfg проекта:
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
Я предполагаю, что идея состоит в том, чтобы сказать, что всякий раз, когда класс определяет конструктор, который может быть вызван инфлятором макета, сохраните его. Однако, согласно документам ProGuard, keepclasseswithmembernames
квалификатор является сокращением для keepclasseswithmembers
а также allowshrinking
, что, если я правильно понимаю, означает: разрешено удалять эти классы, но если они сохраняются, не запутывайте имена его членов (возможно, чтобы не нарушать привязки между именами атрибутов XML и установщиками классов).
Но разве это не означает, что эти классы все еще будут удалены во время фазы сжатия (allowhrinking = true), если на них нет прямой ссылки в коде? Действительно, это то, что произошло с пользовательским виджетом, который мы используем в нашем приложении, и я мог бы решить эту проблему, установив правило просто keepclasseswithmembers
так как это просто полностью сохранит соответствующие классы (стоит отметить, что это также делает и официальный пример ProGuard Android).
Я неправильно читаю документы ProGuard или это ошибка в мастере проекта ADT?
2 ответа
Конфигурация в Android SDK (по крайней мере, до версии 11) не совсем корректна.
Конфигурация для Android в документации ProGuard правильно указывает "-keepclasseswithmembers", а не "-keepclasseswithnamenames".
Когда я впервые попробовал интегрированный proguard с Ant, мое приложение продолжало падать с ошибками времени выполнения на обработчиках кликов. (Я всегда устанавливаю их в XML). Я предположил, что, должно быть, что-то делаю не так, не могу понять что, поэтому добавил строку
-dontshrink
в верхней части proguard.cfg.
Возможно это не оптимально, но это остановило ошибки времени выполнения!
добавление
На самом деле я проверил это, посмотрев на use.txt. Обработчики кликов были перечислены там до того, как я добавил опцию dontshrink, после того как я добавил ее, use.txt был пуст, как и следовало ожидать.