WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章手机编程BREW深入BREW消息处理机制

深入BREW消息处理机制
作者:东方欲晓  来源:本站整理  发布时间:2008-4-8 1:14:04

消息处理机制,即event driven和传统的编程机制不同,如dos,unix下的c编程,他没有main loop,程序的流程不是顺序执行的。有过window编程经历的读者都会清楚这种机制。
   Windows下消息处理机制:当在交互中进行一个action(or signal, or input, etc),window产生相应的event,通过window的event dispatch机制,相应的窗口或者app得到该event,从而触发相应的 event handler fun进行处理。
   BREW下消息处理机制简而言之也相似,即BREW环境(这里是AEE Shell)捕捉到event后,dispatch到相应的app或者control,由其event handler fun处理。
   区别:我们知道BREW的体系结构采用了COM方式,即具有面向对象的类层次结构,从而其具体的event handler fun也是作为各个Interface的外露的接口函数的形式被运用。一个applet本质上来说就是一个实例化的IAPPLET类,所以这样就统一了所有在applet中运用的event handler fun都是各个Interface的外露接口函数的说法。
   具体而言,这些event handler fun还是有区别的,主要是IAPPLET_Handleevent和其他Interface的Handleevent的区别。
   IAPPLET_Handleevent是通过在AEEClsCreateInstance中的AEEApplet_New函数被注册实例化的,AEEApplet_New函数实例化用户的APPLET的Class同时也通过传入USERAPP_HandleEvent参数实例化了IAPPLET_Handleevent。
   除了IAPPLET具有handleevent外,所有的继承Icontrol接口的Interface也具有事件处理函数,允许处理事件。这些各种具体的Icontrol_handleevent有两种方式被调用。一种是在applet的handleevent中由programmer显式的调用,如:
switch (eCode)
{
     case EVT_APP_START:                            
 ………
      return(TRUE);
     case EVT_APP_STOP:    
……….
         Case EVT_KEY:
IMENU_Handleevent….
ItextCtl_Handleevent….
另一种是当这些Control包含于Dialog中,且处于focus状态时,这些事件处理函数的触发是隐式的,是由AEE机制自动触发的,无需在代码中显式的调用这些handleevent。
Idialog接口没有外露的handleevent接口函数,但是允许通过Idialog_seteventhandle来注册一个该Dialog的事件处理函数。需要注意的是,该事件处理函数是何时被触发的:一旦当一个dialog处于active时,aee shell将会把所有的event直接发往该dialog,该dialog会自动的调用处于focus的control的handleevent来处理该事件,只有当该control没有处理该事件时,dialog注册的事件处理函数才会被调用。
Brew中的handle event函数都是boolean返回类型的,这是为了实现事件处理的层次机制,当该层上的handle event没有处理该事件时,应该返回false,以便上层对该事件感兴趣的handle event来处理。 如果处理了,应该返回TRUE,说明该事件已被处理,无需其他层再处理。
有了以上知识后,下面给出完整的BREW环境下消息分发和处理的流程。
首先BREW存在于一个task中,尽管允许brew运行于一个单独的task中,但是实际oem中都是将其运行于现有的一个task中,比如ui task。
当brew运行后,首先ui task中捕捉到各种事件,此时ui task通过aee_dispatch将事件分发至brew环境中,brew环境再通过aee_sentevent具体分发事件至目的地。接着在两种不同的情况下将走不同的流程。
   如果当前没有active dialog,则紧接着IAPPLET_Handleevent被brew自动调用来处理事件,而此时调用的IAPPLET_Handleevent其实就是用户注册的自己的applet_handleevent。从而实现了允许用户app捕捉到事件并处理的机制。在用户的app handleevent中,用户可以将事件继续下发,比如通过调用IMENU_handleevent等将事件下发给各种控件处理。
   如果当前有active dialog,则紧接着Adialog_event被brew自动调用,从而使得事件被dialog最先截获,而dialog之后的处理是检查包含的控件中哪个处于focus,并将事件下发给它的handleevent来处理,同时根据其返回值来判断其是否已经处理了该事件,当其返回False后,dialog将该事件继续转发至该dialog注册的handleevent(如果有的话),如果该handleevent仍然返回false,brew继续将该事件转发至app handleevent。这种机制使得当以dialog方式来创建应用时,各种event被自动的处理,从而简化了代码量,但也使得事件流程更加晦涩,用户的程序不能直接的控制它。
   最后,结合一个我工作中的问题,来加深对brew事件处理机制的理解。
   这是一个关于输入法的问题,当在textctl中进行输入时,如果是拼音和笔画输入时,情况比较复杂,大致如下:
   app handleevent调用itextctl_handleevent来处理按键事件,itextctl_handleevent的oem实现中最后会创建一个拼音dialog(pinyindlg)用来显示输入的拼音和候选字,同时注册一个dialoghandler(pinyindlgevent), pinyindlg中包含一个control(ipinyinmanager),它的handleevent(ipinyinmanager_handleevent)主要来处理用户拼音输入时如何显示候选字等等一系列的复杂任务。
这样的话,当处于拼音输入模式时,输入第一个字母后,就创建了pinyindlg来显示候选字,同时ipinyinmanager_handleevent被激活,之后按的任何键都会直接调用该ipinyinmanager_handleevent来处理,且该handleevent均返回true,表示正确处理了。
   如此,则所有按键事件将均被ipinyinmanager_handleevent截获,app,以及itextctl均没有机会处理事件。那如何退回到text控制之下那?以便进行其他操作,比如删除,切换,保存等。
这是通过在ipinyinmanager_handleevent中对特殊的键进行特殊处理来实现的,比如定义clr为退回至text控制,则在ipinyinmanager_handleevent中当key为avk_CLR时,return false,从而使得pinyindlg注册的pinyindlgevent有机会被调用,而在这个handleevent中release pinyindlg,并且返回true。这样就release了dlg,从而使得下次的按键可被app捕获,由app handleevent 传给itextctl_handleevent,从而成功的使得event处理的焦点回到了itextctl。这里return true是为了避免同时删除最后一个汉字(false使得itextctl_handleevent再次处理该clr,就会删除一个汉字)。
   我们知道,应用可以设置maxchars来限制text中输入的最大字符数。当输入为字

[1] [2]  下一页

[] [返回上一页] [打 印]
文章评论

用户名: 查看更多评论

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

         (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码