分享
 
 
 

BREW & J2ME:在差别中联合

王朝java/jsp·作者佚名  2006-03-22
窄屏简体版  字體: |||超大  

[出自: http://expert.imobile.com.cn]

摘要

本系列面向那些习惯使用J2ME的手机开发者,或者那些对更轻便和更有效的代码生成感兴趣的BREW开发者。主要是受Java GUI模型的启发,当前的BREW_J2ME 框架可以处理J2ME中当作“高级别接口”的东西。关于如何提供确切的J2ME匹配-推理不在本文讨论范围之内,本文只是提供这两个领域的概述。

首先我将快速讨论BREW和J2ME之间的差别以及我们如何缩小这个差距,为此我将深入分析设计过程。然后我会给出一个完全的框架。

概述

从一开始,Qualcomm试图将BREW定位为中立语言,将C/C++定位为最好的语言选择——其它语言总能为应用开发所用就行。从技术的观点来看,这个理论看似相当合理——新的语言总是能够作为静态扩展来实现,还包括了原来的BREW功能。作为一个附带的优点,成为扩展可以立即得到BREW分布式系统(BDS)的所有优点。这是好的方面。但是,他有什么负面影响呢?

这种实现原本就比直接在OS上实现更慢,更笨重(因为所有OS调用都经BREW中转)。现在,J2ME:BREW比标准的MIDP(甚至是2.0版本)提供的功能要多得多,也就是说可能会出现一个非标准的API来填补它们之间差距。 [www.cnjm.net]

当然,编程语言的选择主要是一个商业决定,与比较他们的优点无关。J2ME:BREW最吸引人的地方就是为Java开发者使用C++语言编写BREW应用提供一个更熟悉的方式。从开发者的观点来看,这明显意味着要熟悉J2ME和BREW之间的界限和差别。

他们之间的差别有的源于Java vs C++的争论——例如,存储处理、多重继承、类型安全、泛型等等。有的源于BREW的局限性——典型的如缺乏静态变量的支持、缺乏C++的支持级别、缺乏多任务合作、开发者兼管监察活动等等。当然,Java在BREW之上就意味着Java得接受所有这些差别。还有的源于基础设计决定,如时间模型、组件等等。当然,如前所述,J2ME是一组平台独立的规范,他没有为某些BREW功能提供相应的配对物。

设计

我们的目的就是简化“高级别接口”的代码以及相关的逻辑,使Java开发者的工作更轻松。这就意味着,至少从理论上说,我们能够编写以下代码:

CODE:List* l = new List("Title");

l->setCommandListener(myListUsage);[www.cnjm.net]

String a[] = {"1","2","3","4"};[www.cnjm.net]

l->append(a);

Display.getDisplayable()->setCurrent(l);: [www.cnjm.net]

正如概述中看到的一样,有不同的因素影响着设计,如(不分顺序): 没有内建的垃圾收集器;就某种意义上来说没有静态变量=没有Singleton;没有根对象但有安全类型泛型,等等。考虑到所有这些因素,我们就会了解为什么上述代码不能够在BREW中自由编写。其可能原因有:

1.没有List。

2.'new' 必须与'delete'配对。

3.没有可用的字符串或者广义的字符串。

4.将AECHARs 直接置于堆栈是危险的。

[www.cnjm.net]

5.没有听取者。

6.Singleton难于实现。

BREW_J2ME框架的任务就是为解决这种问题提供最好的可能方案。

BREW_J2ME框架最重要的决定之一是关于存储管理和对象周期的。如果没有删除,谁负责销毁我们的小器件呢?明显的答案如基于堆栈的对象和职能指针,职能指针可用于限制范围的生命周期或者引用计算(这与BREW方案保持一致)。以前文章中用过的一个方案就是:登记对象并将对象周期与登记处周期捆绑在一起。这就意味着要添加一个层(登记处)并且能够追踪某个地方所有资源。直接在BREW上创建的C++应用不是第一级别的C++对象,而只是一个POD结构。那就是为什么真正的C++操作明确需要这样一个绝缘层的原因。我们接下来将调用我们的登记处DisplayableRegistry。 [www.cnjm.net]

我们的登记处主要追踪可显示的资源,实现IDisplayable 接口:[www.cnjm.net]

CODE:struct IDisplayable

{

virtual bool onCmd() = 0;

virtual bool containsItem(int idx) = 0;

virtual int getID() const = 0;

virtual IControl* getControl() const = 0;

virtual ~IDisplayable()

{}[www.cnjm.net]

};

在BREW中, IDisplayable等于IControl ,即使它展示附助功能。

为了方便,每个应用都从IMidlet抽象类继承而来,这个类负责声明和实现哑元应用级的事件回调(这个稍候再讨论),以及提供对DisplayableRegistry唯一范例的访问。这就解决了另外一个问题——Singleton的实现。请注意:IMidlet提供的机制和动态多形性并不是必要的,从本质上来说——静态多形性也可以做同样的事。让每个组件都理解应用,相当于为他们提供了上下文。

CODE:class IMidlet

{

public:[www.cnjm.net]

DisplayableRegistry* getDisplayable() const

{

return rr_;

}

void setRegistry(DisplayableRegistry* rr)

{

rr_ = rr;

}

virtual bool onStart()

{

return true;

}

virtual bool onStop()

{

return true;

}

virtual bool onSuspend()

{[www.cnjm.net]

return false;

}

virtual bool onResume()

{

return false;

}

virtual ~IMidlet()

{}

private:

DisplayableRegistry* rr_;

};

这里是DisplayableRegistry的一个可能实现:

CODE:class DisplayableRegistry

{

public:

int registerResource(IDisplayable* resource)

{

for(int i = resources_.size() - 1; i >= 0; --i)

{

if (resources_[i] && resources_[i] == resource)

{

return i;

}

}

resources_.append(resource);

return resources_.size() - 1;[www.cnjm.net]

}

bool unregisterResource(int uid)

{

if (resources_[uid] )

{[www.cnjm.net]

delete resources_[uid];

resources_[uid] = 0;

return true;

}

return false;

}

IDisplayable* getRegistered(int uid) const

{

return resources_.isEmpty() || ((resources_.size()-1) < uid)[www.cnjm.net]

? 0 : resources_[uid] ;[www.cnjm.net]

}

void setCurrent(IDisplayable* resource )

{

setCurrentImpl(resource);

}

int getNextAvailableID()

{

++itemID_;

return itemID_;

}

bool onCmd(int itemID, long data) const

{

int id = INDEX_OUT_OF_BOUNDS;

for(int i = 0, sz = resources_.size(); i< sz; ++i)

{[www.cnjm.net]

if (resources_[i]->containsItem(itemID))[www.cnjm.net]

{

IDisplayable* d = resources_[i];

return resources_[i]->onCmd();[www.cnjm.net]

}

}

return false;

Midlet* getApp() const

{

return m_;

}

bool isHandled(AEEEvent eCode, uint16 wParam,

uint32 dwParam) const

{

for(int i = 0, sz = resources_.size(); i< sz; ++i)[www.cnjm.net]

{

IControl* c = resources_[i]->getControl();

if (c && ICONTROL_HandleEvent(c,eCode, wParam, dwParam))

return true;[www.cnjm.net]

}

return(false);

}[www.cnjm.net]

~DisplayableRegistry()

{

delete m_;

unregisterResources();

}

DisplayableRegistry(IMidlet* m):itemID_(100), m_(m)

{

m_->setRegistry(this);

}

private:

void unregisterResources()

{

for(int i=0, sz = resources_.size(); i < sz; ++i)

{[www.cnjm.net]

delete resources_[i];

resources_[i] = 0;

}

}

void eraseAll() const

{

for(int i=0, sz = resources_.size(); i < sz; ++i)

{

IControl* c = resources_[i]->getControl();[www.cnjm.net]

ICONTROL_SetActive(c,false);

}

IDISPLAY_ClearScreen(getDisplay());[www.cnjm.net]

}

void setCurrentImpl(IDisplayable* resource)

{

eraseAll();

ICONTROL_SetActive(resource->getControl(),true);

IDISPLAY_UpdateEx(getDisplay(), false);

}

private:[www.cnjm.net]

int itemID_;

IMidlet* m_;

private:

DisplayableRegistry( const DisplayableRegistry &value );

const DisplayableRegistry &operator =

( const DisplayableRegistry &rhs );

};[www.cnjm.net]

最后,使登记过程和基于GUID的BREW初始化过程透明化需要一个附助构造——一个工厂。代码的第一行可以这样写:

CODE:List* l = List::getList("Title", this); [www.cnjm.net]

【未完待续】

源代码下载: cppapp.zip

原文地址:http://www.developer.com/ws/j2me/article.php/3116331

参考文献

1.BREW and J2METM—A Complete Wireless Solution for Operators Committed to Java—Qualcomm http://www.qualcomm.com/brew/images/about/pdf/brew_j2me.pdf [www.cnjm.net]

2.Design Patterns: Elements of Reusable Object-Oriented Software—ErichGamma, RichardHelm, RalphJohnson, and John Vlissides, Addison-Wesley, 1994

3.String in BREW Revisited—a BrewString Generalization—http://www.developer.com/ws/brew/article.php/2229051

4.Emulating C++ Exception Handling—Gregory Colvin, C/C++ Users Journal, December 1994

5.For Brew Developers, There Are New Kids in Town: IThread & IRscPool, Part 2—http://www.developer.com/ws/brew/article.php/3105131

关于作者

Radu Braniste 是Epicad的技术主任。联系他请发邮件到: rbraniste@epicad.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有