做一做native层面消息实战Looper,Handler,Message

nativeMessaging - 本地消息传递 微软官网文档 https://www.youtube.com/watch?v=Odei9r2SB78 chrome开发指南 csdn参考资料 十进制和26进制转换算法 https://github.com/appemit/appemit/blob/master/README_zh.md 阅读详情

背景:

前面分享过一篇文章已经针对Handler和Message进行了详细的源码分析,从上到下对安卓的消息机制进行讲解。在了解了整个消息机制的原理后,可能大家对消息机制都有了一个新的高度。但是想要进一步的深刻理解消息机制的作用,那么还是需要针对消息机制进行相关的实战使用。
大家在java层面经常都会使用到Hander,Message,Looper,但是学习了前面的消息机制后,其实native层面也是完全可以和java层一样使用消息机制,所以本文主要在native层面来使用Looper,Message,Handler组成的消息机制。
在这里插入图片描述

回顾java层面消息机制

一般java层一个子线程需要使用消息循环一般会有如下代码:
在这里插入图片描述
主要分为如下几步:
1、初始化Loop,通过调用Looper.prepare方法
2、构造基于初始化的Loop构造出Handler
3、Loop启动循环等待消息
4、Handler接收处理消息

回顾了Java端的消息机制使用流程后,再来写native的就方便多了。

native层面消息机制实战代码

其实native端使用消息机制步骤和java端基本上一样,也是如下几步
1、初始化Loop,通过调用Looper.prepare方法
2、构造基于初始化的Loop构造出Handler
3、Loop启动循环等待消息
4、Handler接收处理消息

其实关于native层面的消息机制使用aosp原生也有相关的测试文件可以参考,本文的实战demo就是基于这个测试案例进行的改造:
测试文件案例参考地址:

system/core/libutils/Looper_test.cpp

下面展示改造后的实战demo:

#define LOG_TAG "LooperTest"
#include "Pipe.h"
#include <stdio.h>
#include <utils/Looper.h>
#include <unistd.h>
#include <time.h>
#include <utils/threads.h>


using namespace android;
using namespace std;
Pipe pipe1;//管道对象,主要就是搞个管道fd,这样可以不使用Looper自带fd

class CallbackHandler {
public:
    CallbackHandler(){}
    void setCallback(const sp<Looper>& looper, int fd, int events) {
        looper->addFd(fd, 0, events, staticHandler, this);//本质也是调用Looper的addFd进行fd监听
    }

protected:
    int handler(int fd, int events) {
        printf("[Thread=%d] %s fd=%d, events=%d,  pipe1.readSignal() = %s\n", gettid(), __func__, fd, events, pipe1.readSignal() == OK ? "OK":"NOT OK");
        return 0;
    }

private:
    static int staticHandler(int fd, int events, void* data) {
        return static_cast<CallbackHandler*>(data)->handler(fd, events);
    }
};

class LooperEventCallback : public LooperCallback {
  public:
    using Callback = std::function<int(int fd, int events)>;
    explicit LooperEventCallback(Callback callback) : mCallback(std::move(callback)) {}
    //这里handleEvent其实直接调用了mCallback,当然也可以handleEvent直接处理相关业务
    int handleEvent(int fd, int events, void* /*data*/) override { return mCallback(fd, events); }

  private:
    Callback mCallback;
};

class MyMessageHandler : public MessageHandler {
public:
    Vector<Message> messages;

    virtual void handleMessage(const Message& message) {
        printf("[Thread=%d] %s message.what=%d \n", gettid(), __func__, message.what);
        messages.push(message);
    }
};

struct LooperThread : public Thread {
public:
    LooperThread(Looper *looper)
        : mLooper(looper) {
    }

    virtual bool threadLoop() {
        if(mLooper == NULL)
            return false;
        mLooper->pollOnce(-1);//进行Looper循环
        return true;
    }

protected:
    virtual ~LooperThread() {}

private:
    Looper *mLooper;
};

