2014-11-18 3 views
2

Меня зовут Мэтью, и у меня есть проблемы с отражением на Android после использования ProGuard.ProGuard на Android + reflection = NoSuchFieldException

Я пишу игру в libgdx и мне нужно динамически получить строку, у меня есть что-то вроде этого:

package com.PACKAGE; 

    public class CLASS extends ANOTHER_CLASS{ 

     (...) 

    private static void load(String fieldName) { 
     Field field; 
     String fileName; 
     try { 
      field = SOME_CLASS.class.getField(fieldName); 
      fileName = (String) field.get(null); 
     } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 
      throw new RuntimeException(e); 
     } 

     SOME_CLASS.SOME_METHOD.load(fileName); 

    } 

(...) 

    private STH get(String fieldName) { 
     Field field; 
     String fileName; 
     try { 
      field = SOME_CLASS.class.getField(fieldName); 
      fileName = (String) field.get(null); 
     } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 
      throw new RuntimeException(e); 
     } 

     return SOME_CLASS.SOME_METHOD.get(fileName); 

    } 

(...) 

} 

После экспортировать релиз APK (компилировать штраф) и запустить игру, я получаю NoSuchFieldException:

java.lang.RuntimeException: java.lang.NoSuchFieldException: FIELD_NAME

Что мне нужно добавить в proguard-project.txt т o справиться с этим? Это не работает, я понятия не имею, что делать.

-keepclassmembers class com.PACKAGE.CLASS { 
    String fileName; 
} 

класс выглядит следующим образом:

package com.ANOTHER_PACKAGE; 
public class SOME_CLASS { 
    public static final String fieldName1 = "string I want"; 
    public static final String fieldName2 = "string I want"; 
    public static final String fieldName3 = "string I want"; 
} 

UPDATE:

Благодаря @Selvin, ответ был

-keepclassmembers class ANOTHER_PACKAGE.SOME_CLASS { 
    public static final <fields>; 
} 

в project-proguard.txt. Сейчас он работает отлично :)

+0

первый, почему вам нужен отражение для этого. во-вторых, не должен ли он быть классом '-keepclassmembers com.PACKAGE.SOME_CLASS' – Selvin

+0

Мне нужно отражение, чтобы избежать написания кучи кода, но, возможно, это была не очень хорошая идея. SOME_CLASS находится в другом пакете, и мне нужно больше полей String, поэтому мне нужно написать все из них, которые можно использовать с помощью отражения? -keepclassmembers класс com.ANOTHER_PACKAGE.CLASS { Строка fileName1; Строка fileName2; Строка fileName3; } – miecio

+0

так что SOME_CLASS от libgdx? does fileName статично? знаете ли вы, что 'field.get (null)' для статических членов? (я знаю, что ошибки здесь нет), вам нужно передать экземпляр SOME_CLASS вместо null, чтобы получить нестационарное поле ... – Selvin

ответ

0

Попробуйте в файле proguard.cnf

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

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

Ref: Proguard and reflection in Android