来写个demo试试看到底是ALooper AHandler AMessage是怎么运行的,源文件以及Android.bp如下:

// EvenHandler.h
#ifndef __MESSAGE_TEST_H__
#define __MESSAGE_TEST_H__ #include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/ADebug.h> namespace android{ class EventHandler : public AHandler
{
public:
EventHandler(); enum {
kWhatSetDataSource,
kWhatPrepare,
kWhatStart,
kWhatStop
}; void setDataSource(const char* url);
void prepare();
void start();
void stop(); protected:
virtual void onMessageReceived(const sp<AMessage> &msg); private:
void onSetDataSource(const char* url);
void onPrepare();
void onStart();
void onStop(); }; }
#endif
// EventHandler.cpp
#define LOG_TAG "MyEventHandler" #include "EventHandler.h"
#include <string.h> namespace android{ EventHandler::EventHandler()
{
ALOGD("tid = %d, func = %s", gettid(), __func__);
} void EventHandler::onMessageReceived(const sp<AMessage> &msg)
{
ALOGD("(%d)oMessageReceived: %s", gettid() ,msg->debugString().c_str());
switch(msg->what()){
case kWhatSetDataSource:
{
AString url;
CHECK(msg->findString("url", &url));
onSetDataSource(url.c_str());
break;
}
case kWhatPrepare:
{
sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
onPrepare();
sp<AMessage> response = new AMessage;
response->setInt32("err", 0);
response->postReply(replyID);
break;
}
case kWhatStart:
{
onStart();
break;
}
case kWhatStop:
{
onStop();
break;
}
default:
break;
}
} void EventHandler::setDataSource(const char* url)
{
ALOGD("tid = %d, func = %s", gettid(), __func__);
sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
msg->setString("url", url, strlen(url));
msg->post();
} void EventHandler::prepare()
{
ALOGD("tid = %d, func = %s", gettid(), __func__);
sp<AMessage> msg = new AMessage(kWhatPrepare, this);
sp<AMessage> response;
msg->postAndAwaitResponse(&response);
int err;
CHECK(response->findInt32("err", &err));
ALOGD("tid = %d, func = %s, err = %d", gettid(), __func__, err);
} void EventHandler::start()
{
ALOGD("tid = %d, func = %s", gettid(), __func__);
sp<AMessage> msg = new AMessage(kWhatStart, this);
msg->post();
} void EventHandler::stop()
{
ALOGD("tid = %d, func = %s", gettid(), __func__);
sp<AMessage> msg = new AMessage(kWhatStop, this);
msg->post();
} void EventHandler::onSetDataSource(const char *url)
{
ALOGD("tid = %d, func = %s, url = %s", gettid(), __func__, url);
} void EventHandler::onPrepare()
{
ALOGD("tid = %d, func = %s", gettid(), __func__);
int cnt = 0;
while(cnt < 3)
{
ALOGD("tid = %d, func = %s, cnt = %d", gettid(), __func__, cnt);
sleep(1);
cnt++;
}
} void EventHandler::onStart()
{
ALOGD("tid = %d, func = %s", gettid(), __func__);
int cnt = 0;
while(cnt < 10)
{
ALOGD("tid = %d, func = %s, cnt = %d", gettid(), __func__, cnt);
sleep(1);
cnt++;
} } void EventHandler::onStop()
{
ALOGD("tid = %d, func = %s", gettid(), __func__);
} }
// main.cpp
#define LOG_TAG "MyEventHandlerTest" #include "EventHandler.h" using namespace android; int main(int argc, char **argv)
{
ALOGD("tid = %d, func = %s", gettid(), __func__);
sp<EventHandler> handler = new EventHandler; sp<ALooper> looper = new ALooper;
looper->setName("MyLooper");
looper->start();
looper->registerHandler(handler); handler->setDataSource("ABC");
handler->prepare();
handler->start();
handler->stop(); int wait = 0;
while(wait < 20)
{
ALOGD("wait = %d", wait);
sleep(1);
wait++;
}
}
// Android.bp
cc_binary {
name: "EventHandlerTest", srcs: [
"EventHandler.cpp",
"main.cpp"
], shared_libs: [
"libstagefright_foundation",
"libutils",
"liblog"
], include_dirs: [
"frameworks/av/media/libstagefright/foundation/include"
], cflags: [
"-Wno-unused-parameter"
] }

