完全使用本机代码从后台线程更新UI(没有JNI)?

you*_*uri 5 c++ java-native-interface multithreading android android-ndk

我正在编写一个Android应用程序,它在后台线程中进行大量处理.使用C++在本机代码中执行计算.我想在计算过程中使用部分结果更新UI.

我能够通过JNI这样做,即在java中设置对UI对象的引用,然后通过JNI从本机代码调用此对象的方法.我正在寻找一个更有效的解决方案,在渲染部分没有任何JNI调用(基本设置和激活入口点必须在java中).

是否可以在不使用JNI的情况下完全使用本机代码将执行线程从后台更改为UI(仅在渲染部分中)?

谢谢你的回答.非常感激.

编辑: 我正在考虑使用OpenGL在我的视图中呈现计算内容(视频帧类型).在那种情况下,我可能想要使用eglSwapBuffers()从2.3开始的EGL库中可用的方法.我认为,最大的问题是如何在没有JNI开销的情况下轻松地从后台"计算"线程切换到本机代码中的UI"open GL"线程.你会推荐什么?谢谢你的帮助!

PSEUDOCODE: 这是一些伪代码,有助于说明我想在这里实现的目标.它更像是一个线程问题,但Android框架也会发挥作用.

// background thread
void Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz)
{
    //long calculation
    struct result * res = calculate();

    //want to update ui using opengl on ui thread
    updateGL(res);
}


//want to run it on ui thread as opengl can be run only on ui thread
void updateGL(struct result * res)
{
    //some opengl code with "res"
    someGLcodeWithResult(res);

    //render surface
    eglSwapBuffers();
}
Run Code Online (Sandbox Code Playgroud)

编辑2: 随着赏金缓慢逼近,再澄清一点.有几种方法可以调用updateGL上面的方法.最典型的是GLSurfaceView在java代码中使用.它需要设置一个渲染器(setRenderer()),然后用一些代码覆盖onDrawFrame来调用JNI/native层.这种方式为每个正在渲染的帧执行一次JNI调用.

我想以不同的方式进行渲染.我想在updateGL不使用java/JNI代码的情况下调用,只使用本机层(如上面的摘录中所示).我现在面临的最大问题是如何updateGL在没有java回调的情况下运行on UI线程(OpenGL需要).它完全可行吗?

Dir*_*irk 0

我现在面临着同样的问题。也许这可能有帮助:

当您查看最新 NDK 中的 STABLE-APIS.html 时,它会显示:

> 五、Android-9 稳定原生 API:

下面列出的所有 API 可用于开发在 Android > 2.3 系统映像及更高版本上运行的本机代码。

EGL图形库:

EGL 提供本机平台接口来分配和管理 OpenGLES 表面。有关其功能的更多信息,请参阅:

http://www.khronos.org/egl
Run Code Online (Sandbox Code Playgroud)

简而言之,这将允许您直接从本机代码执行以下操作:

- List supported EGL configurations
- Allocate and release OpenGLES surfaces
- Swap/Flip surfaces for display  (eglSwapBuffers)
Run Code Online (Sandbox Code Playgroud)

因此,如果您的目标是 Android-9,那么您可以尝试在本机代码中使用 EGL 库。(让我知道这个是否奏效 :))

  • 好吧,我想我有解决方案。您不必在 UI 线程中执行任何 GL。您只需确保所有事情都在一个线程中完成。在此线程中,您必须手动设置eglSurface/eglContext。eglSurface 的构造函数采用 SurfaceHolder 来表示您的表面,这会自动通知 ui 线程有关更改的信息。看看这个:http://e-university.wisdomjobs.com/net/chapter-924-288/using-android-3d-graphics-with-opengl-es.html 它解决了我的问题,我希望它有帮助;) (2认同)