目录

概述

自实现

下面简单叙述其原理:

如何使用:

注意问题:


概述

本篇探究 Android framework native层多媒体库中的 AHandler+ALooper+AMessage 这三个类的关系和机制,并借鉴此原理,用c++(c++17)重新实现自己的Handler+Looper+Message.  实现可以支持异步和同步的消息处理结构。

android里面的这三个类 在  /frameworks/av/media/libstagefright/foundation
可以在如下 在线 aosp源码找到 http://www.aospxref.com/android-12.0.0_r3/xref/frameworks/av/media/libstagefright/foundation/
android中取名在前面加了个前缀 A, 表示android.

自实现

基于此重新用c++写的 CHandler CLooper CMessage ,在个人的github:https://github.com/Canok7/openScreen/commit/74ae413b916d66a87f27f9c614ab2b2f26104635

下面简单叙述其原理:

looper 为主循环,内部存在一个消息链表,存储着这个消息和该消息应该被处理的时间点,该链表插入消息的时候有序插入,是确保消息是按照消息的处理时间的先后来进行排序的,循环体不停地从链表中取出最先需要处理的消息,如果没有消息,进入条件等待,如果有就调用消息的所绑定的目标hander的onMessageReceived函数。 所以核心即按执行时间排序的消息链表和线程条件等待机制

如何使用:

1. 建一个looper 调用start()   。也可以给looper设置线程名称,方便调试

 std::shared_ptr<CLooper> mSink_Loop = std::make_shared<CLooper>();mSink_Loop->setName("test_looper");mSink_Loop->start();

2. 建一个自定义的Handler,将其注册到looper .(注册到looper有两个作用,一是绑定looper和hander的对应关系,后续Message即可通过handler来找到looper,二是要确保一个hander只能被注册一次,不能绑定到多个looper上去,所以源码里面有LooperRoster,它用一张map表记录有所有的handler和looper对应关系。 这个对象是全局唯一的,即一个进程中只有一个LooperRoster)