来看执行结果吧,试验了两种情况:

1、先说失败的,将looper->start(true),这个时候好像直接卡住不动了,

2、直接调用looper->start(),这里的参数默认为false,也就是会在一个新的线程当中做消息处理。从log中来看onMessageReceived方法都是在子线程中完成,在非阻塞的情况下是和主线程并行执行的。

这边还有个现象,main函数最后没有加while循环等待时,子线程执行完onStart方法进程就结束了,并没有等待处理完stop消息

03-25 17:08:23.437 16962 16962 D MyEventHandlerTest: tid = 16962, func = main
03-25 17:08:23.437 16962 16962 D MyEventHandler: tid = 16962, func = EventHandler
03-25 17:08:23.437 16962 16962 D MyEventHandler: tid = 16962, func = setDataSource
03-25 17:08:23.438 16962 16962 D MyEventHandler: tid = 16962, func = prepare
03-25 17:08:23.438 16962 16963 D MyEventHandler: (16963)oMessageReceived: AMessage(what = 0x00000000, target = 1) = {
03-25 17:08:23.438 16962 16963 D MyEventHandler: string url = "ABC"
03-25 17:08:23.438 16962 16963 D MyEventHandler: }
03-25 17:08:23.438 16962 16963 D MyEventHandler: tid = 16963, func = onSetDataSource, url = ABC
03-25 17:08:23.438 16962 16963 D MyEventHandler: (16963)oMessageReceived: AMessage(what = 0x00000001, target = 1) = {
03-25 17:08:23.438 16962 16963 D MyEventHandler: RefBase *replyID = 0xf5b01180
03-25 17:08:23.438 16962 16963 D MyEventHandler: }
03-25 17:08:23.438 16962 16963 D MyEventHandler: tid = 16963, func = onPrepare
03-25 17:08:23.438 16962 16963 D MyEventHandler: tid = 16963, func = onPrepare, cnt = 0
03-25 17:08:24.438 16962 16963 D MyEventHandler: tid = 16963, func = onPrepare, cnt = 1
03-25 17:08:25.438 16962 16963 D MyEventHandler: tid = 16963, func = onPrepare, cnt = 2
03-25 17:08:26.438 16962 16962 D MyEventHandler: tid = 16962, func = prepare, err = 0
03-25 17:08:26.439 16962 16962 D MyEventHandler: tid = 16962, func = start
03-25 17:08:26.439 16962 16962 D MyEventHandler: tid = 16962, func = stop
03-25 17:08:26.439 16962 16962 D MyEventHandlerTest: wait = 0
03-25 17:08:26.439 16962 16963 D MyEventHandler: (16963)oMessageReceived: AMessage(what = 0x00000002, target = 1) = {
03-25 17:08:26.439 16962 16963 D MyEventHandler: }
03-25 17:08:26.439 16962 16963 D MyEventHandler: tid = 16963, func = onStart
03-25 17:08:26.439 16962 16963 D MyEventHandler: tid = 16963, func = onStart, cnt = 0
03-25 17:08:27.439 16962 16962 D MyEventHandlerTest: wait = 1
03-25 17:08:27.439 16962 16963 D MyEventHandler: tid = 16963, func = onStart, cnt = 1
03-25 17:08:28.439 16962 16962 D MyEventHandlerTest: wait = 2
03-25 17:08:28.439 16962 16963 D MyEventHandler: tid = 16963, func = onStart, cnt = 2
03-25 17:08:29.439 16962 16963 D MyEventHandler: tid = 16963, func = onStart, cnt = 3
03-25 17:08:29.439 16962 16962 D MyEventHandlerTest: wait = 3
03-25 17:08:30.439 16962 16963 D MyEventHandler: tid = 16963, func = onStart, cnt = 4
03-25 17:08:30.439 16962 16962 D MyEventHandlerTest: wait = 4
03-25 17:08:31.439 16962 16963 D MyEventHandler: tid = 16963, func = onStart, cnt = 5
03-25 17:08:31.440 16962 16962 D MyEventHandlerTest: wait = 5
03-25 17:08:32.439 16962 16963 D MyEventHandler: tid = 16963, func = onStart, cnt = 6
03-25 17:08:32.440 16962 16962 D MyEventHandlerTest: wait = 6
03-25 17:08:33.440 16962 16963 D MyEventHandler: tid = 16963, func = onStart, cnt = 7
03-25 17:08:33.440 16962 16962 D MyEventHandlerTest: wait = 7
03-25 17:08:34.440 16962 16963 D MyEventHandler: tid = 16963, func = onStart, cnt = 8
03-25 17:08:34.440 16962 16962 D MyEventHandlerTest: wait = 8
03-25 17:08:35.440 16962 16963 D MyEventHandler: tid = 16963, func = onStart, cnt = 9
03-25 17:08:35.440 16962 16962 D MyEventHandlerTest: wait = 9
03-25 17:08:36.440 16962 16963 D MyEventHandler: (16963)oMessageReceived: AMessage(what = 0x00000003, target = 1) = {
03-25 17:08:36.440 16962 16963 D MyEventHandler: }
03-25 17:08:36.440 16962 16963 D MyEventHandler: tid = 16963, func = onStop
03-25 17:08:36.441 16962 16962 D MyEventHandlerTest: wait = 10
03-25 17:08:37.441 16962 16962 D MyEventHandlerTest: wait = 11
03-25 17:08:38.441 16962 16962 D MyEventHandlerTest: wait = 12
03-25 17:08:39.441 16962 16962 D MyEventHandlerTest: wait = 13
03-25 17:08:40.441 16962 16962 D MyEventHandlerTest: wait = 14
03-25 17:08:41.441 16962 16962 D MyEventHandlerTest: wait = 15
03-25 17:08:42.441 16962 16962 D MyEventHandlerTest: wait = 16
03-25 17:08:43.442 16962 16962 D MyEventHandlerTest: wait = 17
03-25 17:08:44.442 16962 16962 D MyEventHandlerTest: wait = 18
03-25 17:08:45.442 16962 16962 D MyEventHandlerTest: wait = 19

