在ETel第三方API(CTelephony)中使用User::WaitForRequest() 应注意的问题

 

在ETel第三方API(CTelephony)中使用User::WaitForRequest() 应注意的问题

ETel第三方API(即CTelephony)是做为异步模式来设计的,从一个活动对象调用它的方法,然后就等待这个方法的完成。做为活动对象所定义的概念来说,一次只能有个一个active request存在。

Telephony的异步工作模式使得它无论何时检测到一个方法被调用时(这时TRequestStatus 参数被传入该方法),已经是KRequestPending状态的情况下,都会引发一个异常(Telephony 0)。
一般在Symbian程序员中流传的使异步变同步的方法就是调用User::WaitForRequest来锁定该线程直到方法完成(这个方法是不被提倡的)
这样做主要有两个问题:
1、异步工作模式可能会花费较长的执行时间才能完成,这样线程就一直处于阻塞模式下,这样可能会引发VIEWSERV 11异常(参考Symbian FAQ-0920)
2、该异步方法的完成可能依靠同一个线城中其他活动对象的工作,而如果阻塞线程的话,那这个异步工作将永远无法完结。
我们在一个具体的CTelephony事例中来考虑问题:

CTelephony::TBatteryInfoV1 batterystrength;

CTelephony::TBatteryInfoV1Pckg battery(batterystrength);

CTelephony* tel = CTelephony::NewLC();

TRequestStatus status = KRequestPending; // (1)

tel->GetBatteryInfo(status, battery);

User::WaitForRequest(myStat); // (2)

CleanupStack::PopAndDestroy();

这个将意味着:
1、TRequestStatus变量被初始化为KRequestPending(第 (1)行),这是一个常见的错误,会引发CTelephony报Telephony 0错误(如上所述),注意一般来说是没有必要对TRequestStatus进行初始化的。

2、如果第(1)行被删除,那代码也永远无法回到第(2)行,因为在线程被阻塞的情况下CTelephony 的异步方法是无法被完成的。

结论就是CTelephony应该一直使用异步工作模式,另外使用User::WaitForRequest 时一定要谨慎。

程序的自启动的动态配置

目前,在S60第三版中,如果一个程序想要自启动,你可以通过启动列表管理API来完成它。具体信息可以在 S60 3rd Edition SDK中找到。
为了进行Symbian Signed criteria的传递,你需要在你的程序中提供对自启动的取消功能。暂时没有公开的API可以帮助你解决这个问题,下面有两个解决方案:
1)设计一个启动程序,它可用来启动一个实际的应用程序。无论手机何时启动该启动程序需被自动开启。然后它检查配置文件(.ini),如果配置文件中该boot 选项被标记为开启,那就去启动响应的实际程序,如果为关闭,那就终止自己,当然也不需要去启动实际程序了。

注意在启动程序成功启动实际程序后它不能立刻将自己结束掉,否则实际程序将因此而无法成功运行。

在实际运用中,第三方程序可以找到一个公共位置去存放配置文件,或者为两个程序(启动程序和实际程序)准备一个公共的secure ID。RVCT编译程序可以帮助你解决这个问题。

2)你也可以安排手机开启后每次都去启动实际程序,在开始阶段就去检查配置文件,如果其中的flag被标记为 ON,则继续运行它自己,如果flag被标记为OFF,则需要调用CAknAppUi::Exit()函数来结束自己。
同第一个方案相比,这个方法不需要去解决两个程序同时拥有一个secure ID的问题。这样如果程序十分大,并且用户不是选择每次都自启动的话,我们可以花费更多CPU时间在加载程序上。
从Symbian Singed的角度来看,第二个方法要优于第一个。

如果控制一个进程中的堆分配

我的程序试图从堆上分配一定内存,却产生了失败。我该怎么做才能分配到更多内存呢?
我们可以在.mmp中通过EPOCHEAPSIZE命令直接来保留或压缩一定内存空间,这样进程在启动时就能使用。
Syntax: epocheapsize minimum maximum
最小值(以字节为单位,一般为4K左右)以保证进程的正常运行。
最大值说明进行所能使用内存的数量限度。
要获取更多信息可参考Symbian FAQ知识库:
http://www3.symbian.com/faq.nsf/0/8D…5?OpenDocument

在S60上编写一个有发送短信功能的程序

根据下面Forum Nokia上的示例来写一个具有短信发送能力的程序是很简单的。根据不同的目标平台,有两种方法可选择,在早期的S60和S80设备上一般使用一个客户端的MTM API,而S60第三版中

