我正在使用SDL,而且我几乎整理了我遇到的所有问题。
我正在进行jni调用以初始化框架,然后从中创建一个全局引用,因为这是我现在能想到的最佳方式。
我的大多数JNI函数都使用实例变量来读取文件除外。 这就是我设置globalref的方式。
JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv* mEnv, jobject instance)
{
Android_JNI_SetupThread();
mInstance = instance;
jclass clazz = (*mEnv)->GetObjectClass(mEnv, instance);
mActivityClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, clazz));
.....
}
我只在这段代码中两次使用这个mActivityClass全局引用来读取一些可以随时调用的函数。
主要问题,专门针对Android JNI。如果我坚持使用globalref,因为android控制它的应用程序的生命周期,ref会导致我的应用程序恢复"即使我试图戒烟。
如果我尝试使用类似DeleteLocalRef
的内容清除globalref,那么该应用似乎仍然希望恢复而不是退出。有没有办法阻止这种行为?
另一个问题是,是否可以创建一个非静态JNI函数,该函数可以从代码世界的c方面调用,这样我就可以获得一个实例jobject并使用它来获取类实例
例如,通常你在java中编写一个函数:
public native void do_c_work();
在c方面:
void Java_com_test_java_do_c_work(JNIEnv* env, jobject inst)
{
...use the instance do your work
}
如果某些函数在c方面被调用,我想从java获取一个实例来做什么怎么办。
c功能:
public int get_number();
我有点卡在这里,我不想在这一点上实例化一个新的java对象,主要是因为i saw this而且看起来有点矫枉过正。
必须有一种方法可以克服这个障碍,要么能够在不使用静态或创建新活动的情况下从c调用java,那里已经有一个或者释放了globalref,但是并没有这样做。在这一刻,我似乎对我这么好。
答案 0 :(得分:0)
一些注意事项:
JNI全球参考不会强制您的应用保持开放状态。垃圾收集器知道它们,但控制生命周期的应用程序框架却没有。应用程序框架本身创建了大量全局引用。 (应用程序不是“垃圾收集”。)
如果您要删除全局参考,请使用DeleteGlobalRef
,而不是DeleteLocalRef
。
如果要从C调用非静态Java语言方法,请将Object传递给本机代码,并将invoke a method传递给它。如果在本机方法返回VM后将要使用它,请为jobject创建全局引用。 (我觉得我可能不理解这部分问题。)
答案 1 :(得分:-1)
将GlobalRef
保存到jclass
的目的是什么?如果只是这样你可以得到methodIDs
,现在就在这段代码中获取它们并存储它们。它们只是整数,而不是对象引用,因此您不必GlobalRef
任何东西。