2015-09-21 2 views
1

Я работаю с SDL, и я почти разобрал все проблемы, которые у меня есть.Android JNI и NewGlobalRef

Я делаю 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, так как андроид контролирует жизненный цикл приложения, который ref заставит мое приложение «возобновиться», даже если я пытаюсь выйти.

Если я попытаюсь очистить этот globalref чем-то вроде DeleteLocalRef, приложение все же, похоже, хочет возобновить работу вместо того, чтобы уйти. Есть ли способ остановить это поведение?

Другой вопрос: возможно ли создать нестационарную функцию JNI, которая будет вызвана со стороны c кодового мира, чтобы я мог получить экземплярное задание и использовать его для захвата экземпляра класса?

Например, как правило, вы пишете функцию в Java:

public native void do_c_work(); 

на СТОРОНА С:

void Java_com_test_java_do_c_work(JNIEnv* env, jobject inst) 
{ 
    ...use the instance do your work 
} 

Что делать, если некоторые функции вызываются на с-стороны, что я хотел бы получить экземпляр из java, чтобы что-то сделать.

с функцией:

public int get_number(); 

Я немного застрял здесь, я не хочу, чтобы создать экземпляр нового объекта Java в данный момент, в основном потому, что i saw this и кажется излишним.

Должен быть способ преодолеть это препятствие, будь то возможность вызова в java из c без использования статического или создания нового действия, там уже есть или освобождение globalref, но это, похоже, не работает так хорошо для меня в этот момент.

ответ

-1

Какова цель проведения GlobalRefjclass? Если это так, вы можете получить methodIDs, получить их сейчас в этом коде и сохранить их. Они - только ints, а не ссылки на объекты, так что вам не нужно GlobalRef ничего.

+0

Я получаю задания с этим ref, мне нужно получить контекст приложения, который является заданием, а также jmethodID, ex: jmethodID mid = (* env) -> GetStaticMethodID (env, mActivityClass, "getContext", "() Landroid/содержание/контекст; "); | контекст jobject = (* env) -> CallStaticObjectMethod (env, mActivityClass, mid); – user1610950

0

Несколько замечаний:

  1. JNI глобальные ссылки не заставляйте приложение, чтобы оставаться открытым. Сборщик мусора знает о них, но инфраструктура приложения, которая управляет жизненным циклом, не является. Существует множество глобальных ссылок, созданных самой платформой приложений. (Приложения не выбраны «мусор».)

  2. Если вы хотите удалить глобальную ссылку, используйте DeleteGlobalRef, а не DeleteLocalRef.

  3. Если вы хотите вызывать нестатические методы Java-языка из C, передайте Object на собственный код и invoke a method. Создайте глобальную ссылку для задания, если вы собираетесь использовать его после того, как собственный метод вернется к виртуальной машине. (Я чувствую, что, возможно, я не понимая эту часть вопроса.)

Смотрите также JNI Tips и JNI spec.

Смежные вопросы