Proguard и всё, что с ним связано

Ответить
GRAF_COLLIOSTRO
Сообщения: 115
Зарегистрирован: 08 янв 2015, 14:32

Proguard и всё, что с ним связано

Сообщение GRAF_COLLIOSTRO » 14 мар 2016, 07:45

Столкнулся с проблемой обфускации. в итоге нарыл массу интересной инфы. Копирую сюда. Может кто чего дополнит или подправит.

КАК ЮЗАТЬ Proguard

Суть в том, что наш код в APK очень кривой непожатый и не обфускован. Eсть полезная штука - proguard, который решает эту проблему. Во-первых делает код не читаемым - и это очень полезно, чтобы вашему приложению не выкручивали руки нерадивые юзвери. Ну и самое главное то, что всё внутри Вашего APK сжимается и упорядочивается так, чтобы мало весило и быстро работало.

Как это вообще делается - инфы достаточно в нете: Просто при релизе в студии ставится галка (или задаётся в коде билда) minifyEnabled true.

В app build.gradle должна появиться вот такая запись:

Код: Выделить всё

  buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
#// - собстна два файла, первый - студия получит из SDK, а второй файлик настроек, в котором пишется что делать гварду с конкретными библиотеками или классами
            signingConfig signingConfigs.namecfg
        }
        debug {
            signingConfig signingConfigs.namecfg
        }
    }

Начнём с того, что обфусковывать сторонние библиотеки нет смысла - они есть в открытом доступе и получить их внутренности не проблема. (обфускацией же мы пытаемся добиться целостности и нечитабельности данных или не? ) - ну вот какбы не нужно это делать!

Пресловутая библиотека appcompat уже миллион раз добавлена в исключения самого прогварда (на сегодня проблема решена автоматоматом, её прогвард умеет корректно добавлять в апк), но если же есть желание написать руками это исключение, то правильно будет использовать вот такую запись:

-keep class android.support.v7.** {*;}

можно (а точнее НУЖНО) также исключить другие библиотеки (редактируем файл proguard-rules):

-dontwarn org.apache.http.**
-dontwarn android.net.http.AndroidHttpClient
-dontwarn com.google.android.gms.**
-dontwarn com.android.volley.toolbox.**

... ну и так далее, в зависимости от того, какие библиотеки использовали в проекте.

обратите также внимание, что строки тут комментируют знаком "#", так как это не JAVA:

Код: Выделить всё

# Add any project specific keep options here...
Интересный момент: никто не предупреждал, но Proguard ругается насчёт одинаковых имён классов, если в одной активити вы использовали класс Hallobaby, то в другой активити это имя юзать не следует. либо выносите его отдельно и используйте классические правила наследования, либо используйте уникальные имена внутри проекта. При упаковке Proguard будет всё сжимать и утрамбовывать и очень удивится когда обнаружит одинаковые имена классов. Это Вы знаете, где у Вас чего лежит, а для него это ошибка: что то типа "can't write resource (Duplicate zip entry [classes.jar:])"

Равно также нарвётесь на такую же ошибку и в самих ресурсах, даже если они лежат в разных папках:
Пример:

Есть файл dimens.xml в нём ресурс:

Код: Выделить всё

<bool name="makaka">true</bool>
А в файле strings.xml лежит:

Код: Выделить всё

<string name="makaka">makaka</string>
На момент дебага ошибки не возникает. В R.java это разные ресурсы. проблем нет так как, когда вы их выдёргиваете, то пишете явно тип нужного ресурса.
НО!!! Proguard попытается сжать эти ресурсы и произойдёт коллапс. имена то у них одинаковые.

Для дешифрации конечного продукта можно использовать соответствующую утилитку и сам файлик proguard-android.txt. без него дешифровать очень сложно.

Для редактирования и дебажирования проекта снимаем галку minify - можно прямо в билдере заменить "minifyEnabled true" на "minifyEnabled false".

Ответить