Proguard и отражение в Android - PullRequest
       20

Proguard и отражение в Android

33 голосов
/ 15 декабря 2010

Я только что использовал proguard, но классы, которые я пытаюсь создать с помощью отражения, не работают.

У меня есть интерфейс

Algorithm

Я передаю такие классы

AlgorithmFactory.SomeClassThatExtendsAlgorithmImpl.class

Класс создается как этот

public ArrayList<Algorithm> getAlgorithms(Context cnx) {
ArrayList<Algorithm> list = new ArrayList<Algorithm>();

for(Class<? extends Algorithm> alg: algorithms) {

    try {
        Constructor<? extends Algorithm> c = alg.getConstructor(Context.class);
        list.add(c.newInstance(cnx));
    } catch (IllegalArgumentException e) {
        Log.e(TAG, "IllegalArgumentException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    } catch (InvocationTargetException e) {
        Log.e(TAG, "InvocationTargetException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    } catch (InstantiationException e) {
        Log.e(TAG, "InstantiationException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    } catch (IllegalAccessException e) {
        Log.e(TAG, "IllegalAccessException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    } catch (SecurityException e) {
        Log.e(TAG, "SecurityException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    } catch (NoSuchMethodException e) {
        Log.e(TAG, "NoSuchMethodException", e);
        throw new IllegalStateException("There was a problem creating the Algorithm class");
    }
}
return list;
}

Вот мой proguard.cnf

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService


-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
    public static *** i(...);
    public static *** w(...);
    public static *** e(...);
}

Ответы [ 3 ]

59 голосов
/ 16 декабря 2010

решено

Для других, у которых возникла эта проблема, вам необходимо добавить в proguard.cnf следующее:

-keep public class * extends com.yoursite.android.yourappname.YourClassName

-keepclassmembers class * extends com.yoursite.android.yourappname.YourClassName{
 public <init>(android.content.Context);
}

. Первое сохранение указывает proguard не запутывать имена классов, расширяющие YourClassName

Второй говорит, что имя конструктора (<init> означает конструктор) не обфусцируется, имеет единственный аргумент Context и расширяет YourClassName

Кроме того, для разработчиков Androidкоторые используют атрибут onClick в вашем файле XML-макетов , вам также необходимо добавить имя функции в ваш файл proguard.cnf.

-keepclassmembers class * {
 public void myClickHandler(android.view.View);
}

Это означает, что все методы должны называтьсяmyClickHandler с одним аргументом View во всех классах.Вы можете дополнительно ограничить это, используя ключевое слово extends, как указано выше.

надеюсь, это поможет.

18 голосов
/ 16 декабря 2010

Для исправления по клику вам не нужно указывать название каждого метода. Вы можете сделать:

-keepclassmembers class * {
   public void *(android.view.View);
}

, который находит все методы, которые имеют View как параметр.

0 голосов
/ 09 апреля 2019

Поскольку процесс компиляции удалит метод, который не используется, метод конструктора будет удален, даже если вы используете отражение для вызова в процессе компиляции.

Вы можете увидеть метод, который будет удален во время процесса компиляции, в файле use.txt в вашем проекте.

Так что вы должны оставить метод конструктора в файле proguard.

-keepclassmembers class * extends com.yoursite.android.yourappname.YourClassName{
 public <init>(android.content.Context);
}
...