忆龙2009:Brew FAQ-常见问答(1)

来源:互联网 发布:网吧服务器攻击软件 编辑:程序博客网 时间:2024/04/29 18:33

(1)如何能够将已编译的应用程序传输到电话上?
使用 BREW AppLoader 将应用程序上载到电话。以下示例显示了 名为 "myapp" 的应用程序的文件和位置。

/brew/sch/myapp.mif - 由 BREW MIF 编辑器生成
/brew/sch/myapp/myapp.bar - 由 BREW 资源编辑器生成
/brew/sch/myapp/myapp.mod - 使用 ARM BREW 编译器编译和链接
/brew/sch/myapp/myapp.sig - 数字签名

电话上的所有目录和文件名都必须采用小写形式。特定于您的应用程序的附加文件也可能要复制到应用程序目录, 或应用程序目录的子目录。

数据签名是使用 BREW TestSig Generator 生成的,随后会用应用程序名称重命名。.sig 文件名的第一部分必须与 .mod 文件名的第一部分相同。

上载文件后,请重置电话。

有关详细信息,请参阅构建可下载的 BREW 应用程序的方法。

(2)如何编译在手持设备上运行的应用程序?
要编译电话使用的应用程序,需要使用工具的 ARM 开发者套件,这些工具用于编译和链接 已使用基于 PC 的 BREW SDK 及相关工具开发的项目。运行使用 ARM工具编译的应用程序需要一部 启用 BREW 的 电话、一根用于建立至电话的串行连接的电缆,和文件复制软件 (如 QUALCOMM 的 BREW AppLoader 应用程序)。

(3)如何将 Device Configurator 文件 (.qsc) 上载到电话?
Device Configurator 文件 (.qsc) 由 BREW Emulator 应用程序使用, 无需在电话上运行该应用程序。

(4)如何调试模拟器和电话上的输出?
应用程序在 BREW Emulator 上运行时,DBGPRINTF 向 Visual C++ 调试窗口输出消息。目前,电话上运行应用程序时,DBGPRINTF 消息不可用。 正在开发对通过串行连接向主机 PC 输出调试消息的支持。
(5)可以使用哪些编译器编译 BREW 应用程序?
ARM BREW 编译器可以用于编译 BREW 应用程序。
(6)在 Thumb 模式下编译应用程序时应遵守哪些指导原则?

1.AEEMod_Load() 函数必须移至一个不同的源文件中,而且此文件必须在 ARM 模式下编译。AEEMod_Load() 必须始终在 ARM 模式下编译。
2.在 Thumb 模式下编译的所有文件必须启用 INTERWORK 编译器选项。如果此选项在生成文件中未启用,则该应用程序很可能崩溃。

(7)将 ARM BREW 编译器或 ARM 开发套件安装到有空格的路径中时该怎么办?
解决办法是按照以下方式修改您的生成文件:
1.标出 ARMBIN、ARMINC 和 ARMLIB 声明。
2.将完整路径添加到 ARMCC、LD 和 HEXTOOL 变量。确保使用双引号括起路径。

(8)在哪里可以找到安装 ARM BREW 编译器或 ARM 开发套件的提示?
有关详细信息,请参阅 ARM 编译器安装提示和 构建可下载的 BREW 应用程序的方法。
(9)ARM BREW 编译器的最新版本是什么以及 在哪里可以找到维护补丁(如果有)?
最新版本是 ARM BREW 编译器 1.0。ARM BREW 编译器 1.0 是以 ARM 开发套件 (ADS) 1.1 为基础的。发布 ARM BREW 编译器 1.0 后,armlink(725 版)的维护补丁亦也发布。该补丁可以从 http://www.arm.com/support.nsf/html/downloads-ads11 下载。

