programar para desarrollar cppdroid c4droid app aplicaciones android android-ndk

cppdroid - ide para desarrollar aplicaciones android



¿Cómo publico el código para ejecutarse en el subproceso principal de Android desde un subproceso separado en C++? (5)

Esto podría ayudarlo a https://groups.google.com/forum/#!topic/android-ndk/v2OITtaZTes

Pero es fácil de lograr a través de un manejador en el lado de Java, enviando y procesando mensajes de ida y vuelta entre nativos y Java con llamadas jni.

Tengo un subproceso independiente que se ejecuta en C ++ en segundo plano y quiero que pueda publicar código para ejecutarse en otro subproceso que ya esté ejecutando android.os.Looper (por ejemplo, el subproceso principal). Por "publicación", me refiero a algo similar a la View#post donde un Runnable se Runnable en Runnable para ejecutarse en el bucle de eventos. El código que se ejecutaría también está escrito en C ++.

Encontré la API de ALooper ( http://developer.android.com/ndk/reference/group___looper.html ), pero los documentos no son excelentes y no me queda claro si obtener el ALooper asociado con el hilo de destino, agregando otro FD , y señalizándolo hará que mi código mantenga el orden correcto en la cola de eventos con respecto a los otros Runnables en cola.

Preferiría no tener que pasar por Java y obtener un Handler, etc., simplemente parece innecesario, ya que tanto el código que estoy intentando ejecutar como el código que lo está publicando están en c ++.


Necesitas una función ya ejecutada en el hilo principal. Si llamas a ALooper_forThread() o ALooper_prepare() allí, obtendrás un puntero a Looper asociado con el hilo principal. Recuerda llamar a ALooper_acquire() para que pueda ser compartido entre diferentes hilos.


Si quieres hacer algunas cosas en el hilo principal de otro hilo, te sugiero que uses la función runOnUiThread . El hilo principal en Android es el hilo de la interfaz de usuario. No estoy seguro de si puedes usar esta función en el código ndk.

Un ejemplo de código podría ser este:

void privado runOnMainThread () {

runOnUiThread(new Runnable(){ public void run() { try { // do some stuffs } catch (final Exception ex) { // handle the possible exception } } }); }

De todos modos te sugiero que leas los siguientes enlaces: link3 , link3 , link3 .

Espero que ayude.


Tendrá que pasar por Java, ya que android.os.Looper no está implementado en código nativo (al menos en la confirmación actual más reciente ).

No tengo suficiente experiencia con el NDK para escribir rápidamente la Runnable requerida, pero la opción obvia parece ser crear un Runnable java basado en código nativo y enviarlo al looper.

La solución no tan obvia está operando directamente en el MessageQueue del hilo. Una vez que tenga una referencia de eso, puede registrar un extremo de un conducto nativo allí y escribir mensajes en el otro extremo; la canalización básicamente toma la función de un Handler , pero en código nativo. Técnicamente, su código aún se llama desde Java, pero no necesitará la sobrecarga. No he encontrado mucha documentación sobre todo esto, pero este hilo podría ser un buen punto de partida.¹

Sin embargo, es perfectamente posible que su código no tenga que llamarse desde el hilo principal, o que haya otra opción para resolver su problema sin pasar por Java. Eso, sin embargo, dependería del problema que estés tratando de resolver.

Nota: Asumo el escenario del hilo principal. Si puede usar un looper basado en código nativo en el hilo que desea implementar, tiene más opciones.

¹ Es posible que ALooper pueda usarse en algún tipo de modo cliente para hacer eso, también. Muy inseguro sobre eso.


Un subproceso solo puede tener un Looper asociado, un Looper tiene solo una cola de mensajes, por lo que la mezcla de Java y devoluciones de llamada nativas mantendrá el orden.

Con eso, no creo que haya ninguna obligación contractual en Android hoy en día que post() esté garantizado para ejecutarse en un orden particular, es decir,

getHandler().post(new Runnable() { @Override public void run() { mTextView.setText("first"); } }); getHandler().post(new Runnable() { @Override public void run() { mTextView.setText("second"); } });

no se garantiza formalmente que mTextView se muestre en segundo lugar . Definitivamente, nada está escrito en piedra cuando se emiten dos publicaciones desde hilos diferentes o se retrasan.

Puede encontrar un marco de mensajes y concurrencia de Android para el desarrollo de código nativo descrito en una excelente publicación de blog .

Actualizar

Aquí está la prueba requerida. El seguimiento de pila a continuación se recibió mientras trabajaba en un problema no relacionado:

A/art: art/runtime/check_jni.cc:65] native: #00 pc 0000484c /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23) A/art: art/runtime/check_jni.cc:65] native: #01 pc 00003031 /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8) A/art: art/runtime/check_jni.cc:65] native: #02 pc 002441f9 /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+68) A/art: art/runtime/check_jni.cc:65] native: #03 pc 002285a1 /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+144) A/art: art/runtime/check_jni.cc:65] native: #04 pc 000afe9b /system/lib/libart.so (art::JniAbort(char const*, char const*)+582) A/art: art/runtime/check_jni.cc:65] native: #05 pc 000b05d1 /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+60) A/art: art/runtime/check_jni.cc:65] native: #06 pc 000b299d /system/lib/libart.so (art::ScopedCheck::Check(bool, char const*, ...) (.constprop.129)+672) A/art: art/runtime/check_jni.cc:65] native: #07 pc 000bab87 /system/lib/libart.so (art::CheckJNI::CallVoidMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+50) A/art: art/runtime/check_jni.cc:65] native: #08 pc 00060817 /system/lib/libandroid_runtime.so (???) A/art: art/runtime/check_jni.cc:65] native: #09 pc 000a5b29 /system/lib/libandroid_runtime.so (???) A/art: art/runtime/check_jni.cc:65] native: #10 pc 00010fd7 /system/lib/libutils.so (android::Looper::pollInner(int)+482) A/art: art/runtime/check_jni.cc:65] native: #11 pc 00011081 /system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+92) A/art: art/runtime/check_jni.cc:65] native: #12 pc 0007fbe5 /system/lib/libandroid_runtime.so (android::NativeMessageQueue::pollOnce(_JNIEnv*, int)+22) A/art: art/runtime/check_jni.cc:65] native: #13 pc 00051b8b /system/framework/arm/boot.oat (Java_android_os_MessageQueue_nativePollOnce__JI+102) A/art: art/runtime/check_jni.cc:65] at android.os.MessageQueue.nativePollOnce(Native method) A/art: art/runtime/check_jni.cc:65] at android.os.MessageQueue.next(MessageQueue.java:143) A/art: art/runtime/check_jni.cc:65] at android.os.Looper.loop(Looper.java:122) A/art: art/runtime/check_jni.cc:65] at android.app.ActivityThread.main(ActivityThread.java:5411) A/art: art/runtime/check_jni.cc:65] at java.lang.reflect.Method.invoke!(Native method) A/art: art/runtime/check_jni.cc:65] at java.lang.reflect.Method.invoke(Method.java:372) A/art: art/runtime/check_jni.cc:65] at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:916) A/art: art/runtime/check_jni.cc:65] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:709)