Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating UI from background thread using native code entirely (no JNI)?

I am writing an Android application that does much of a processing in the background thread. The calculations are performed in the native code using C++. I want to update UI with the partial results during calculations.

I am able to do so through JNI, namely set reference to UI object in java and then call a method of this object from native code trough JNI. I am looking for a more efficient solution without any JNI calls in the rendering part (the basic setup and an activation entry point will have to be in java).

Is it possible to change execution thread from background to UI entirely in native code without using JNI (only in the rendering part)?

Thanks for your answers. Much appreciated.

EDIT: I am considering using OpenGL to render calculated content (sort of video frames) in my view. In that case I would probably want to use eglSwapBuffers() method that is available in EGL library from 2.3 onwards. The biggest problem is, I think, how to easily switch from background "calculation" thread to UI "open GL" thread in native code without JNI overhead. What would you recommend? Thanks for your help!

PSEUDOCODE: Here is some pseudocode that helps to illustrate what I want to achieve here. It is more like a threading issue but Android framework comes into play as well.

// 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();
}

EDIT 2: As the bounty slowly draws to close, one more clarification. There are couple of ways to call the updateGL method above. The most typical one is to use GLSurfaceView in java code. It would require setting a renderer (setRenderer()) and then overriding onDrawFrame with some code to call JNI/native layer. This way for every frame being rendered one JNI call gets executed.

I would like to do the rendering a little differently. I want to call updateGL without using java/JNI code at all and use only the native layer (as presented in the excerpt above). The biggest problem for me now is how to run the updateGL on UI thread (required by OpenGL) without the java callback. Is it at all feasible?

like image 973
youri Avatar asked Dec 29 '11 11:12

youri


2 Answers

I suggest taking a look at the Mozilla Fennec source. There is a minimal Java/JNI shim that allows rendering on Android, but all the work is done via native code (regular ol' Mozilla code)

like image 169
NuSkooler Avatar answered Nov 07 '22 02:11

NuSkooler


Great thoughts, but try and understand this thing

  1. You have code in C++ in native
  2. UI in java runs in VM

Now what you are asking is C++ code to interact with UI in Java VM which is another program to communicate. The only way to do it would be some interprocess communication. Having said that, now go figure that out which suits you best. JNI is fast and reliable, since u dont want to go that way, figure out any other IPC that suits you.

like image 26
the100rabh Avatar answered Nov 07 '22 02:11

the100rabh