ARM BREW 编译器版本 1.2 预计在 2002 年 7 月份发布。该版本支持 Windows XP,已购买了 ARM BREW 编译器 1.0 的开发者可以免费升级到该版本。
(10)BREW 有哪些 Java 开发选项?
尽管 QUALCOMM 本身不为 BREW 提供 Java 运行时间,但是我们正在与几个合作伙伴一起为我们的开发者提供选择。目前,我们无法提供对这些 Java 解决方案的访问,但是有望在近期提供。同时,如果您正在开发 J2ME/CLDC/MIDP 应用程序或 midlet,则您可以使用任何标准的 Java 开发环境。同时有望在某些执行环境下直接使用 BREW API。

(12)使用 C++ 时应该注意什么?
肯定应该使用 IHEAP 内存管理例程。最好过载每个类中的新操作符和删除操作符,在这些过载操作符实施中分别使用 AEEStdlib 函数 MALLOC 和 FREE。

下面是一个示例:

void *operator new ( size_t size) {
return MALLOC (size) ;
}
// 重载删除操作符
void operator delete(void * ptr) {
FREE(ptr) ;
}
您无法使用将从现有 BREW 类中派生的 C++ 虚拟函数或继承机制。例如,您无法定义 CApplet 类并让它从 IApplet 接口中派生。我们正在克服这一局限。

在 C++ 中您只能将您的小程序的数据定义为类。例如,您不定义一个包含所有应用程序特定数据的结构 CmyApp,而是可以将其变成类。您可以继续将其大小传递到 AEEApplet_New。在 HandleEvent(及其它)函数中将向您传递回您的 C++ 对象的指针,然后您可以按 C++ 的方式使用它。

(13)使用汇编程序时应该注意什么?
您应该注意分支指令,即从您的代码内到模块外的长分支。您的代码分支外的任何内容都应该使用寄存器。而且,照常您应该没有全局和静态数据。

(14)BREW SDK 的操作系统要求是什么?
由于 Unicode 支持的要求,SDK 仅在 Microsoft Windows NT™ 4.0、Windows 2000™ 和 Windows XP™ 平台上运行。BREW SDK 不支持 Windows 98。

(15)BREW 是否支持多线程?
目前,BREW 不支持多线程。BREW 的确支持合作性的多任务处理。

(16)我是否可以从 SDK 链接到 Windows DLL?
不可以。您应该将 SDK 当作完全集成的独立平台,包括不使用 C 标准库。BREW 提供了最常见函数的端口。
(17)BREW 是否在非 Qualcomm 芯片集上可用?
目前,仅 QUALCOMM MSM 芯片集支持 BREW,但是我们预计将来非 Qualcomm 芯片集也可以支持。目前还没有公布非 QUALCOMM MSM 系列芯片集的芯片集支持BREW 的时限。
(18)哪些设备可以支持 BREW?
目前,仅基于以下 QUALCOMM 芯片集的设备可以支持 BREW。MSM3100、MSM3300、MSM5000、MSM5100 和 MSM5105。另外,要使某电话或其它设备支持 BREW,它必须是“启用 BREW 的”且具有设备生产商提供的 BREW 运行时版本。
(19)小程序必须处理哪些事件?
除明显的 EVT_APP_START 和 EVT_APP_STOP 外,您的小程序必须支持 EVT_APP_SUSPEND 和 EVT_APP_RESUME 才能通过 True BREW 测试。

(20)使用电话的“End(结束)”键关闭小程序和使用“Clear(清除)”键关闭小程序有何区别?
特定设备(电话)的 OEM 为以下两个活动指定按键:
按下将关闭当前应用程序的按键。大多数 OEM 将此键指定为 AVK_CLR 键。
按下将关闭所有应用程序的按键。大多数 OEM 将此键指定为 AVK_END 键。
按下 AVK_END 时,BREW 会立即将 EVT_APP_STOP 发送到激活的小程序,而不先发送 AVK_END 键。另外,将在卸载小程序前调用向 AEEApplet_New() 提供的FreeAppData() 回调例程;将不发生任何其它事件或回调。

