BREW Notify机制使用注意点

BREW Notify机制使用注意点

毛晓冬

2007-10-12

一、注册Notify的注意点:

       a. 注册方式:

BREW中有两种注册Notify的方式,一种是在MIF文件中Add Notification,一种是在代码中通过调用ISHELL_RegisterNotify来显式的注册NotifyMIF文件中注册的Notify,从BREW初始化后就开始生效,所以从此刻开始,App就可以收到Notification,即便App不在运行。代码中注册的Notify,从执行ISHELL_RegisterNotify后开始生效,所以如果App是在On Start时调用ISHELL_RegisterNotify进行注册,那么只有App运行后才可能收到该Notification。通常情况下,如果应用需要从开机开始就能收到Notification,即便应用不再运行,那么可以使用在MIF中注册Notify。否则可以在Code中注册Notify

       b. 如何注册多个Mask

有一点需要明确的,就是BREW Notify注册时,Mask32bit的,高16位为VALUE,低16位为NMASK。对于同一个应用对同一个Notifier注册的多个MaskVALUE相同的Mask将被覆盖(后注册的有效),而VALUE不同的Mask将不会被覆盖,BREW会单独保存每个纪录。所以,对于VALUE相同的多个Mask的注册,必须由App先进行位或运算,然后再注册,否则会出问题(非常重要,因为大部分的Mask,高16位的VALUE都是一样的,都为0)。而对于VALUE不同的Mask,则依次单独注册它们。

Case1应用如果想注册多个VALUEKey Notification,例如AVK_UPAVK_DOWN,此时,相应的Mask0xE0310040, 0xE0320040. 如果在MIF中注册,则只需Add相应的两个item即可。如果在Code中注册,则必须单独的依次注册,即

ISHELL_RegisterNotify(,,,0xE0310040);

ISHELL_RegisterNotify(,,,0xE0320040);

而不应该先或然后再注册,如:

ISHELL_RegisterNotify(,,,0xE0320040|0xE0310040);

这样的话,实际注册的就变成0xE0330040了,是AVK_LEFTNotification了。

Case2:应用想同时注册NMASK_SHELL_INITNMASK_SHELL_START_STATUSNMASK_SHELL_MOD_LIST_CHANGED,由于这些Mask只有低16位的NMASK,而没有高16位的VALUE,所以它们的VALUE都是相同的,即为0。那么,此时如果在MIF中进行注册,也没什么问题,单独的Add每个item即可,但是如果在Code中注册,则必须先进行或运算,然后再去注册,即:

ISHELL_RegisterNotify(,,,NMASK_SHELL_INIT|NMASK_SHELL_START_STATUS| NMASK_SHELL_MOD_LIST_CHANGED);

如果单独的一次次注册,则后者永远会覆盖前者。(注意,即便MIF中已经有相应注册的Notify了,此时在Code中想再增加注册一个Notify,如果VALUE一样的话,也必须先或MIF中的Mask,然后再注册)。

 

二、取消Notify的注意点:

       要取消一个应用对一个Notifier的所有注册的通知,则调用ISHELL_RegisterNotify并传入0x0Mask即可。BREW不会自动取消相应注册的通知,即便应用退出了。只有应用显式的调用接口取消通知,或者BREW整个环境退出才会导致通知的取消注册。

       要仅仅取消某几个已经注册的Mask,而不是全部。那么对于VALUE相同的Mask,只需要使用位运算(与非)剔除当前已注册的MaskApp需要保存)中的特定位,然后使用新的Mask再注册一下即可。如果VALUE不一样,则比较麻烦,一种可行的方式是,先取消全部的(使用Mask 0x0),然后再依次注册想要注册的。

 

三、运行时动态调整Notify的注意点:

这里指的是,可能增加新的Mask和取消旧的Mask同时发生。其规则其实和上面提到的一致,App只需要保存当前已注册的所有Mask,然后再根据VALUE相同和不相同的情况作不同的操作即可。一种较好的方式是,总是先取消所有的,然后再注册当前想注册的。

 

四、接收Notify的注意点:

       a. 避免Dead-Loop:

应用在收到EVT_Notify的处理中,不得同步的再次调用ISHELL_RegisterNotify或者ISHELL_Notify来注册或者Trigger Notify,这会引起死循环,导致Crash。如果应用的确需要如此,建议使用BREWAEECallback Resume到下一个循环再操作。

       b. Consume Notification

应用收到Notification后,可以Consume这个Notification,即禁止BREW再将该Notification发给其他注册的App。方法是:将传入的AEENotifyst置为NSTAT_STOP,即:

(AEENotify*) dwParam->st = NSTAT_STOP;

这种Consume Notification的方法,可以使得某些复杂的逻辑处理变得非常简单,举个实际的例子:

手机的侧健在某些特定情况下用来调节音量,假设需求是,当前在MP3的应用界面,或者当前MP3在进行后台播放,按侧健自动的调节MP3的播放音量,其他情况下,按侧健会弹出手机的音量调节界面,来调节手机默认的音量。

对于这种需求,采用Consume Notification的机制后,就非常容易实现,手机音量调节的应用Vol App开机时注册侧健的Notify(不能在MIF中注册,原因下面会提到,需要由CoreApp代为触发注册)MP3 App在启动或者后台播放MP3时注册侧健的Notify,退出或者停止(完成)播放时取消注册。并且,MP3 App收到侧健的Notify后,进行相应的音量调节后,Consumenotification。而Vol App收到侧健的Notification后,启动自身并弹出界面供用户调节。由于BREWNotification的投递顺序和应用的注册顺序(必须是Code中注册的)相反,所以运行中可以很好的满足需求,当MP3在播放时,侧健的通知永远先发给MP3,所以MP3有机会Consume它。这里需要提及的是,在MIF中注册的notify,其投递顺序不可知,所以上面的Vol App的侧健的Notify必须由CoreApp代为在开机触发注册,而不可以在MIF中注册。

另外需要注意的是,这里提到的是CoreApp代为在开机时“触发”注册,而不是“替代”注册。BREW中的Register Notify存在安全检查,注册执行的环境和被注册的App CLSID必须同属于一个Module的环境,即,只有App本身可以为自己注册Notify,或者同属于一个ModuleApp中可以为该Module的其他App注册Notify。当不能满足这种情况,但是必须跨App间产生注册时,可以使用一种“触发机制”,即,由App A触发App B在其自身的环境中进行注册,通常采用SendEvent即可以做到。如上面的需求,Vol App必须在开机时注册Notify,但是又不能在MIF中注册,则可以让CoreApp在开机后,SendEvent一个特殊事件给VolApp,导致VolApp的环境被创建,此时VolApp就可以在自己的环境中,当收到该特殊事件时,进行注册了。

 

 

五、Trigger Notify的注意点:

Notifier的实现者,在Trigger Notify,即调用ISHELL_Notify或者AEE_Notify发出Notify时,必须保证执行的环境是BREW Task的正常环境。如果是其他Task,则该投递会直接失败,Notify不会被投递出来。典型的在其他Task中发出Notify的方式是,使用BREWAEE_ResumeCallback先切换到BREW的系统环境中,然后再发出Notify

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值