Multimedia Alooper 机制分析
来源:互联网 发布:淘宝产品搜索排名 编辑:程序博客网 时间:2024/06/06 00:07
android 底层的录制和播放都会用到ALooper,AHandler和AMessage,这个和上一篇讲的looper有什么不一样呢?其实作用是差不多的,只是实现的方式不一样而已。
1、looper线程的创建
status_t ALooper::start( bool runOnCallingThread, bool canCallJava, int32_t priority) { if (runOnCallingThread) { //如果传入的参数为true,就会使用当前的线程作为looper线程,否则下面会再创建一个线程作为looper线程 { Mutex::Autolock autoLock(mLock); if (mThread != NULL || mRunningLocally) { return INVALID_OPERATION; } mRunningLocally = true; } do { } while (loop()); return OK; } Mutex::Autolock autoLock(mLock); if (mThread != NULL || mRunningLocally) { return INVALID_OPERATION; } mThread = new LooperThread(this, canCallJava); status_t err = mThread->run( mName.empty() ? "ALooper" : mName.c_str(), priority); if (err != OK) { mThread.clear(); } return err;}调用ALooper的start()函数后,就会进入loop,也就是一直循环调用loop()函数,如果传入的第一个参数是true,就会让当前线程变成looper线程,否则会创建一个新的looper线程。
virtual bool threadLoop() { return mLooper->loop(); }其实就是创建一个普通线程,然后循环调用loop()函数。
2、AHandler和Alooper进行绑定
ALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) { return gLooperRoster.registerHandler(this, handler);}调用ALooper的registerHandler()接口后就能将AHandler对象和该ALooper对象进行绑定了。
ALooper::handler_id ALooperRoster::registerHandler( const sp<ALooper> looper, const sp<AHandler> &handler) { Mutex::Autolock autoLock(mLock); if (handler->id() != 0) { CHECK(!"A handler must only be registered once."); return INVALID_OPERATION; } HandlerInfo info; info.mLooper = looper; info.mHandler = handler; ALooper::handler_id handlerID = mNextHandlerID++; mHandlers.add(handlerID, info); handler->setID(handlerID, looper); return handlerID;}gLooperRoster 可以认为它是一个全局变量,主要的作用是管理AHandler和ALooper,返回的handlerID十分重要,L版本之前可以通过这个id找到对应的AHandler。
3、AMessage怎么和AHandler进行绑定
AMessage::AMessage(uint32_t what, const sp<const AHandler> &handler) : mWhat(what), mNumItems(0) { setTarget(handler);}void AMessage::setTarget(const sp<const AHandler> &handler) { if (handler == NULL) { mTarget = 0; mHandler.clear(); mLooper.clear(); } else { mTarget = handler->id(); mHandler = handler->getHandler(); mLooper = handler->getLooper(); }}创建AMessage 对象的时候可以把对应AHandler对象传入进行绑定,或者通过setTarget()函数进行绑定。
4、AMessage从发送到处理流程
1)异步消息,不需要等待执行结果
post()到ALooper后,会把AMessage插入到mEventQueue队列中,此时把Message封装到Event中。
void ALooper::post(const sp<AMessage> &msg, int64_t delayUs) { Mutex::Autolock autoLock(mLock); int64_t whenUs; if (delayUs > 0) { whenUs = GetNowUs() + delayUs; } else { whenUs = GetNowUs(); } List<Event>::iterator it = mEventQueue.begin(); while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) { ++it; } Event event; event.mWhenUs = whenUs; event.mMessage = msg; if (it == mEventQueue.begin()) { //如果需要插入到队列头部,则发一次信号 mQueueChangedCondition.signal(); } mEventQueue.insert(it, event);}
上面的post()后,会把Event(AMessage)插入event队列中,如果插在头部,会发一次信号到loop()中。
bool ALooper::loop() { Event event; { Mutex::Autolock autoLock(mLock); if (mThread == NULL && !mRunningLocally) { return false; } if (mEventQueue.empty()) { mQueueChangedCondition.wait(mLock); return true; } int64_t whenUs = (*mEventQueue.begin()).mWhenUs; int64_t nowUs = GetNowUs(); if (whenUs > nowUs) { int64_t delayUs = whenUs - nowUs; mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll); //收到信号或者等待超时后会返回 return true; } event = *mEventQueue.begin(); mEventQueue.erase(mEventQueue.begin()); } event.mMessage->deliver(); // NOTE: It's important to note that at this point our "ALooper" object // may no longer exist (its final reference may have gone away while // delivering the message). We have made sure, however, that loop() // won't be called again. return true;}收到信号后,mQueueChangedCondition.waitRelative()会返回true,重新跑一次loop(),这时如果队列中的第一个消息需要马上处理(whenUs > nowUs 不成立),会继续往下跑,从队列中取出第一个消息,并从队列移除,调用event.mMessage->deliver();就走到了后面AHandler的消息处理流程。
2)同步消息,需要等待消息处理完成之后才返回
和异步消息的流程差不多,只不过多了等带AHandler处理完消息后并postReply()后才会往下走,并且得到一个AMessage类型返回结果。AMessage可以保存很多类型的数据,通过<ker,value>的形式,在传递参数时,使用起来十分方便,有兴趣的同学阅读源码深入了解。
对比一下:
Looper 通过epoll_wait()等待事件触发或者超时。
int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
ALooper通过waitRelative()等待信号或者超时。
mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll);
阅读全文
0 0
- Multimedia Alooper 机制分析
- 3 Alooper分析
- ②NuPlayer播放框架之ALooper-AHandler-AMessage底层机制分析
- 安卓异步消息处理机制ALooper
- libstagefright 框架设计分析 (1): ALooper, AHandler
- Android Media Player 框架分析-AHandler AMessage ALooper
- [Multimedia][图像]PNG格式分析
- Qt Multimedia::QMediaPlayer框架源码分析
- android native ALooper AHandler
- Multimedia Networking
- MultiMedia eXtensions
- multimedia framework
- multimedia sync
- multimedia programming
- Android Multimedia
- Multimedia Timers
- Multimedia memory
- Multimedia Application Programming Guide
- bzoj2850巧克力王国 K-Dtree
- SpringMvc和Struts2 比较
- xml、dtd、SAX解析、DOM解析、DOM4J解析学习
- 怪诞心理学读书笔记
- Debian 9 安装 NVIDIA显卡驱动
- Multimedia Alooper 机制分析
- 线程基础:多任务处理——Fork/Join框架(基本使用)
- 神经网络模型学习笔记(ANN,BPNN)
- MongoDB的Journal
- MySQL服务未打开 导致tomcat启动时报出N多无关异常
- neural networks deep learning Planar data classification with a hidden layer参考答案
- poj1860Currency Exchange
- 最短路
- 1026:求s=a+aa+aaa+aaaa+aa..a的值