则介绍了一个更为高级易用的API。
2nd Edition platforms:
在S60 第二版和S80平台上如果要发送SMS程序可以直接使用SMS Client MTM来进行信息发送。早期的平台上对开发者来说主要的问题是其中一部分需要的API不是公开的,不过在S60 2nd和S80 2nd中已经解决了。
Forum Nokia已有SMS示例,它将教你一步步来生成并发送一个短信。可以通过下列连接查看:
S60 Platform: SMS Example
http://www.forum.nokia.com/info/sw.n…_0_en.zip.html

3rd Edition:
在S60第三版上通过新的SendAs API我们可以更加容易的发送短信。这是封装在messaging client MTMs上的API,通过它们你的程序可以去访问所有支持的messaging protocol,而不光是sms messaging。

S60第三版也支持对MTM的直接使用。
可以通过下列连接去找到在MTM方法和新的SendAs方法的示例:
S60 Platform: SMS Example
http://www.forum.nokia.com/info/sw.n…_0_en.zip.html
Related topics:
Forum Nokia Messaging examples (C++)
http://www.forum.nokia.com/main/1%2c…0_11%2c00.html
Messaging discussion on Forum Nokia C++ developer’s board
http://discussion.forum.nokia.com/fo…splay.php?f=26
Messaging in Symbian Developer Library - online API reference
http://www.symbian.com/developer/tec…reference/cpp/
2007-4-17 08:21 Cotuvdi
存放应用程序图标的文件夹名的本地化问题

应用程序可以选择安装后存放的菜单目录文件夹,在S60第一版和第二版中,文件夹的名称可在AIF_DATA 资源中进行定义,在application information file(.aif)代码为:
RESOURCE AIF_DATA
{

groupname = “Games”;
}
在S60第三版中,该定义是放在app中完成的,registration file(_reg.rsc)代码为:
RESOURCE APP_REGISTRATION_INFO
{

group_name = “Games”;
}
其中有一些名字可通过组名 (group_name)参数被本地化识别。如果这样使用的话,那图标将放在会放置在相应合适的目录下,该目录回根据所选语言有个本地化名称。本地化名的文件夹们在设备和

S60平台版本系列中并不是一成不变的。但至少下列名称是被所有基于S60第二版FP1或更新版的机器所支持的:
Communications
Configurations
Games
SIM
Tools

但是你需要知道的是,同样的组名也会被不同的机器映射为不同的名称,例如,在一些S60第三版设备上会将 Tool和Configurations都映射为Tool文件夹,其他设备会将Tools映射到缺省安装的目录

下(“Extras”,“My Own”,或“Install”,具体根据设备来判断)如果该组名无法被识别或不存在,那就会产生一个新的。

并不是所有的文件夹都有个可适合本地化的组名。如果在S60第三版上使用“Office”组名,就会在非英文机上产生一个新的“Office”文件夹。
正是因为这些原因,我们一般建议为他们的图标使用缺省的组名。如果游戏类程序就用“Games”做为组名,这样被本地化并放在S60手机正确的菜单位置。
如果应用程序需要被放置在一个不能被识别的组名文件夹里,如“Office”,我们还可以去为它进行本地化注册工作。下面是一个示例,来注册“Office”文件夹以支持英语和法语。在这样的情况

下,资源编译器将生成两个版本的注册文件,_reg.r01和_reg.r02
RESOURCE APP_REGISTRATION_INFO
{

#if defined(LANGUAGE_01) // English

group_name=”Office”;

#else if defined(LANGUAGE_02) // French

group_name=”Bureau”;

#else // Other languages

group_name=”Office”;

#endif

}

如何指定最大和最小堆内存

在一台手机(或SDK的模拟器)上会有一定的物理内存大小,而你的应用程序将获取一部分做为堆内存使用。
当你程序启动后产生进程,会有一个预先分配的堆给其使用。S60第三版设备上缺省大小是4KB,早期的S60平台上是1KB。
根据需要,应用程序可以自由分配更多的堆内存,程序能使用的堆大小可在1M范围内动态增加,这是操作系统所规定最高极限了,呵呵。
如果试图分配的内存超过所能最大限制,将引发KErrNoMemory异常。
大部分Symbian C++程序在这样的堆内存安排下可以正常工作,但有时间我们需要更大的堆内存来工作。我们可以通过MMP文件中使用EPOCHEAPSIZE命令来指定最大和最小堆内存。
例如
TARGET MemoryTest.exe

TARGETTYPE exe

UID 0x00000000 KMemoryTestUID3

SECUREID KMemoryTestUID3

VENDORID 0x00000000

CAPABILITY NONE

EPOCHEAPSIZE 0x5000 0x400000

EPOCSTACKSIZE 0x5000

....
在上述代码中,应用程序描述了它所需要的最大和最小堆内存,分别是0x5000字节 (20KB)和0x400000字节(4MB),现在该程序可以安全来分配一块3MB的堆空间。
Note: As documented, prior to S60 3rd Edition the EPOCHEAPSIZE statement has no effect on WINS32 platforms.