class LooperTest : public CHandler{
public:enum{MSG_SAY,MSG_SUM,};LooperTest() = default;virtual ~LooperTest() = default;void onMessageReceived(const std::shared_ptr<CMessage> &msg) override{switch (msg->what()) {case MSG_SAY:{std::string say_Str;int32_t say_Int=0;CHECK(msg->findString("say_Str", &say_Str));CHECK(msg->findInt32("say_Int", &say_Int));ALOGD("[%s%d](%d) say_Str.c_str():%s,say_Int:%d\n",__FUNCTION__,__LINE__,gettid(),say_Str.c_str(),say_Int);}break;case MSG_SUM:{//get reply from msgstd::shared_ptr<CReplyToken> replyID;CHECK(msg->senderAwaitsResponse(&replyID));//do workint32_t add1=0,add2=0;msg->findInt32("add1", &add1);msg->findInt32("add2", &add2);ALOGD("[%s%d](%d) to sum:%d,%d\n",__FUNCTION__,__LINE__,gettid(),add1,add2);//post resutstd::shared_ptr<CMessage> response = std::make_shared<CMessage>();response->setInt32("result", add1+add2);response->postReply(replyID);}break;default:ALOGD("unKnow msg:%d\n",msg->what());break;}}
};
enum{TEST_THREAD,TEST_SP,TEST_LOOPER,TEST_ABUFFER_LIST,
};// std::shared_ptr<LooperTest> mHander = std::make_shared<LooperTest>();mSink_Loop->registerHandler(mHander);

3. 建一个Message, 设定message 的Handler 和what.(可以直接在构造函数中携带)  调用异步处理post(只管把消息发出去,不管结果),或者同步postAndAwaitResponse(把消息发出去,并且阻塞在这里等待返回结果)

//异步std::shared_ptr<CMessage> msg = std::make_shared<CMessage>(LooperTest::MSG_SAY,mHander);msg->setString("say_Str", "hello");msg->setInt32("say_Int", count++);msg->post();//同步等待std::shared_ptr<CMessage> msg = std::make_shared<CMessage>(LooperTest::MSG_SUM,mHander);msg->setInt32("add1", 7);msg->setInt32("add2", 8);ALOGD("[%s%d](%d) postAndAwaitResponse\n",__FUNCTION__,__LINE__,gettid());std::shared_ptr<CMessage> response;//this will make a reply,and wait !!status_t err = msg->postAndAwaitResponse(&response);ALOGD("[%s%d] -----debug %d err ",__FUNCTION__ ,__LINE__,err);if (err == OK) {int ret=0;response->findInt32("result", &ret);ALOGD("[%s%d]xxxxxxxxxxxx(%d) get add ret:%d\n",__FUNCTION__,__LINE__,gettid(),ret);}

注意问题:

1. 为了保证所有的Handler只会被绑定到一个Looper, 这里有一个单例的LooperRoster . 调试的时候可以从LooperRoster中看到所有已注册的looper和Handler.  外部register的时候如果Handler已经被注册,register将不成功。
        2. Message持有Looper Handler ,  Handler持有Looper,  存储的都是weak_ptr,  如果某个Handler已经被释放,looper循环体在处理和这个Handler对应的消息时会忽略这个Message,不会发生错误。
        3. 调用者往Looper里面注册Handler, 相应地也应该需要调用反注册的机制,但是如果忘了没用调用反注册(registerHandler/unregisterHandler),也不会发生错误,在Looper的构造函数中会调用gLooperRoster.unregisterStaleHandlers()候判断哪一些handler已经是被析构了,然后去掉这些已经析构的无效Handler.

Android native层Hander原理分析相关推荐

  1. android transact,Android Native层Binder.transact()函数调用 Binder.onTransact() 函数失败分析...

    Q:Android Native层Binder.transact()函数调用 Binder.onTransact() 函数失败? 在Android Native层调用Camera.h中的api实现一个 ...

  2. Android系统的JNI原理分析(二)- 数据类型转换和方法签名

    声明 前阶段在项目中使用了Android的JNI技术,在此文中做些技术知识总结. 本文参考了一些书籍的若干章节,比如<Android进阶解密-第9章-JNI原理>.<深入理解Andr ...

  3. 安卓逆向学习笔记:native层开发、分析和调试基础

    安卓逆向学习笔记:native层开发.分析和调试基础 本笔记主要是自己看,所以如果有看不懂的地方也请多多包涵,这一篇的笔记主要是<Android应用安全防护和逆向分析>的部分内容. 一 A ...

  4. Android锁屏机制原理分析

    转载自:http://www.2cto.com/kf/201401/273898.html 春节前最后几天了,工作上几乎没有什么要做.大致整理下之前工作中写的文档,PPT,手册. 由于去年一年完全转到 ...

  5. Android native 层使用opengl渲染YUV420p和NV12

    <Ndk中使用Mediacode解码> <android mediacodec 编码demo(java)> <NDK中使用mediacodec编码h264> < ...

  6. 【Binder 机制】Native 层 Binder 机制分析 ( binder_loop | svcmgr_handler | binder.c | binder_parse )

    文章目录 前言 一.binder_loop 方法调用 二.binder_loop 方法参数 svcmgr_handler 三.binder_loop 方法 四.binder_parse 方法 前言 在 ...

  7. Android Native层

    android native层是 相对于Java 层的底层,一般用c++开发 Java框架层就是常说的Framework,这层里东西很多也很复杂,比如说主要的一些系统服务如ActivityManage ...

  8. android native层进程通信

    我们需要在android native层实现两个进程间的通信,这两个进程一个是native c 进程,一个是apk,两者需要传递一张几百K的图片,natice c 程序写该图片,apk读该图片,而且, ...

  9. Android手机一键Root原理分析(作者:非虫,文章来自:《黑客防线》2012年7月)

    之前几天都在做Android漏洞分析的项目,万幸发现了这篇文章.废话不多说,上文章! <Android手机一键Root原理分析> (作者:非虫,文章来自:<黑客防线>2012年 ...

最新文章

  1. 36晋级12第五场:冯志刚决胜入围(节目视频)
  2. Flask之Cookie与Session
  3. c++函数模板和类模板
  4. 找到所有数组中消失的数字—leetcode448
  5. 酒店wifi代理服务器没有响应,wn10连接酒店wifi的登录界面无法弹出如何处理
  6. 利用python来求解网络的平均路径长度和聚类系数
  7. nginx 499 502 413 404 处理
  8. abb变频器dp适配器说明书_国产变频器与西门子和ABB的差距大吗?
  9. 创业文档:项目启动会PPT
  10. 华为P50/P50Pro怎么解锁huawei P50pro屏幕锁开机锁激活设备锁了应该如何强制解除鸿蒙系统刷机解锁方法流程步骤不开机跳过锁屏移除锁定进系统方法经验
  11. k3导入账套_K3金蝶维护绝密(内部技术教程)
  12. 用python爬取校花网图片
  13. bongo cat mver手机版|键盘猫手机版
  14. js-函数式编程-柯里化和语义化
  15. 计算机应用基础 机考,计算机应用基础机考答案
  16. 大专学数控技术是计算机一类的吗,学专科数控技术,出来后找什么工作呢?
  17. 【孟子E章】祝大家新年愉快!
  18. react中使用阿里Viser图表
  19. 计算机英语性考任务答案,国开电大理工英语1单元自测2形考任务答案
  20. RN:metro缓存以及如何清除缓存

热门文章

  1. 通信协议-GMSL(千兆多媒体串行链路)
  2. 什么是上下变频器?以及对5G应用的作用
  3. 服务器重启后启动php项目
  4. hitTest:(CGPoint)point withEvent:(UIEvent *)event
  5. 一文看懂“摩根系”,摩根士丹利、摩根大通、大摩、小摩到底有什么关系?
  6. 如何下载安装Devc++
  7. 让CEF支持HEVC(H.265)视频播放
  8. WIN10安装postgresql启动服务失败解决
  9. Field ‘recordID‘ doesn‘t have a default value
  10. 交叉测试、探索性测试的概念、价值、实践