Android 12(S) ALooper AHandler AMessage(二)的更多相关文章

  1. Android 12(S) 图形显示系统 - Surface 一点补充知识(十二)

    必读: Android 12(S) 图形显示系统 - 开篇 一.前言 因为个人工作主要是Android多媒体播放的内容,在工作中查看源码或设计程序经常会遇到调用API: static inline i ...

  2. Android 12(S) 图形显示系统 - 示例应用(二)

    1 前言 为了更深刻的理解Android图形系统抽象的概念和BufferQueue的工作机制,这篇文章我们将从Native Level入手,基于Android图形系统API写作一个简单的图形处理小程序 ...

  3. Android应用--QR的生成(二维码)

    二维码的定义: 二维码(2-dimensional bar code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的. 在许多种类的二维条码中,常用的码制 ...

  4. Android基础——项目的文件结构(二)

    Android基础--项目的文件结构(二) AndroidManifest.xml文件分析 [注]此项目文件结构仅限于Android Studio下的Android项目!!! 在一个Android项目 ...

  5. Android 12(S) 图形显示系统 - createSurface的流程(五)

    题外话 刚刚开始着笔写作这篇文章时,正好看电视在采访一位92岁的考古学家,在他的日记中有这样一句话,写在这里与君共勉"不要等待幸运的降临,要去努力的掌握知识".如此朴实的一句话,此 ...

  6. Android 12(S) 图形显示系统 - BufferQueue/BLASTBufferQueue之初识(六)

    题外话 你有没有听见,心里有一声咆哮,那一声咆哮,它好像在说:我就是要从后面追上去! 写文章真的好痛苦,特别是自己对这方面的知识也一知半解就更加痛苦了.这已经是这个系列的第六篇了,很多次都想放弃了,但 ...

  7. Android 12(S) 图形显示系统 - 初识ANativeWindow/Surface/SurfaceControl(七)

    题外话 "行百里者半九十",是说步行一百里路,走过九十里,只能算是走了一半.因为步行越接近目的地,走起来越困难.借指凡事到了接近成功,往往是最吃力.最艰难的时段.劝人做事贵在坚持, ...

  8. Android 12(S) 图形显示系统 - BufferQueue的工作流程(八)

    题外话 最近总有一个感觉:在不断学习中,越发的感觉自己的无知,自己是不是要从"愚昧之巅"掉到"绝望之谷"了,哈哈哈 邓宁-克鲁格效应 一.前言 前面的文章中已经 ...

  9. Android 12(S) 图形显示系统 - BufferQueue的工作流程(九)

    题外话 Covid-19疫情的强烈反弹,小区里检测出了无症状感染者.小区封闭管理,我也不得不居家办公了.既然这么大把的时间可以光明正大的宅家里,自然要好好利用,八个字 == 努力工作,好好学习 一.前 ...

  10. Android 12(S) 图形显示系统 - BufferQueue的工作流程(十)

    题外话 疫情隔离在家,周末还在努力学习的我  ..... 一.前言 上一篇文章中,有基本讲清楚Producer一端的处理逻辑,最后也留下了一个疑问: Consumer是什么时候来消费数据的?他是自己主 ...

随机推荐

  1. redis和memcached的区别和使用场景

    Redis 和 Memcached 都是基于内存的数据存储系统.Memcached是高性能分布式内存缓存服务,其本质上就是一个内存key-value数据库.Redis是一个开源的key-value存储 ...

  2. 消息队列Kafka「检索组件」重磅上线!

    ​简介:本文对消息队列 Kafka「检索组件」进行详细介绍,首先通过对消息队列使用过程中的痛点问题进行介绍,然后针对痛点问题提出相应的解决办法,并对关键技术技术进行解读,旨在帮助大家对消息队列 Kaf ...

  3. 如何利用 AHAS 保障 Web 服务稳如磐石?

    ​简介:应用高可用服务 AHAS (Application High Availability Service) 是经阿里巴巴内部多年高可用体系沉淀下来的云产品,基于阿里开源流控降级组件 Sentin ...

  4. 如何高效完成ECS多环境部署?

    ​简介:通过本文,你可以了解到,如何通过云效流水线有效拉通开发与运维,打破二者之间的壁垒墙,让开发与运维高效联动.在软件开发和部署过程中,我们的软件往往需要在不同的运行环境中运行,例如:开发人员本地开 ...

  5. 【视频特辑】提效神器!如何用Quick BI高效配置员工的用数权限

    ​简介:随着企业数字化进程逐步加速,企业所产生和积累的数据资源日益增多.每当员工的用数权限发生变动,管理员都需要进行复杂繁琐的重复性配置流程,不仅耗时耗力还容易出错. 如何能便捷地对员工用数权限进行高 ...

  6. Hologres揭秘:优化COPY,批量导入性能提升5倍+

    简介: 揭秘Hologres优化COPY的技术原理,实现批量导入性能提升5倍+ Hologres(中文名交互式分析)是阿里云自研的一站式实时数仓,这个云原生系统融合了实时服务和分析大数据的场景,全面兼 ...

  7. 快手基于 Flink 构建实时数仓场景化实践

    简介: 一文了解快手基于 Flink 构建的实时数仓架构,以及一些难题的解决方案. 本文整理自快手数据技术专家李天朔在 5 月 22 日北京站 Flink Meetup 分享的议题<快手基于 F ...

  8. [Blockchain] Cosmos Starport 地址前缀的变更方式

    # 在新的区块链上修改 starport app github.com/hello/planet --address-prefix your_new_prefix # 在已存在的区块链上修改 `app ...

  9. [Contract] ETH 与 Gas 之间的价格转换关系, Ethereum Gas Price Chart

    以太坊网络每天的平均气价(Gas)是变化,有一张价格表:https://etherscan.io/chart/gasprice 然后你可以知道 1 Gas = xx Gwei,再换算一下 1 ETH ...

  10. [FE] Quasar BEX 预览版指南

    BEX(Browser Extension)是 Quasar 基于同一套代码允许编译成浏览器扩展来运行,支持 Firefox & Chrome. 截止目前(2019/12/25), bex 模 ...