Наконец-то нашел хорошую информацию по этому вопросу.
Потоки связующего не могут быть удалены или объединены, но вы можете довольно легко перенаправить вызовы функций в основной поток, используя Handler
и Runnable
объекты.
Handler handle = new Handler(); //Will be associated with current thread
handle.post(new Runnable ()
{
@Override public void run()
{
// Your code to be executed in this thread
// you can call native code here to make sure they run under this thread.
}
});
Но вы не можете использовать это в своем нативном коде. Таким образом, возможно, что некоторые из вашего нативного кода создают неожиданную ошибку. Для этого вы можете синхронизировать свой код внутри JNI, чтобы минимизировать странное поведение. ( подробности )
env->MonitorEnter(obj);
// Your code
env->MonitorExit(obj);
Вы также можете перенаправить некоторую часть вашего кода для выполнения внутри потока пользовательского интерфейса (что я не рекомендую, если вы хотите повысить производительность пользовательского интерфейса)
myActivity.runOnUiThread(new Runnable ()
{
@Override public void run()
{
// Your code
}
});
Если вы используете GLSurfaceView
, как я, вы также можете перенаправить код в поток GL
myGLSurfaceView.queueEvent(new Runnable()
{
@Override public void run()
{
/* do something on the GLSurfaceView thread */
}});
Важно отметить, что android всегда будет создавать отдельный поток для пользовательского интерфейса, поэтому вызов нативного кода из вашего кода пользовательского интерфейса и откуда-то еще может вызвать неожиданное поведение.
Кроме того, использование GLSurfaceView
в равной степени сгенерирует собственный поток для рендеринга, поэтому такого же взаимодействия с нативным кодом следует избегать. Но с этими несколькими подсказками вы сможете синхронизировать эти потоки и заставить их работать без сбоев;)