gpt4 book ai didi

android - 如何从 C++ 中的单独线程发布要在 Android 主线程上运行的代码?

转载 作者:IT老高 更新时间:2023-10-28 22:23:01 25 4
gpt4 key购买 nike

我在后台有一个在 C++ 中运行的单独线程,我希望它能够发布代码以在另一个已经运行 android.os.Looper 的线程(例如主线程)上运行。 'post' 是指类似于 View#post 的东西,其中 Runnable 被排入队列以在事件循环上运行。将要执行的代码也是用 C++ 编写的。

我找到了 ALooper API (http://developer.android.com/ndk/reference/group___looper.html),但文档不是很好,我不清楚是否将 ALooper 与目标线程关联,添加另一个 FD 并发出信号,这将使我的代码保持正确的顺序在相对于其他排队的 Runnables 的事件队列中。

我宁愿不必通过 Java 并获得 Handler 等。这似乎是不必要的,因为我尝试运行的代码和发布它的代码都是用 c++ 编写的。

最佳答案

一个线程只能有一个Looper与之关联,一个Looper只有一个消息队列,所以混合Java和 native 回调将保持顺序。

因此,我认为今天的 Android 没有任何契约(Contract)义务保证 post() 保证以特定顺序执行,即

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

不正式保证离开 mTextView 显示 。当两个帖子从不同的线程发布或延迟时,绝对没有什么是一成不变的。

您可以找到 Android messaging and concurrency framework for native code development描述了一个伟大的blog post .

更新

这是所需的证明。在处理一个不相关的问题时收到了下面的堆栈跟踪:

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)

关于android - 如何从 C++ 中的单独线程发布要在 Android 主线程上运行的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34212056/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com