Итак, у меня есть класс данных Kotlin, используемый в качестве объекта передачи данных с библиотекой Retrofit, следующим образом:
data class GenericPaginationResponse<T>(
@SerializedName("data")
val data: List<T>,
@SerializedName("pagination")
val pagination: PaginationResponse
)
Однако, когда я минимизирую приложение, оно обнаруживает ошибку при выполнении со следующим сообщением:
Невозможно вызвать конструктор без аргументов для класса com.lelestacia.network.model.GenericPaginationResponse. Регистрация InstanceCreator с Gson для этого типа может решить эту проблему.
Я использую этот класс данных в сетевом модуле проекта Android с многомодульной архитектурой. Вот репозиторий: Github Repository
Вот мой прогард:
# If you keep the line number information, uncomment this to
# hide the original source file name.
-renamesourcefileattribute SourceFile
# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
-if class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keep class <1> {
<init>();
}
да, извините, я забыл включить свои настройки proguard в вопрос. Я обновил его сейчас
Вам нужно добавить атрибут keep для моделей данных, которые вы создаете в своем проекте.
-keep class com.lelestacia.network.model.GenericPaginationResponse { <fields>; } я поставил их на свои прогарды, но проблема все равно не решается. И у него также есть такое же сообщение об ошибке
Не могли бы вы также включить сообщения о причинах исключений? Трассировка стека должна содержать один или несколько Caused by: ...
В вашем сетевом модуле есть файл consumer-rules.pro
Добавьте ниже код
-keep class com.lelestacia.network.model.*
-keep class com.lelestacia.network.model.anime.*
Также в вашем build.gradle
сетевого модуля в типе сборки релиза добавьте код ниже
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'consumer-rules.pro'
Вы можете перейти по ссылке ниже для consumer-rules
против proguard-rules
https://stackoverflow.com/a/60862591/8007341
Итак, я никак не мог запутать это?
давайте предположим, что вы хотите запутать код сетевого модуля. Весь код/файл/метод будет запутан, и все будет работать без проблем для этого сетевого модуля. Это означает, что весь код внутри сетевого модуля будет работать после обфускации. Но проблема возникает, когда вы хотите поделиться pojo/классами для сетевого модуля с другими модулями. Теперь, когда весь код запутан, другие модули этого не поймут и начнут выдавать ошибку во время выполнения. Чтобы решить эту проблему, вы должны использовать правила proguard, которые будут запутывать весь код/файлы, кроме упомянутых файлов внутри правил.
Если вы напишете весь свой код в одном модуле (приложении), тогда обфускация будет работать правильно. В многомодульном проекте, если вы хотите запутать каждый модуль, вам нужно использовать правила proguard/consumer. Каждый модуль будет работать правильно по отдельности, но при совместном использовании данных/использовании друг друга возникает проблема, если вы используете обфускацию/минимизацию.
у вас есть ссылка, чтобы узнать все это? Я немного потерялся в вашем объяснении
Вы должны указать ниже код в правилах proguard.
-keepclasseswithmembers class com.lelestacia.network.model** { *; }
Не стесняйтесь спрашивать, если что-то непонятно.
Итак, я никак не мог запутать это?
Второй вариант — использовать аннотацию для каждого класса данных @Keep
. Например @Keep data class GenericPaginationResponse<T>( @SerializedName("data") val data: List<T>, @SerializedName("pagination") val pagination: PaginationResponse )
Итак, я действительно не знаю об обфускации в отраслевых приложениях, так как я никогда не работал над реальным проектом, подобным этому. Но действительно ли это нормально, чтобы класс данных, как в этом случае, не запутывался? Не стало ли проще, если кто-то захотел заняться реверс-инжинирингом? или нам на самом деле не нужно запутывать все, например, мы можем просто позволить нашему DTO не запутаться. Я был бы очень признателен, если бы вы захотели объяснить это
вы настроили правила pro guard?