Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android NDK对Java活动的回调_Java_Android_Callback_Android Ndk_Native - Fatal编程技术网

Android NDK对Java活动的回调

Android NDK对Java活动的回调,java,android,callback,android-ndk,native,Java,Android,Callback,Android Ndk,Native,我正在移植我的一个应用程序,因此大部分工作都是在应用程序的本机部分完成的,Java端完全是为我的UI设计的 我现在尝试实现的是一个ProgressBar,它将显示本机线程操作的状态。UI由不同的活动组成,我打算显示这些活动的进度条 jmethodID ProgressUpdateFromNative = env->GetMethodID( clazz, "ProgressUpdateFromNative", "(I)V"); env->CallObjectMethod( g_pObj

我正在移植我的一个应用程序,因此大部分工作都是在应用程序的本机部分完成的,Java端完全是为我的UI设计的

我现在尝试实现的是一个ProgressBar,它将显示本机线程操作的状态。UI由不同的活动组成,我打算显示这些活动的进度条

jmethodID ProgressUpdateFromNative = env->GetMethodID( clazz, "ProgressUpdateFromNative", "(I)V");
env->CallObjectMethod( g_pObj, ProgressUpdateFromNative, 1 ) ;
问题是:我该怎么做?我有一些本机代码,如下所示:

jclass clazz = emv->FindClass( "com/example/myapp/MainActivity" );
它为clazz返回null。我意识到当时实际上没有显示MainActivity活动-这是我的SettingsActivity的一个实例,所以我尝试相应地更改上面的行,但它仍然返回null

无法从本机代码调用FindClass()来检索活动类吗

最终,我认为我需要做的是调用如下方法:

  public void ProgressUpdateFromNative( int i )
  {
    runOnUiThread( new Runnable()
    {
      @Override
      public void run()
      {
        DisplayProgressUpdate();
      }
    } );
  }
…这是我活动中的一种方法

jmethodID ProgressUpdateFromNative = env->GetMethodID( clazz, "ProgressUpdateFromNative", "(I)V");
env->CallObjectMethod( g_pObj, ProgressUpdateFromNative, 1 ) ;
我已经从onLoad()JNI调用中检索到JavaVM指针,并调用JavaVM->AttachCurrentThread()来检索上面使用的环境指针

有人能告诉我我遗漏了什么吗?比如,为什么我要从FindClass返回null类,或者如果我做的完全错误,就把我放在另一条轨道上。我也打算读一些关于操纵者的书,但我认为我的理解还不太透彻


注意:我确实意识到我可以从Java UI轮询一些本机变量,但我更喜欢回调/事件处理实现,而不是轮询。

如果您的代码不是从Java方法调用的,它将使用
FindClass()
中的系统类加载器,它只知道Android系统类

我建议在
JNI_OnLoad
中获取类的引用,通过
NewGlobalRef
创建对该类的全局引用,并将其传递给线程或存储在全局变量中


有关此行为的更多信息:

调用
FindClass()
调用的本机代码如何?@Hans Kratz:我有一个pthread运行处理从Java活动发送到本机线程的消息。本机线程在一个循环中连续运行,并处理它从JavaUI获得的任何消息。查看我的NDK食谱,我注意到在OnLoad()函数中的main活动上调用了FindClass()。我不知道NewGlobalRef做了什么,但我会做一些阅读和搜索。在JNI中对Java对象(如类)的引用通常只有在获取它们的框架是生命的情况下才有效。为了延长生命周期,您需要创建对它的全局引用。请注意,这将防止对创建全局引用的对象进行垃圾收集。这就是为什么当你通过
DeleteGlobalRef
处理普通对象时,删除引用非常重要的原因。@Hand Kratz:谢谢你。所以,如果我要获得一个活动的全局引用,这将是一件非常糟糕的事情,不是吗?我的MainActivity将始终保持不变,但如果设备被旋转,那么它将被重新创建-因此我最终将有两个Activity对象保持不变,对吗即使只有一个活动是有效的和最新的。我之前想知道,无论何时(重新)创建活动,是否有可能以某种方式用我的本机代码“注册”该活动?确保可以通过活动的
onResume()
方法中的JNI调用本机方法来设置当前活动。在本机代码中,您可以删除旧的全局引用(如果它不为null),并为新活动创建新的全局引用。但是:我建议您从本机代码中调用静态方法,并用Java进行所有进一步的处理。通过这种方式,您可以避免使用NewGlobalRef/DeleteGlobalRef内容,除了对jclass的引用。