Monodroid JNI for Java reflection to call a private method

筅森魡賤 提交于 2019-12-08 12:33:10

问题


In a Monodroid project, I need to be able to call a private method on a class. From an answer on a related question, it seems that this is possible in Java via reflection:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.os.ParcelFileDescriptor;

...

ParcelFileDescriptor pipe[] = null;

try {
    Method createPipeMethod = ParcelFileDescriptor.class.getDeclaredMethod("createPipe");
    pipe = (ParcelFileDescriptor[]) createPipeMethod.invoke(null);
} catch (NoSuchMethodException e) {
    throw new RuntimeException(e);
} catch (IllegalAccessException e) {
        throw new RuntimeException(e);
} catch (InvocationTargetException e) {
    throw new RuntimeException(e);
}

I need to use this code from Monodroid. Unfortunately, java.lang.reflect is not available in Monodroid. However, it has been suggested that I can run this code using JNI from my Monodroid project. The Xamarin documentation states that inline JNI is possible, without having to bind a whole JAR. Unfortunately, further documentation doesn't say anything more on the subject. Furthermore, the documentation on JNIEnv is blank.

It looks like I need JNIEnv.CallVoidMethod(), but I have no idea how to do it. I can't find an example, or further documentation.

How can I use java.lang.reflect in my Monodroid project, or in some other way call the private method .createPipe on ParcelFileDescriptor?


回答1:


Did you try to use C# reflection on Android.OS.ParcelFileDescriptor?

http://docs.mono-android.net/index.aspx?link=T%3AAndroid.OS.ParcelFileDescriptor

I did not yet try it, but if Mono for Android even wraps private members of a Java class, simply using C# reflection might be enough.

If this failed, you can pursue on the JNI attempt.




回答2:


It should be possible with JNI: http://docs.xamarin.com/guides/android/advanced_topics/java_integration_overview/working_with_jni#_Static_Methods

A rough untested sketch:

var methodId = JNIEnv.GetStaticMethodID(ParcelFileDescriptor.Class.Handle, 
                                        "createPipe", 
                                        "()[Landroid/os/ParcelFileDescriptor;");
var result = JNIEnv.CallStaticObjectMethod(myCSharpFileDescriptorInstance.Handle,
                                           methodId);


来源:https://stackoverflow.com/questions/12612975/monodroid-jni-for-java-reflection-to-call-a-private-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!