按下 AVK_CLR 时,BREW 首先将此事件发送到小程序。如果小程序不处理该事件(即在 HandleEvent 中返回 FALSE),只有在此时 BREW 才会关闭应用程序。在您的 AVK_CLR 处理程序的实施过程中,记住同时要调用 FreeAppData,如下所示:
case AVK_CLR:
if (pMe->OnMainMenu == TRUE) {
// 小程序位于主菜单上, 因此按下 CLR 键将退出小程序
HelloWorld_FreeAppData(pi); //清除
return FALSE; //返回 FALSE 以使 BREW 立即关闭应用程序
}
else { // 不在主菜单上。
// 因此,按下 CLR 键将使小程序取消一级菜单操作
// 嵌套。 显示菜单结构中的前一级菜单
return TRUE;
}

确保您的 FreeAppletData() 会正确清除分配的所有内存和资源。由 CreateInstance、CreateDialog、MALLOC 等创建的所有对象和接口必须对 Release 或FREE 有关联调用。

(22)如何处理电池电量不足警告?
在电池电量不足警告情况下,BREW 会向正在运行的应用程序发送 EVT_APP_SUSPEND 事件。为了处理电池电量不足的情况,必须正确处理 EVT_APP_SUSPEND 和EVT_APP_RESUME 事件。

ISHELL_SendEvent() 和 ISHELL_ PostEvent() 有什么区别?
ISHELL_SendEvent() 和 ISHELL_PostEvent() 函数都用来向指定类发送事件。两者的区别在于发送事件的方式。

对于 ISHELL_SendEvent(),事件会立即发送到指定 Class ID 的应用程序。如果当前没有该类的实例,AEE Shell 将创建一个实例,然后使用指定事件代码和数据参数调用 IAPPLET_HandleEvent() 函数。除非应用程序愿意自动启动,否则事件处理完后它即会终止。

除目标类的 IAPPLET_HandleEvent() 函数不立即调用外,ISHELL_PostEvent() 类似。事件进入队列,稍后发送。这样,调用应用程序可以不中断地继续进行处理。

ISHELL_SendEvent() 函数允许控制目的小程序,并直接向目的小程序发送事件。对使用 ISHELL_PostEvent() 传递的事件的处理会延迟到下一个事件循环。在处理其它事件的同时允许程序不间断执行方面,此函数非常有用。

(23)我的应用程序可以注册哪些通知事件?
应用程序可以注册以下系统通知:

TAPI (Class ID: 0x01001007)
NMASK_TAPI_STATUS 0x0001 TAPI 状态改变事件
NMASK_TAPI_SMS_TEXT 0x0002 进入的 SMS
NMASK_TAPI_SMS_TS 0x0004 特定电信业务 ID 上的 SMS 消息

INETMGR
NMASK_OPENED 0x0001 网络层可用
NMASK_CLOSED 0x0002 网络层已关闭
NMASK_UDP_LISTEN 0x8000 UDP 监听
NMASK_IDLE 0x0004 网络层可用且空闲
(包含在 BREW SDK 1.1 及更高版本)

应用程序也可以注册从其它动态应用程序和模块接收通知。有关详细信息,请参阅 SDK 随附的 INotifier 用法示例。
如何从“Undef Inst 例外”恢复电话?
“Undef Inst 例外”即“未定义指令例外”,意指程序指针跳转到包含未定义指令的代码段。这可能是由于内存错误、堆栈超限或电话上小程序代码和 BREW 图像间与版本相关的不兼容引起的。

内存在电话上比在模拟器上运行时更紧张。因此,内存和堆栈超限问题更可能在电话上出现。应该进一步检查您的代码与内存相关的部分,特别是自动变量数组和已分配内存的最大大小总量。

要清除电话,请将电池取出几秒钟。

(24)什么是“可重入数据中止”?
“可重入数据中止”例外通常是由堆栈超限引起的。小程序在电话上运行时,堆栈较小,因此在模拟器上运行时更可能出现堆栈超限问题。此问题的解决办法是减小堆栈上对象的大小或减少这些对象的数量并使用在堆上分配的对象,而不是自动变量。

