Я пишу приложение для Android, которое выполняет большую часть обработки в фоновом потоке. Расчеты выполняются в собственном коде с использованием C ++. Я хочу обновить пользовательский интерфейс с частичными результатами во время расчетов.
Я могу сделать это через JNI, а именно установить ссылку на объект пользовательского интерфейса в Java, а затем вызвать метод этого объекта из нативного кода через JNI. Я ищу более эффективное решение без каких-либо вызовов JNI в части рендеринга (базовая настройка и точка входа активации должны быть в java).
Можно ли полностью изменить поток выполнения из фона в пользовательский интерфейс в собственном коде без использования JNI (только в части рендеринга)?
Спасибо за ваши ответы. Очень признателен.
EDIT:
Я рассматриваю возможность использования OpenGL для визуализации рассчитанного контента (вроде видеокадров) в моем представлении. В этом случае я бы, вероятно, хотел бы использовать метод eglSwapBuffers()
, который доступен в библиотеке EGL начиная с версии 2.3. Я думаю, что самая большая проблема заключается в том, как легко переключиться с фонового потока «вычислений» на поток «открытых GL» пользовательского интерфейса в собственном коде без затрат JNI. Чтобы вы посоветовали? Спасибо за вашу помощь!
ПСЕВДОКОД:
Вот некоторый псевдокод, который помогает проиллюстрировать, чего я хочу достичь здесь. Это больше похоже на многопоточность, но в игру вступает и 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();
}
РЕДАКТИРОВАТЬ 2:
Поскольку щедрость медленно приближается, еще одно уточнение. Есть несколько способов вызвать метод updateGL
выше. Наиболее типичным является использование GLSurfaceView
в коде Java. Для этого потребуется установить средство визуализации ( setRenderer () ), а затем переопределить onDrawFrame с некоторым кодом для вызова JNI / собственного уровня. Таким образом, для каждого визуализируемого кадра выполняется один вызов JNI.
Я бы хотел сделать рендеринг немного по-другому. Я хочу вызвать updateGL
без использования кода java / JNI вообще и использовать только нативный уровень (как представлено в приведенной выше выдержке). Самая большая проблема для меня сейчас заключается в том, как запустить updateGL
в потоке пользовательского интерфейса (требуется OpenGL) без обратного вызова Java. Это вообще возможно?