Я только начинаю с JNI, и у меня возникла следующая проблема.
У меня есть библиотека C ++, которая имеет простой класс.У меня есть три метода JNI, вызванных из проекта Java Android, которые, инстанцируя указанный класс, вызывают метод инстанцированного класса и уничтожают его соответственно.Я сохраняю глобальную ссылку на этот объект, поэтому он будет доступен для меня в двух других методах JNI.
Я подозреваю, что не могу этого сделать.Когда я запускаю приложение, я получаю ошибку времени выполнения (используется устаревшая ссылка), и я подозреваю, что это происходит потому, что глобальная ссылка недопустима при последующих вызовах других методов JNI.
Это единственный способ добиться того, чтоЯ хочу (чтобы объект работал через несколько вызовов JNI), чтобы фактически передать обратно указатель на экземпляр класса обратно в Java, сохранить его там, а затем передать его обратно в функции JNI?Если это так, это нормально, я хочу убедиться, что я не могу сделать это с глобальной ссылкой, и я не просто что-то упустил.
Я прочитал документацию и главы о глобальных / локальных ссылках в JNI, но похоже, что это относится только к классам Java, а не к моим собственным, родным классам C ++, или я ошибаюсь.
Вот код, если мое описание неясно (резюмируя, мне интересно, будет ли вообще работать этот механизм сохранения объектов):
Java:
package com.test.ndktest;
import android.app.Activity;
import android.os.Bundle;
import android.app.AlertDialog;
public class NDKTestActivity extends Activity {
static {
System.loadLibrary("ndkDTP");
}
private native void initializeTestClass();
private native void destroyTestClass();
private native String invokeNativeFunction();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initializeTestClass();
String hello = invokeNativeFunction();
destroyTestClass();
new AlertDialog.Builder(this).setMessage(hello).show();
}
}
Заголовок JNI:
extern "C" {
jstring Java_com_test_ndktest_NDKTestActivity_initializeTestClass(JNIEnv* env, jobject javaThis);
jstring Java_com_test_ndktest_NDKTestActivity_destroyTestClass(JNIEnv* env, jobject javaThis);
jstring Java_com_test_ndktest_NDKTestActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis);
};
Тело JNI:
#include <string.h>
#include <jni.h>
#include <ndkDTP.h> //JNI header
#include <TestClass.h> //C++ header
TestClass *m_globalTestClass;
void Java_com_test_ndktest_NDKTestActivity_initializeTestClass(JNIEnv* env, jobject javaThis) {
m_globalTestClass = new TestClass(env);
}
void Java_com_test_ndktest_NDKTestActivity_destroyTestClass(JNIEnv* env, jobject javaThis) {
delete m_globalTestClass;
m_globalTestClass = NULL;
}
jstring Java_com_test_ndktest_NDKTestActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
jstring testJS = m_globalTestClass->getString();
return testJS;
}
Заголовок C ++:
class TestClass
{
public:
jstring m_testString;
JNIEnv *m_env;
TestClass(JNIEnv *env);
jstring getString();
};
Тело C ++:
#include <jni.h>
#include <string.h>
#include <TestClass.h>
TestClass::TestClass(JNIEnv *env){
m_env = env;
m_testString = m_env->NewStringUTF("TestClass: Test string!");
}
jstring TestClass::getString(){
return m_testString;
}
Спасибо