2015-09-18 141 views
0

我试图重构一些android jni代码。它最初设置为在JNI中使用静态变量,在Android端使用静态调用。我想改变这一点,以提高与其他代码的兼容性。android jni从静态方法到非静态方法

电流的方法签名

static jclass main_activity; 

static jmethodID on_init; 
static jmethodID on_update; 
static jmethodID on_render; 
static jmethodID on_exit; 
static jmethodID on_get_input; 

这些绑定是建立在这样的代码的开头:

main_activity = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls)); 

on_init = (*mEnv)->GetStaticMethodID(mEnv, main_activity, 
          "on_native_init","()V"); 
on_update = (*mEnv)->GetStaticMethodID(mEnv, main_activity, 
          "on_native_update","()V"); 
on_render = (*mEnv)->GetStaticMethodID(mEnv, main_activity, 
          "on_native_render","()V"); 
on_exit = (*mEnv)->GetStaticMethodID(mEnv, main_activity, 
          "on_native_exit", "()V"); 

然后在后面的代码,他们会使用这样的:

void Android_JNI_SwapEGLwindow(void) 
{ 
    JNIEnv *a_env = get_android_jni_env(); 
    (*mEnv)->CallStaticVoidMethod(a_env, main_activity, on_update); 
} 

由于此项目目前设置为存储主要活动和功能地址sses作为一个静态参考,只需拨打get_android_jni_env();即可访问获取当前的android jni环境。

如何重构此代码,以便能够获取实例而不是保持静态引用?

+0

即使您将MainActivity类中的这些方法设置为非静态,您仍然需要保留对MainActivity实例的全局引用。更糟糕的是,今天你可以在Java中保留这个引用,但是现在你也需要在你的本地代码中知道它。 –

回答

1

只需将一个静态方法添加为“getInstance()”来检索类main_activity的对象,然后就可以使用该对象来调用非静态方法。

jmethodID midGetInstance = (*env)->GetStaticMethodID(env, main_activity_class, "getInstance", "()Lcom/package/yourapp/MainActivity;"); 
jobject main_activity_obj = (*env)->CallStaticObjectMethod(env, main_activity_class, midGetInstance); 
...NewGlobalRef(main_activity_obj); 

其中main_activity_class与您的原始jclass main_activity相同。

在Java方面,你需要

onCreate(...) {mInstance = this;...} 
public static MainActivity getInstance() {return mInstance;} 

然后你可以使用main_acitivty_obj访问非静态方法。