我有一个带有本地代码的Android应用程序。如何在调用本机方法之间保持对对象的引用?
// 1: create native object and hold it
Object obj = jni_wrapper.native_getObject();
// ... do smth
// 2: return an object back to native code
Object result = jni_wrapper.native_doSmthWithObject(obj);
因此,代码需要保存对对象的引用,并以某种方式找到它(在上面的示例中,在1:和2:之间)。我可以创建自己的类和特殊实例字段(如果需要的话)来保存引用。
我使用了下一个解决方案(只在Index对象的“指针”实例字段中保持指向实例的指针),但它似乎不起作用。
Java (Index.java):
/**
* CXIndex
*/
public class Index {
private long pointer;
public long getPointer() {
return pointer;
}
}
本地代码:
// index
static jclass IndexClass;
static jmethodID IndexConstructor;
static jfieldID IndexPointerField;
void bindIndex(JNIEnv *env)
{
IndexClass = env->FindClass("name/antonsmirnov/xxx/dto/Index");
IndexConstructor = env->GetMethodID(IndexClass, "<init>", "()V");
IndexPointerField = env->GetFieldID(IndexClass, "pointer", "J");
}
// map CXIndex
jobject mapIndex(JNIEnv *env, CXIndex *index)
{
if (IndexClass == NULL)
bindIndex(env);
jobject obj = env->NewObject(IndexClass, IndexConstructor);
jlong jpointer = reinterpret_cast<jlong>(index);
env->SetLongField(obj, IndexPointerField, jpointer);
return obj;
}
// map Index -> CXIndex
CXIndex unmapIndex(JNIEnv *env, jobject jindex)
{
if (IndexClass == NULL)
bindIndex(env);
jlong jpointer = env->GetLongField(jindex, IndexPointerField);
CXIndex *ptr = reinterpret_cast<CXIndex*>(jpointer);
return *ptr;
}
这涉及到Android,它可以带来特定的行为!
发布于 2013-10-04 14:40:37
您可以创建一个函数
jlong JNI_mypackage_myclass_createMyNativePeer() {
return new MyNativePeer();
}
然后,在Java中,将返回的值保留在类中。
class MyWrapper {
private long mPeer;
public void createPeer() {
mPeer = createMyNativePeer();
}
private native long createMyNativePeer();
public void controlPeer(int param) {
controlPeer(mPeer, param);
}
private native void controlPeer(long peer, int param);
}
然后将该值传递给您的控制函数:
jvoid JNI_mypackage_myclass_controlPeer(jlong peer, int someParam) {
((*MyNativePeer)peer)->doSomething(param);
}
发布于 2017-06-20 04:12:15
这里至少有两个问题。
jobject
或jclass
的静态引用。要做到这一点,需要一个GlobalRef
或WeakGlobalRef
。GetClass()
、GetMethodID()
、GetFieldID()
、GetLongField()
等的结果,也必须检查挂起的异常。但是我不明白你为什么需要这个。第一个解决方案要简单得多,可以通过在公共Java方法中封装私有本机方法来实现,这些方法调用私有方法并自动提供所需的对象,其中对象可以存储在具有本机方法的类中。
https://stackoverflow.com/questions/19183849
复制相似问题