据报道,电话上的小程序代码和 BREW 图像之间与版本相关的不兼容也可能导致此类例外。
(25)什么是“Pref 中止例外”?
“Pref 中止例外”通常表示对电话操作系统重要的内存被破坏。此例外的两个最常见原因是数据破坏(即从数组末尾逃逸)和堆栈超限。

(26)什么是“SWI 例外”?
“SWI 例外”通常与堆内存管理不善有关。堆内存错误的最常见原因如下:覆盖所分配数组的界限、多次释放对象以及写入难以操纵的指针或 NULL 指针。

除了更常见的原因外,堆栈超限也可能导致 SWI 例外。建议将堆上而非堆栈上的大缓冲区作为自动变量分配。

(27)为什么模拟器在我的应用程序退出时会显示有我的应用程序名的空白屏幕?
这种情况是由于退出应用程序前未释放分配的全部内存所引起的。必须使用 FREE 或 IHEAP_Free() 释放您用 MALLOC 或 IHEAP_Malloc() 分配的任何缓冲区。

对于您创建的 BREW 类的任何实例,必须调用相应的释放函数来释放该实例。

(28)BREW 中的内存结构如何工作?
BREW 设备拥有闪存 RAM 和堆 RAM。您可以将闪存 RAM 当作硬盘驱动器。程序在这里存储,但不从此处运行。您可以将堆 RAM 当作内存堆。假定您有一个应用程序,大小为 35k。这样就需要 35k 闪存 RAM 用于在设备上存储。运行应用程序时,这 35k 将被全部加载到堆 RAM,而且还需要分配更多的堆 RAM。释放小程序时,会释放此堆 RAM。它将仍然占用闪存 RAM 上的空间,直到从设备上删除。
(29)小程序的大小限制是什么?
BREW 小程序的大小受可用空闲文件系统空间量和可用 RAM 量的限制。

BREW 小程序在执行时会加载到 RAM 中;任何剩余的 RAM 可用于内存分配、加载资源、创建控件等。可用 RAM 的多少取决于电话的类型及其配置。例如,在QCP-3035 上,可用 RAM 是 90K。30K 属于 BREW 和其它电话相关的任务,60K 可由小程序使用。运行 BREW 的每个电话上的可用内存可以从此处获得。

小程序大小的另一个限制因素是堆存储碎片。如果最大可用内存块小于小程序的大小,则不会加载小程序。使用 IHEAP_CheckAvail() 确定是否可以分配足够大的内存块。IHEAP_GetMemStats() 可用来确定已使用的 RAM 量。如果您的一个小程序对于某设备而言太大,解决办法是将该应用程序分割成多个小程序。有关如何能够避免产生堆存储碎片的详细信息,请参阅内存分配。

注意:
为了在 BREW Emulator 上测试内存不足的情况,请将设备配置文件中的堆大小减小相应的量。
BREW System Info(系统信息)屏幕报告的是可用闪存量,而不是可用 RAM 量。
为什么小程序无法直接从闪存 RAM 运行?
BREW 将应用程序加载到堆 RAM 中,因为 EFS 上的文件是作为非连续块存储的。
BREW-SDK 中 MALLOC() 和 IHEAP_Malloc() 函数的区别是什么?
MALLOC 和 IHEAP_Malloc() 完全一样,如同 FREE 和 IHEAP_Free() 也是完全一样的。在 BREW SDK 的早期版本中,malloc 是 IHEAP 接口的一部分,后来为便

于使用而合并到助手函数中。两者仍可以向后兼容,但建议使用 MALLOC 和 FREE,而不是 IHEAP_Malloc() 和 IHEAP_Free()。

小程序若希望获得当前内存使用统计数字 (IHEAP_GetMemStats()) 或检查是否可以分配一定大小的内存块 (IHEAP_CheckAvail()),只需要创建 IHeap 接口。

