android主线程中调用函数,Android JNI-来自C ++的Android UI线程上的调用函数

本文详细介绍了如何通过JNI在Android应用中使用Looper将本机代码发布到主线程,通过文件描述符和事件监听实现高效的消息传递。示例代码展示了如何创建消息管道并实现代理回调,确保在主线程接收复杂数据。
摘要由CSDN通过智能技术生成

小编典典

正如@Elviss提到的-

将代码发布到主线程中,您应该使用Looper。实际上,无需额外处理JNI以及创建自定义项java.lang.Runnable并通过复杂的JNI内容将其发布即可完成此操作。

Android

NDK提供了极其轻便高效的方式来将本机代码发布到任意循环程序。关键是您应该向循环程序提供任意文件描述符,并指定您感兴趣的文件事件(输入,输出等)。在后台,looper会轮询该文件描述符,一旦事件可用,它将在适当的线程上运行您的回调。

有一个最小的示例(没有错误检查和删除):

#include

#include

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "sergik", __VA_ARGS__)

static ALooper* mainThreadLooper;

static int messagePipe[2];

static int looperCallback(int fd, int events, void* data);

void someJniFuncThatYouShouldCallOnceOnMainThread() {

mainThreadLooper = ALooper_forThread(); // get looper for this thread

ALooper_acquire(mainThreadLooper); // add reference to keep object alive

pipe(messagePipe); //create send-receive pipe

// listen for pipe read end, if there is something to read

// - notify via provided callback on main thread

ALooper_addFd(mainThreadLooper, messagePipe[0],

0, ALOOPER_EVENT_INPUT, looperCallback, nullptr);

LOGI("fd is registered");

// send few messages from arbitrary thread

std::thread worker([]() {

for(char msg = 100; msg < 110; msg++) {

LOGI("send message #%d", msg);

write(messagePipe[1], &msg, 1);

sleep(1);

}

});

worker.detach();

}

// this will be called on main thread

static int looperCallback(int fd, int events, void* data) {

char msg;

read(fd, &msg, 1); // read message from pipe

LOGI("got message #%d", msg);

return 1; // continue listening for events

}

此代码产生下一个输出:

06-28 23:28:27.076 30930-30930/? I/sergik: fd is registered

06-28 23:28:27.076 30930-30945/? I/sergik: send message #100

06-28 23:28:27.089 30930-30930/? I/sergik: got message #100

06-28 23:28:28.077 30930-30945/? I/sergik: send message #101

06-28 23:28:28.077 30930-30930/? I/sergik: got message #101

06-28 23:28:29.077 30930-30945/? I/sergik: send message #102

06-28 23:28:29.078 30930-30930/? I/sergik: got message #102

06-28 23:28:30.078 30930-30945/? I/sergik: send message #103

06-28 23:28:30.078 30930-30930/? I/sergik: got message #103

06-28 23:28:31.079 30930-30945/? I/sergik: send message #104

06-28 23:28:31.079 30930-30930/? I/sergik: got message #104

06-28 23:28:32.079 30930-30945/? I/sergik: send message #105

06-28 23:28:32.080 30930-30930/? I/sergik: got message #105

06-28 23:28:33.080 30930-30945/? I/sergik: send message #106

06-28 23:28:33.080 30930-30930/? I/sergik: got message #106

06-28 23:28:34.081 30930-30945/? I/sergik: send message #107

06-28 23:28:34.081 30930-30930/? I/sergik: got message #107

06-28 23:28:35.081 30930-30945/? I/sergik: send message #108

06-28 23:28:35.082 30930-30930/? I/sergik: got message #108

06-28 23:28:36.082 30930-30945/? I/sergik: send message #109

06-28 23:28:36.083 30930-30930/? I/sergik: got message #109

从pid-tid对中可以看到-消息是在主线程上接收的。当然,您可能会发送比一字节消息更复杂的内容。

2020-10-09

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值