3

Me name is Matthew and i have some trouble with reflection on Android after i use ProGuard.

I'm writing game in libgdx and I need to dynamically get String, I have something like this:

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);

    }

(...)

}

After I export release apk (compile fine) and run game, I get NoSuchFieldException:

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

What I need to add in proguard-project.txt to handle this? This is not working, I have no clue what to do.

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

class looks like:

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:

Thanks to @Selvin, the answer was

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

in project-proguard.txt. Now it works perfectly :)

miecio
  • 315
  • 1
  • 4
  • 19
  • 1
    first why do you need a reflection for this. second, shouldn't it be `-keepclassmembers class com.PACKAGE.SOME_CLASS` – Selvin Nov 18 '14 at 12:53
  • I need reflection to avoid write bunch of code, but maybe it was not a good idea. SOME_CLASS is in another package and there is more String fields I need to get, so I need to write all of them which it could be used via reflection? -keepclassmembers class com.ANOTHER_PACKAGE.CLASS { String fileName1; String fileName2; String fileName3; } – miecio Nov 18 '14 at 13:02
  • so SOME_CLASS is from libgdx ? does fileName is static? do you know that `field.get(null)` is for static members? (i know that the error is not here but) you need to pass instance of SOME_CLASS instead null to get the non static field ... – Selvin Nov 18 '14 at 13:10
  • Not from, but I use it in "core" section when you write in clean Java, not in "Android" section. Yes all String I try get are static. – miecio Nov 18 '14 at 13:17

1 Answers1

0

Try this in your proguard.cnf file

-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

Community
  • 1
  • 1
SubinM
  • 394
  • 3
  • 7