int main()
{
    printf("process %s  pid = %d\n", LOG_TAG,getpid());
   
    sp<Looper> mLooper = new Looper(true);//构建Looper对象
    sp<LooperThread> mLooperThread = new LooperThread(mLooper.get());//使用该Looper构建对应的Thread
    mLooperThread->run("LooperThreadTest");//让Thread运行,让Looper进行循环

    //------------------开始使用自带Message进行消息传递,也就是使用的fd其实是Looper自带的mWakeEventFd
    sp<MyMessageHandler> handler = new MyMessageHandler();
    printf("[Thread=%d] sendMessage message.what=%d \n", gettid(), 1);
    mLooper->sendMessage(handler, Message(1));//主线程发送消息
    sleep(1);
    
    //-------------------开始使用Looper监听用户自定义fd方式,这里演示两种回调方式 
    //1.直接函数指针回调法
   
    CallbackHandler mCallbackHandler;
    //注意这里使用的是 pipe1.receiveFd管道fd
    mCallbackHandler.setCallback(mLooper, pipe1.receiveFd, Looper::EVENT_INPUT);
    printf("[Thread=%d] writeSignal 1\n", gettid());
    pipe1.writeSignal(); 
    sleep(1);
    
    
    //2.使用LooperCallback这种回调方法
    auto testCallback = [](int fd, int events) {

        if ((events & Looper::EVENT_INPUT) == 0) {
            return 1;  
        }
        char buf[1];
        int size = (int)::read(fd, buf, 1);
        printf("[Thread %d]  testCallback EVENT_INPUT buf = %c size = %d\n", gettid(),buf[0],size);
        return 0;  
    };
    mLooper->addFd( pipe1.receiveFd, 0, Looper::EVENT_INPUT, new LooperEventCallback(std::move(testCallback)), nullptr);
    printf("[Thread=%d] writeSignal 2\n", gettid());
    pipe1.writeSignal();
    
    sleep(2);
    mLooperThread->requestExit();
    mLooper.clear();
}

整体实战demo案例设计图如下:
在这里插入图片描述
代码中本身已经有详细的注释进行解释,这里也就不需要多说,大家看代码既可以。

实战成果展示:

process LooperTest  pid = 2711  ---进程号,主线程号
 -------默认Looper自带fd部分
[Thread=2711] sendMessage message.what=1  ---主线程发送默认消息,传递what为1
[Thread=2712] handleMessage message.what=1 ---子线程handler中接受到进行处理

 -------自定义Looper的fd部分
[Thread=2711] writeSignal 1   ---主线程给管道fd写入数据
[Thread=2712] handler fd=3, events=1,  pipe1.readSignal() = OK  ---子线程通过函数指针方式回调接受到

[Thread=2711] writeSignal 2  ---主线程给管道fd写入数据
[Thread 2712]  testCallback EVENT_INPUT buf = a size = 1  ---子线程通过LooperCallback方式回调接受到

文章参考来源:https://mp.weixin.qq.com/s/g5rauYoW8KpomvDkr73Y7Q

更多framework实战干货,请关注下面“千里马学框架”

浏览器插件基于nativeMessaging通信 以上是基于Qt程序实现的通信方法,该例子是在Mac上实现的,Win上没调成功,主要是Win的命令行启动程序不是保持运行状态,启动后就和控制台断开,插件就判定为连接已断开,没法进行通信,目前Win没找到能保持控制台运行的启动命令行。 阅读详情

相关推荐

Android消息处理惩罚机制(Handler、Looper、MessageQueue与Message)

Android是消息驱动的,实现消息驱动有几个要素: (1)消息的默示:Message (2)消息队列:MessageQueue (3)消息轮回,用于轮回取出消息进行处理惩罚:Looper (4)消息处理惩罚,消息轮回从消息队列中取出消息后要对消息进行处理惩罚:Handler   日常平凡我们最常应用的就是Message与Handler了,若是应用过HandlerThread或者

ysh06201418的专栏 3643

ChromeNativeMessaging 原生消息通信

原生消息通信 chrome extension扩展程序可以与原生应用程序交换消息。支持该特性的原生应用程序必须注册一个了解如何与扩展程序通信的原生消息宿主,Chrome 浏览器将在单独的进程中启动宿主,并通过标准输入和标准输出流与之通信。在Chrome浏览器中,Native Messaging是唯一能让web page调用Native API的技术,这里记录要达到这个目的所要涉及到的知识。web page、extension和native messaging host三者之间用UTF-8编码的json字符

顺其自然~专栏 7747

Android的消息机制学习(一)Looper,Handler,MessageQueue

Message,Handler是在Android中最常用的,更新UI点手段。与其他图形界面的原理类似,Android系统中UI也是靠消息驱动来工作的,具体有以下一些概念。 消息发送者:发生消息到队列 消息队列:存储消息的队列 消息循环:不断的循环取出消息,发给处理者 消息处理者:处理消息

云涛的博客 1192

浏览器本地通信(Native Messaging)