(30)如何在模拟器上测试应用程序以确定它在内存不足情况下是否正确运行?
这可以通过将设备配置文件(.qsc 文件)中的堆大小减小到与 .mod 文件的大小差不多来实现。如果应用程序的任何运行时分配失败,您可以测试您的应用程序是否可以正确处理这些故障。

由于 mod 文件的大小大大小于在模拟器中运行的 dll,模拟器估计 mod 文件的大小是 dll 的 10%。

要正确运行此测试,请单独创建一个仅包含测试中应用程序的 MIF 的目录,并将模拟器指向这个新目录(File(文件)->Change MIF Dir(更改 MIF 目录))


(31)如何从 BREW 应用程序发送 SMS 消息?
目前,BREW 无法从 BREW 小程序内发送 SMS 消息。 BREW 应用程序只能接收 SMS 消息。

(32)SMS 消息是否可以发送给不活动的小程序?
是,可以将 SMS 通知事件发送到一个应用程序,即使它目前不活动。 为此,BREW 首先加载小程序,然后再向它发送 EVT_APP_MESSAGE 事件。 应用程序可以通过调用 ISHELL_StartApplet() 自动启动,也可以不调用 ISHELL_StartApplet() 而“无声地”处理该事件。

(33)何在 BREW 应用程序中处理进入的 SMS 消息?
有关 BREW 中 SMS 的详细信息,请参阅在 BREW 中处理 SMS。

(34)进入的 SMS 消息是否可以用 SDK 模拟?
SMS 模拟将在 BREW SDK 版本 1.1 中实现。

(35)在 Sharp Z-800 上收到非 BREW SMS 消息时让正在运行的 BREW 应用程序中止需要进行哪些设置?
在 Sharp Z-800 手持设备上,您必须进行以下设置才能接收非 BREW SMS:

Main Menu(主菜单)-> Setup/Tool(设置/工具)-> BREW Setting(BREW 设置)-> OFF(关闭)
使用 ITAPI_MakeVoiceCall 进行语音呼叫时,对 Privacy Alert(隐私警告)响应 No(否)会使应用程序挂起。有什么解决办法?
这是 BREW SDK 版本 1.0.1 中的缺陷,将在以后版本中修复。

对于 BREW SDK 版本 1.0.1,建议解决办法是用户按两次 No(否)(即按 Select(选择)键两次)。 显示 Privacy Alert Yes/No(隐私警告是/否)时,所有的按键事件直到 第一次按下 Select(选择)键后才会转至该对话框。在第一次按下 Select(选择)键(对话框)后,后续按键事件将转至应用程序。

步骤概述如下:

1. 在小程序结构中添加一个布尔型 "madeVoiceCall"
2. 如果 ITAPI_MakeVoiceCall() 返回 Success,则将 madeVoiceCall 设置为 TRUE
retValue = ITAPI_MakeVoiceCall(pMe->p_tapi, PHONE_NUM,
AEECLSID_SAMPLEAPP);
ITAPI_Release(pMe->p_tapi);
if(retValue == SUCCESS) {
pMe->madeTapiCall = TRUE;
}

3. 处理应用程序处理程序函数中的 EVT_KEY。如果 Select(选择)键已按下且 madeVoiceCall 为 TRUE,则用户已选择 No(否)作为对 Privacy Alert(隐私警告)的响应。设置 madeVoiceCall = FALSE 并 刷新屏幕。
case EVT_KEY:
if (wParam == AVK_SELECT && pMe->madeTapiCall ==
TRUE) {
// 刷新屏幕
pMe->madeTapiCall = FALSE;
}
return TRUE;

4. 如果用户对 Privacy Alert(隐私警告)选择“Yes(是)”,则应该已中止了该应用程序。 恢复时,必须清除 madeVoiceCall 标记。
case EVT_APP_RESUME:
if(pMe->madeTapiCall == TRUE) {
pMe->madeTapiCall = FALSE;
}
... ... ...
... ... ...
return TRUE;

原创粉丝点击