Chinaunix首页 | 论坛 | 博客
  • 博客访问: 914259
  • 博文数量: 75
  • 博客积分: 6236
  • 博客等级: 准将
  • 技术积分: 726
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-03 14:43
文章分类

全部博文(75)

文章存档

2019年(1)

2018年(6)

2017年(4)

2015年(1)

2014年(9)

2013年(1)

2012年(3)

2011年(9)

2010年(3)

2009年(2)

2008年(4)

2007年(24)

2006年(8)

我的朋友

分类:

2007-04-06 15:08:50

摘要:回调机制是BREW平台中最关键的机制之一,很多接口类都是通过回调机制呈现在开发人员的面前,《对AEECallback结构体及其基础函数的分析》中队brew/src/thrdutil中的一些源代码进行分析,初略的理解了AEECallback结构体及其相关函数的实现,对开发能有一定的帮助,本文则更加深入的分析了该机制的特点,以及高通工作人员给出的一些答案。
 
:非常感谢手机之家_开发联盟的superant, 东方欲晓, record等人,是他们激烈的讨论才引出了最后的答案。本文很多内容都摘自他们的帖子。
 
BREW平台的回调机制,通常是异步的,举例来说,在网络通信的时候,如果是发送数据,普通的方式是发送一快数据,判断是否发送成功,如果发送不成功,则空闲一段时间,在调用发送数据的函数,如此往复,但是如果在BREW平台上,调用发送函数发送数据,如果发送成功,函数会返回发送成功的字节数,如果返回的是-2,表示当前发送不成功,接下来,需要通过_Writeable注册一个回调函数,BREW会根据网络状况调用你注册的回调函数,继续发送需要发送的数据,直到所有数据发送成功。同样的道理,在接收数据的时候,如果数据量比较大,不是一次能够接收完,通常来说就是通过_Readable函数来注册接收回调函数,当有数据到的时候就会调用你注册的回调函数接收数据,直到所有数据接收成功。
 
BREW平台回调机制的实现有几个关键的部分下面一一介绍。
Callback机制中的核心数据结构:
struct _AEECallback
{
    AEECallback *pNext;
    void        *pmc;
    PFNCBCANCEL pfnCancel;
    void        *pCancelData;
    PFNNOTIFY    pfnNotify;
    void        *pNotifyData;
    void        *pReserved;
};
该结构体的每一个成员在《对AEECallback结构体及其基础函数的分析》中有介绍,在此略过。
从结构的命名中可以猜测,其实AEECallback结构体是以链表形式存在,其中的pNext成员就是起到遍历链表的作用,该链表由系统维护。
CALLBACK_Init和CALLBACK_Cancel是两个关键函数。CALLBACK_Init负责对AEECallback结构体进行初始化,该函数的参数列表第二个参数是PFNNOTIFY类型,就是需要回调的函数的函数指针类型,第三个参数是传递给该回调函数的参数指针,类型是void型指针。CALLBACK_Cancel函数是取消回调函数,也就是调用AEECallback结构体中的pfnCancel指针指向的函数来取消回调。
ISHELL_Resume()函数允许向 AEE 外壳注册回调。 它可以向 AEE 外壳的待处理操作列表中添加回调。 AEE 外壳将在下一次调用事件循环时调用此回调函数,以使应用程序或对象协同处理多任务。如果已注册回调,则会先将其注销,然后再重新注册。
 
举例来说,我们在APPLET里中定义m_pCB为AEECallback类型,调用CALLBACK_Init(&pme->m_pCB,FUNC1,pme),意在初始化m_pCB,将函数FUNC1注册到这个结构体中,这时候,m_pCB中的pfnNotify就指向了FUNC1,任何时候,不管是开发人员自己写代码调用ISHELL_Resume()函数,还是通过调用其它函数(BREW平台的APIs),在这些函数中有隐含的调用ISHELL_Resume(),该函数都会在BREW系统的回调链表中添加一个节点,该节点就是m_pCB,那么在适当的时候,BREW就会调用你的FUNC1函数。其实在很多BREW APIs中都会有调用ISHELL_Resume(),例如ISHELL_SetTimerEx()函数,不过这个只是猜测,因为根本无法看到该这些函数的原代码。
 
归纳起来,如过要使用BREW平台的回调机制,则只要初始化适当的AEECallback结构体,再在需要回调的时候调用ISHELL_Resume来启动回调函数 。
 
下面来叙述一下BREW平台的消息机制和回调机制的大概流程:
 
我们假设BREW运行于Ui Task,特定于BREW的Sig为AEE_APP_SIG。
 
For(;;)
{
  waitfor sig         // 无限循环,捕捉到相应的Sig后,作相应的处理
}
 
if (receive aee app sig)
{
  AEE_Dispatch         // 如果收到AEE_APP_SIG 说明BREW需要执行,调用AEE_Dispatch进行消息循环分发。
}
 
其中AEE_Dispathc是最关键的函数,他会检查BREW事件队列中的所有事件一一分发(调用APP->HandleEvent函数),同时也会检查Callback队列中注册的Callback,一一回调。所有都处理完后,表示本次BREW循环结束,将运行环境切换回UI Task中的其他非BREW程序,或者切换至其他Task。当下次BREW再需要执行时,BREW将再次设置AEE_APP_SIG,从而导致当系统任务调度到UI Task时,AEE_Dispatch再次被调用,以此往复。
 
关于在ISHELL_Resume注册完回调函数之后,具体会在什么时候调用回调函数,这个并没有深究的价值,在Callback对列中,BREW根据自身的算法选择回调,当一个时间片不够回调所有的Callback的话,则会把未完成的Callback放到下一个或者下几个时间片执行。所以,对于正常的概念来说,只需要知道,当执行了ISHELL_Resume之后,很短的时间内BREW会调用完成Callback的调用。
阅读(3954) | 评论(2) | 转发(0) |
0

上一篇:谈手机软件

下一篇:MIDP3.0新增特性介绍

给主人留下些什么吧!~~

chinaunix网友2010-07-09 12:43:50

请问前辈,如何编一个可以捕获手机屏幕大小,然后能自适应的程序 我想将一个游戏改成在所有手机屏幕上都能运行的游戏。请指教。QQ704232694 邮箱09mtpeng@stu.edu.cn

chinaunix网友2010-07-09 12:43:42

请问前辈,如何编一个可以捕获手机屏幕大小,然后能自适应的程序 我想将一个游戏改成在所有手机屏幕上都能运行的游戏。请指教。QQ704232694 邮箱09mtpeng@stu.edu.cn