扩展和应用程序可以使用与其他消息传递API类似的API与本机应用程序交换消息。支持此功能的本机应用程序必须注册知道如何与扩展通信的本机消息传递主机。Chrome在一个单独的进程中启动主机,并使用标准输入和标准输出流与主机通信。 Native messaging host 为了注册本机消息传递主机,应用程序必须安装定义本机消息传递主机配置的清单文件。下面是清单文件的示例: { "name": "com.my_company.my_application", "description": "My

啊渊的专栏 3014

Android消息机制:Handler与Looper原理详解

消息机制是Android系统实现线程间通信的核心架构,基于生产者-消费者模型构建。其核心组件包括Handler、Looper和MessageQueue,共同构成了Android的事件驱动模型。Looper负责线程的消息循环管理,通过不断从MessageQueue中取出消息并分发给对应Handler处理。这种机制不仅确保了UI线程的安全性,还解决了跨线程通信和异步处理的工程难题。在Android开发中,Handler-Looper机制广泛应用于UI更新、后台任务处理等场景,同时也是理解ANR(Applicat

huqiyes的专栏 425

Android 消息传递机制 - Looper/Handler/MessageQueue/Message 详解

目录 总览 Message Obtain - 获取对象 Recycle Asynchronous - 异步 MessageQueue enqueueMessage函数详解 next函数详解 barrier详解 postSyncBarrier函数解读 removeSyncBarrier函数解读 IdleHandler解读 FileDescriptor介绍 Handler ...

码农的世界 1312

chrome插件开发之Native Message

更多工具] --> [扩展程序] --> [开发者模式] --> [加载已解压的扩展程序] --> [选择nativeMessaging\extension路径]打开chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/main.html,点击。这里的python的解释器是/usr/bin/python3,可以通过。,所以这里的/usr/bin/python3要替换成这个。,大概率可能是python的问题,因为我就是~~,可以查看到应用程序。

漫漫L路的博客 2444

Android消息机制:Handler与Message深度解析

在Android开发中,线程间通信是构建响应式应用的关键技术。Handler消息机制作为Android系统的核心基础架构,通过Message、Looper和MessageQueue三大组件实现高效的异步通信。Message作为数据载体,采用对象池设计优化内存使用;Looper通过事件循环模型实现消息分发,底层依赖epoll机制保证高效性;MessageQueue则管理着按执行时间排序的优先级队列。这套机制不仅支撑着Android的UI更新体系,还能有效解决跨线程任务调度问题。理解Handler的工作原理有助

xpp02的专栏 355

Android消息处理机制(Handler、Looper、MessageQueue与Message)

Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取出消息后要对消息进行处理:Handler   平时我们最常使用的就是Message与Handler了,如果使用过HandlerThread或者自己实现类似HandlerThr

AngelDevil的专栏 954

NativeMessage-crx插件

启动APP 这是一个自主研发的一个Chrome扩展程序,为了通信与本地的一个exe程序而进行开发的,启动一个本地的exe程序去进行打印操作功能。 支持语言:中文 (简体)

村田电感模型选型指南:.s2p和SPICE netlist在ADS中的表现差异

本文深度解析了村田电感在ADS仿真中.s2p与SPICE netlist两种模型的表现差异。通过对比模型本质、仿真设置及高低频段精度,揭示了.s2p文件基于实测插值而SPICE netlist基于等效电路外推的特性。文章提供了明确的选型策略,帮助工程师根据项目频段、仿真类型和精度需求,在射频与微波电路设计中做出最优模型选择。

k9l0m1的博客 452

Handler、MessageQueue、Looper底层原理梳理(详解)

本文深入分析了Android消息处理机制的核心组件:Handler、Looper、Message和MessageQueue的工作原理及相互关系。详细列举了安卓源码,对理解安卓的通信机制有重要意义。解释的非常详细,非常适合刚入门的小伙伴。

appron的博客 1344

BetaFlight开源飞控源码分析

BetaFlight是穿越机领域比较成熟的开源飞控,本篇文章主要分析一下源代码以及如何使用这个开源代码

weixin_43811044的博客 1万+

线程通信:Handler、MessageQueue和Looper

Android 消息机制:Handler、MessageQueue 和 Looper在这篇文章中,我们将会讨论 Android 的

夜游神 1540

基于淘宝商城用户购物行为数据分析系统

本文使用HIve+superset技术对阿里云天池提供的淘宝用户购物数据进行处理分析,得到有价值的信息并对平台提出有建设性意义的意见。

m0_51388399的博客 2821

第3.2.1章 Eigen代码实战:四元数赋值用法总结及与变换矩阵转换

Eigen库中四元数(Quaternion)的赋值方法解析:Quaterniond和Quaternion<double>本质相同,但Quaterniond是更简洁的别名。主要赋值方式包括直接构造(w,x,y,z分量、旋转矩阵或轴角)、赋值运算符和成员函数赋值。使用时需注意参数顺序、归一化处理和头文件包含,常见错误包括模板参数缺失和构造顺序错误。四元数广泛应用于旋转矩阵转换、姿态组合等场景,合理选择赋值方式能提高代码可读性和正确性。

行知SLAM 587

Android消息机制:Message与Handler深度解析

消息机制是Android系统线程通信的核心架构,通过Message、Handler、MessageQueue和Looper四大组件协同工作。Message作为消息载体采用对象池技术优化性能,包含what、arg等轻量级字段设计。Handler负责消息分发处理,结合Looper实现线程间通信。这种机制广泛应用于UI更新、事件处理等场景,其复用机制和优先级队列设计能有效提升应用性能。理解消息机制对解决ANR问题、优化线程模型至关重要,也是Android开发者必须掌握的基础知识。

weixin_30443813的博客 551

三步实现Java分布式追踪:像“开灯”一样简单

摘要: 本文通过三步实现Java分布式追踪: 引入依赖:配置Spring Cloud Sleuth+Zipkin,自动埋点无需代码侵入; 启动服务:REST接口自动生成Trace/Span ID,日志可验证; 可视化分析:通过Zipkin UI查看调用链耗时和拓扑关系。 亮点:AOP自动埋点、零业务代码修改、支持多服务链路追踪,助力快速定位性能瓶颈。适用于微服务诊断,生产环境可调整采样率平衡性能。(150字)

墨夶的博客 2711

Looper、MessageQueue、Message及Handler的关系是什么?如何保证MessageQueue的并发访问安全?

消息的载体,包含任务数据和目标Handler信息。它在Handler机制中贯穿始终,本质是一个链表节点。当多线程同时操作MessageQueue(生产者线程入队,Looper线程出队),通过。这种机制保证了跨线程通信的安全性和高效性,是Android事件驱动的核心基础。,允许生产者线程随时入队新消息。唤醒后重新竞争锁执行出队操作。nativePollOnce() 等待。Handler发送Message。消息容器,本质是优先级队列(按。:当队列为空时,Looper在。中释放CPU资源并等待,此时。

bookzhan的专栏 1199

5、卡尔ibration中Denavit - Hartenberg与Hayati约定的转换

本文详细介绍了机器人运动学中Denavit-Hartenberg(DH)参数与Hayati参数的定义、适用场景及其相互转换方法。重点分析了两种参数在描述关节坐标系变换时的差异,特别是在处理平行或接近平行关节轴时的稳定性问题,并给出了从DH到Hayati及反向转换的具体数学公式与流程图。通过参数转换,可在不改变运动学模型的前提下提升建模精度与计算鲁棒性,适用于机器人标定与运动学分析等应用场景。

h0i1j2k3l的博客 121

【GEE数据库】WRF常用数据集总结

【GEE数据库】WRF常用数据集总结

WW、forever的博客 638

Handler消息机制-Looper(system)

接续 “NativeMessageQueue” 部分,在NativeMessageQueue的 JNI 方法实现中,最终几乎全部都是在操作 “” 对象。接下来看一下​Looper(system)它如何通过监听和处理消息队列中的事件,确保线程能够按照预定的方式响应各种消息和回调。

只想搞钱 803

AgentScope 2.0 源码解析-工具系统解读:从内置工具到权限管控的完整实践

本文深入解析AgentScope 2.0工具系统的完整架构,覆盖内置工具集(文件读写、命令执行、搜索匹配)、MCP协议集成(STDIO/HTTP双传输、客户端封装、工作空间网关)、工具包管理与动态分组、权限引擎的多级决策机制(危险路径保护、只读识别、模式控制),以及自定义工具开发流程。通过分层架构图和时序图直观展示组件协作关系,结合安全最佳实践与故障排除指南,为开发者提供从工具使用到安全管控的全链路参考。

program哲学 571

Android Handler 消息循环机制

核心思想:利用 Linux 的epoll机制,在无事可做时让线程进入休眠,在有新消息时能及时唤醒,从而兼顾了响应效率和资源消耗。

w2064004678的博客 1387

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: 聊一聊 Android 的消息机制
下一篇: 看一看系统Task都为啥不显示的问题--学员作业
千里马学框架
博客等级 码龄6年 1万+粉丝 650原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值