0

I have three functions: getMeses(), getDias() and getHoras(), these functions I want to call or invoke them from a Map like myMap.get("meses").invoke and it calls the getMeses() function.

I'm trying using this explain the Hack Reflection one.

But when execute the *.invoke method an error appears:

02-20 13:36:01.153 27778-27778/com.urbanclouds.finntime E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.urbanclouds.finntime, PID: 27778
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.urbanclouds.finntime/com.urbanclouds.finntime.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2543)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2609)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1465)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5683)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference
at com.urbanclouds.finntime.MainActivity.onCreate(MainActivity.java:39)
at android.app.Activity.performCreate(Activity.java:6270)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2609) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1465) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:207) 
at android.app.ActivityThread.main(ActivityThread.java:5683) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

This method can't be use on Android? If not, how can I do what I want?

This is my actual code:

String time_data_keys[] = {"meses", "dias", "horas"};
HashMap<String, TextView> time_data;

@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    int id;

    time_data = new HashMap<>();

    for ( String key : time_data_keys) {
        id =  getResources().getIdentifier(key,"id",getApplication().getPackageName());
        time_data.put(key, (TextView) findViewById(id));
    }

    Map<String, Method> methodMap = new HashMap<>();

    try {
        methodMap.put("meses", MainActivity.class.getMethod("getMeses"));
        //methodMap.put("dias", MainActivity.class.getMethod("getDias"));
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
/*
    try {
        methodMap.get("meses").invoke(null);
    } catch (IllegalAccessException | InvocationTargetException e) {
        e.printStackTrace();
    }
*/
    time_data.get("meses").setText(getMeses());
    //time_data.get("dias").setText(getDias());
    //time_data.get("horas").setText("Horas: %128:%32:%17");
}

private String getMeses() {

    // some stuff
    int num_meses = 2;
    String meses = String.valueOf(num_meses);

    Log.i("getMeses()", "He conseguido entrar!!");

    return getResources().getString(getResources().getIdentifier("meses","string",getApplication().getPackageName()))
            .replace("%m",meses);
}

EDIT: Using this instead of null have the same result

Community
  • 1
  • 1
Josete Manu
  • 187
  • 2
  • 16
  • 1
    I think you are looking for `methodMap.get("meses").invoke(this);` - invoke needs an object parameter. You can only pass `null` if the method is `static`. – Kenney Feb 20 '16 at 12:59
  • 1
    invoke with null is for static methods... In other case you need object from which this method should be called... – Selvin Feb 20 '16 at 13:03
  • So I need to create an object just for call that function on that way? Using this instead of null get the already NullPointer Exception – Josete Manu Feb 20 '16 at 13:04
  • Kenney the problem isn't what is a null pointer is why it produced on my project. – Josete Manu Feb 21 '16 at 10:46

1 Answers1

0

Ok, thanks for Selvin I create a new object and then I can do what I want:

private class MisMetodos {

    public String getMeses() {

        // some stuff
        int num_meses = 2;
        String meses = String.valueOf(num_meses);

        Log.i("getMeses()", "He conseguido entrar!!");

        return getResources().getString(getResources().getIdentifier("meses","string",getApplication().getPackageName()))
                .replace("%m",meses);
    }

    public String getDias() {
        // some stuff
        int num_dias = 32;
        String dias = String.valueOf(num_dias);

        return getResources().getString(getResources().getIdentifier("dias","string",getApplication().getPackageName()))
                .replace("%m",dias);
    }
}

And use the Reflection this way:

MisMetodos metodos = new MisMetodos();

try {
    methodMap.put("meses", MisMetodos.class.getMethod("getMeses"));
    //methodMap.put("dias", MainActivity.class.getMethod("getDias"));
} catch (NoSuchMethodException e) {
    e.printStackTrace();
}

try {
    methodMap.get("meses").invoke(metodos);
} catch (IllegalAccessException | InvocationTargetException e) {
    e.printStackTrace();
}
Josete Manu
  • 187
  • 2
  • 16