当前位置: 首页 > 知识库问答 >
问题:

我如何发布代码,使其从C中的一个单独线程运行到Android主线程上?

卓正业
2023-03-14

我有一个单独的线程在后台运行在C中,我希望它能够发布代码,在另一个已经运行android的线程上运行。操作系统。活套(例如主线)。我所说的“post”是指类似于视图post的东西,其中可运行的排队在事件循环上运行。将要执行的代码也用C编写。

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

我不希望通过Java获得处理程序,等等——这似乎是不必要的,因为我试图运行的代码和发布它的代码都是c语言

共有3个答案

闾丘英悟
2023-03-14

这可以帮助你https://groups.google.com/forum/#!topic/android ndk/v2OITtaZTes

但通过java端的处理程序很容易实现,通过jni调用在本机和java之间来回发送和处理消息

吴飞语
2023-03-14

您需要一个已经在主线程中执行的函数。如果您在那里调用ALooper_forThread()ALooper_prepare(),您将获得一个指向与主线程关联的循环器的指针。请记住调用ALooper_acquire(),以便它可以在不同的线程之间共享。

益阳平
2023-03-14

一个线程只能有一个与之关联的循环器,一个循环器只有一个消息队列,因此混合Java和本机回调将保持顺序。

因此,我不认为Android今天有任何合同义务保证按特定顺序执行。

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

不能正式保证让mTextView第二次显示。当两个帖子从不同的线程发出或延迟时,肯定没有什么是一成不变的。

您可以在一篇很棒的博客文章中找到用于本机代码开发的Android消息传递和并发框架。

这是所需的证据。在处理一个不相关的问题时收到了下面的stacktrace:

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服务中,我创建了用于执行一些后台任务的线程。 我遇到一个情况,线程需要在主线程的消息队列上发布特定任务,例如。 有没有方法获取主线程的并从我的另一个线程向它发布/?

  • 例如: 假设有一个按钮启动异步请求,该请求返回并触发主线程上运行的runnable/callback。会发生什么?runnable被添加到MessageQueue中,并在“时间”到时运行。但是什么时候是“时间”呢?如果在异步请求将runnable发布到MainThread之前,我按下另一个按钮,在MainThread上执行一些半长的阻塞任务呢?它会等到我的阻塞按钮上的逻辑完成吗?会打断它吗?它是否

  • 问题内容: 这是一个普遍的Java问题,而不是Android的第一个问题! 我想从二级线程的上下文中了解如何在主线程上运行代码。例如: 这类事情-我意识到我的示例有点差,因为在Java中,您不需要进入主线程即可打印出某些内容,并且Swing也具有事件队列- 但在一般情况下,您可能需要在后台线程的上下文中,在主线程上运行Runnable。 编辑:为了进行比较-这是我在Objective-C中的做法:

  • 我想让一些代码在后台持续运行。我不想在服务中这样做。还有其他可能的方法吗? 我曾尝试在我的活动中调用线程类,但我的活动在后台保留了一段时间,然后就停止了。线程类也停止工作。

  • 问题内容: 因此,正如标题所述:将可运行对象从另一个线程发布到主线程时,实际上会发生什么? 我已经看到很多问题,询问您如何执行以及其基本原理。但是,当您将可运行对象放在MessageQueue上时,我很难找到确切的解释。当然,它在轮到Runnable时运行。但是什么时候呢? 因此,例如: 假设有一个按钮启动ASync请求,并且该请求返回并触发在MainThread上运行的可运行/回调。怎么了?可运