在上述代码中,应用程序描述了它所需要的最大和最小堆内存,分别是0×5000字节(20KB)和 0×400000字节(4MB),现在该程序可以安全来分配一块3MB的堆空间。Note: As documented, prior to S60 3rd Edition the EPOCHEAPSIZE statement has no effect on WINS32 platforms.在对一张使用逐行编码的JPG图片进行解码时,会出现“内存不够”的错误

详细描述:
在对使用逐行编码的JPG图片进行解码时将比对使用顺序编码的JPG图片解码占用更多内存。
列如当使用CImageDecoder类对一张较大的逐行编码JPEG进行解码时,CImageDecoder::Convert()将会获得KErrNoMemory(-4)错误。
应用程序增加堆的大小将有助于这类问题的解决,我们可以在.mmp文件中使用EPOCHEAPSIZE 命令进行调整,如:
EPOCHEAPSIZE 0×1000 0×200000
这样将初始化的堆大小从4KB(缺省)调整到2MB

解决方案:
我们可以通过在.mmp工程定义文件中使用epocstacksize命令行来修改缺省的 8KB大小。
epocstacksize stacksize
堆栈的大小,可以通过十六进制或十进制来指定。但这对 winscw/wins平台是无效的。
列如下面这行将堆栈大小增加到20KB
epocstacksize 0×5000
同样,我们也可以在产生新线程时定义该线程的堆栈大小。

S60第三版中最小缺省堆栈大小

说明:在S60第三版中缺省的堆栈大小只有8KB,这对大多数复杂程序来说是不够的

详细描述:
在symbian OS v9中缺省的堆栈大小从20kb缩减到8kb,以优化内存的消耗。这主要是因为平台安全性导致了在系统中同时运行的进程增多。
实际上,8kb的堆栈大小对任何一个稍大的S60程序来说都是不够的。如果在当前设备上缺省的堆栈能运行你的程序,那因为堆栈的溢出(平台库的消耗而引发堆栈的增长),它也很容易引发崩溃。在S60第三版SDK中建议所有程序都增长到20KB堆栈,这需要为此重新编译。

解决方案:
我们可以通过在.mmp工程定义文件中使用epocstacksize命令行来修改缺省的 8KB大小。
epocstacksize stacksize
堆栈的大小,可以通过十六进制或十进制来指定。但这对 winscw/wins平台是无效的。
列如下面这行将堆栈大小增加到20KB
epocstacksize 0×5000
同样,我们也可以在产生新线程时定义该线程的堆栈大小。

蓝牙L2CAP错误-6305

详细描述:
该错误是因为物理上连接和断开事件冲突所引起的。有时间物理连接中,HCI处传输状态时,程序会出现发送间隔。S60第二版,FP3在连接实际被关闭时会允许新的激活,这就是-6305错误所在原因。对这个问题一个解决方案是保持通道通讯而避免物理连接的空闲时间中断连接。

解决方案:
在S60第三版中该问题被修正了。

S60上不再支持CMdaAudioConvertUtility

说明:
S60上不再支持CMdaAudioConvertUtility

详细描述:
CMdaAudioConvertUility做为Symbian’ Media Client Audio API的一部分,从S60第二版SDK, FP1后就不再被支持。
当在新平台使用时,所有 CMdaAudioConvertUtility::OpenL()所返回的变量将为KErrNotSupported错误代码。

解决方案:
Audio convert utility在S60上不再被支持,流媒体程序不再需要将声音先转成PCM中间格式,取而代之的是我们可以直接将压缩的声音数据向流中传递或从中接收,只需在初始化流对象时提供一

个被支持的数据类型(fourCC代码)。
如,使用CMdaAudioInputStream从 AMR-NB格式中直接读取声音数据:
void MyStreamClass::MaiscOpenComplete(TInt aError)

{

iInputStream->SetDataTypeL(KMMFFourCCCodeAMR);

}

使用Ctrl+V(粘贴)上时所引发的程序错误

说明:
在可编辑的文本输入框中拷贝粘贴文本时会引发异常

详细描述:
这个情况只在E61手机上出现,并且版本号为1.0610.04.04
一些第三方的程序复制文本到剪贴板后在可编辑文本框中进行粘贴操作时(Ctrl+V),会引发WSERV 66异常而崩溃掉。这是因为该应用程序没有SwEvent兼容性。

解决方案:
在E61机型(版本1.0610.04.04)上运行的程序,当处理Ctrl+V(粘贴) 时需要SwEvent兼容来避免WSERV 66异常,不过这个问题在后继版本中被修复了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值