Как сохранить java.lang.reflect при использовании proGuard? - PullRequest
0 голосов
/ 27 июня 2018

В моем приложении я хочу использовать эту библиотеку : https://github.com/xmuSistone/AndroidPileLayout

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

Для исправления proguard разработчик библиотеки говорит:

proguard работает неправильно, когда вы используете java.lang.reflect api, пожалуйста проверьте свой код.

Мои правила защиты:

#--------Glide--------
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}
#--------Glide transformations--------
-dontwarn jp.co.cyberagent.android.gpuimage.**
#--------Retrofit--------
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-dontwarn com.squareup.retrofit2.**
-dontwarn retrofit2.Platform$Java8
#--------Gson--------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
#--------ButterKnife--------
# Retain generated class which implement Unbinder.
-keep public class * implements butterknife.Unbinder { public <init>(**, android.view.View); }
# Prevent obfuscation of types which use ButterKnife annotations since the simple name
# is used to reflectively look up the generated ViewBinding.
-keep class butterknife.*
-keepclasseswithmembernames class * { @butterknife.* <methods>; }
-keepclasseswithmembernames class * { @butterknife.* <fields>; }
#--------MyCustomViews--------
-keep class com.app.app.view.** { *; }
-keep class com.app.app.api.models.** { *; }
-keep class java.lang.reflect.** { *; }
-keepclassmembers public class java.lang.reflect.**

Как я могу это исправить и сохранить java.lang.reflect?

Пожалуйста, помогите мне

Пожалуйста, помогите мне

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Причины возникновения исключений во время выполнения могут различаться в зависимости от кода, который вы реализовали. Одной из причин получения исключения может быть использование имен полей / классов / методов в вашем коде с использованием отражения - ProGuard переименовывает ваши классы, запутывая их, поэтому для того, чтобы они были доступны после запутывания, их необходимо явно запретить из-за запутывания .

-keep app.package.FancyClass { *; } 

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

Самый простой вариант - сохранить всю библиотеку:

-keep com.stone.pile.** { *; } 

но вы очень часто можете настроить ProGuard на более агрессивный режим. Тем не менее, это хорошая отправная точка.

Я думаю, -keep java.lang.reflect.** правило здесь не сильно помогает. Основная причина в коде, который опирается на внутренние классы, которые должны быть исключены из запутывания.

Найдите уязвимый код и постарайтесь сохранить доступ к классам / методам / внутренним объектам с помощью отражения.

EDIT: Было бы очень полезно, если бы вы вставили файл класса в место, где указано исключение. Сообщение об исключении также добавляется в контекст. Можете ли вы сделать это, пожалуйста?

0 голосов
/ 27 июня 2018

Проблема не в том, что вам нужно хранить классы в java.lang.reflect, а в том, что где-то в вашем коде отражение используется для загрузки, доступа и, возможно, изменения классов во время выполнения.

Поскольку ProGuard и другие обфускаторы переименовывают ваши классы, чтобы усложнить реверс-инжиниринг, иметь жестко закодированное имя класса в строке может не получиться. Например, рассмотрим этот код:

com.acme.Acme acme = Class.forName("com.acme.Acme").newInstance();

Теперь учтите, что после запуска Proguard на com.acme.Acme его можно было переименовать в a.a.A. Код будет эффективно читать:

a.a.A acme = Class.forName("com.acme.Acme").newInstance();

Это приведет к ClassNotFoundException во время выполнения, поэтому ProGuard выдаст предупреждение или ошибку в зависимости от его конфигурации.

Решение состоит в том, чтобы тщательно выяснить, можете ли вы использовать отражение в своем собственном коде и где вы можете использовать его, можете ли вы избежать такого отражения, можно ли его игнорировать или нужно ли сохранять классы, которые отражаются при . В моем примере выше вы можете избежать проблем, указав -keepnames com.acme.Acme. Если для обучения членов класса используется отражение, вам может понадобиться рассмотреть -keep весь класс и всех его членов.

Но, по сути, по определению запутывание и отражение не очень хорошо сочетаются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...