作者:mingjava 文章来源:http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=859
6.3 移植问题
这一节讨论一系列特定的移植问题,涉及UI(包括低级图像和高级UI组件)、可选的和第三方API以及下载大小限制。
为了创建能在一系列不同类型和功能的设备上运行的MIDlet,在MIDlet运行期间,识别设备的性能是非常有用的,这样它就能动态改变其行为,或者在提供MIDlet时,服务器能发送一个恰当的经过裁剪的JAR文件。
支持设备的运行期识别也是相当有限的:我们能使用System.getProperty()来识别JTWI或MIDP版本,并且我们可以使用Canvas.getHeight()、Canvas.getWidth()、Canvas.isDoubleBuffered,Display.isColor()和Display.numColors()来识别显示能力。
当前,当下载一个应用程序时,通常让用户点击手机上的链接来(例如,“BoyRacer for Sony Ericsson P800/P900”或“BoyRacer for Nokia 6600 or Series 60”)下载。然而,在每个HTTP处理期间,设备将自己的识别码加入用户代理字段(例如,“Sony Ericsson P900”或“Nokia 6600”),这能够被提供下载的服务器识别来发送恰当的JAR应用程序。针对设备识别的Composite Capability/Preference Profiles(CC/PP,参见www.w3.org/Mobile/CCPP)UAProf标准正在慢慢地形成,它将使提供下载的服务器能够获得一个手机的更详细的特性。
HTTP处理一个URI,它指向手机的详细信息,但是也能包含一些其他信息,这些信息能够标识出单个手机相对厂家标准可能进行了哪些修改。这就能使下载服务器为一个指定的手机动态创建一个量身定制的JAR文件。
通常,需要检查目标设备的设计标准并尽量服从这些标准。甚至开发者可能实现任何他们希望使用的低层GUI API,对用户而言,使用他们熟悉的界面会更容易。因此,对于不同的主机设备,尽可能地模拟菜单和命令的标准命名法。一些设备为用户提供一个一致的界面。例如,在Nokia手机上,右边的软键通常总是“导航”命令,如退出、后退和取消等,左边的软键用于“主动的”命令,如确定、选择和连接等。
6.3.1 低级图形内容
在游戏应用程序中,构成基本用户界面的便是图形内容。
尽管在一个游戏环境中,主要的Sprite一般都保持大小不变,但对于背景图像就不一定。背景构成了游戏的“世界”,并且随着屏幕尺寸不同而变化。例如,Nokia 6600显示像素为176×208,而Sony Ericsson P900显示像素为208×253,当显示软键盘时,尺寸变为208×173。
当UI被初始化后,需要使用Canvas.getHeight()和Canvas.getWidth()方法来查询设备屏幕的宽度和高度。这就为创建背景图像提供了足够的信息。使用TiledLayer时,我们能做以下两件事情:
· 我们能改变贴砖的大小来反映屏幕的尺寸。这最大限度地减少了对MIDlet的影响,虽然这对图形设计者增加了负担。更重要的是,游戏背景的贴砖可能变形。
· 我们能使TiledLayer更智能,在初始化时,通过查询设备屏幕尺寸,对背景作出合适的更改。新的贴砖背景的尺寸取决于单个的贴砖和屏幕尺寸。这种更好的方式允许我们调整视角来反映不同的屏幕尺寸,使MIDlet允许用户在一个较大的设备上有一个较大的游戏世界的视图。例如,一个迷宫游戏应当显示更多的迷宫。7.14节的LifeTime MIDlet就使用了这种方式,以在大屏幕设备上显示更多的游戏空间。
用于创建游戏的图像通常要根据目标手机的屏幕特性来裁剪,可能还要根据手机的内存和性能特性来裁剪。它们甚至要根据下载的JAR文件大小的限制来进行更改。因此我们需要针对一些手机采用小的黑白图像,但是对有更大处理能力的彩屏手机,(应当)采用更大的彩色图像。这需要针对每一个或者一组目标设备创建各自的JAR包。
MIDP 2.0的更有用的新特性就是游戏API。它允许通过一个包含所有帧的图像文件为一个角色或屏幕对象创建一个Sprite。在第5章的Racer MIDlet示例中,我们提供了一个4帧的序列,其中封装了动画所必需的所有帧。
Sprite的子类使用一个PNG文件初始化,并且根据自身已知的尺寸创建帧。这意味着如果屏幕尺寸改变而帧的数量不变,我们可以改变帧序列而不是改动代码,使得Sprite仍然保持比例。
我们已经讨论了改变图像以适应设备的必要性,但是Sprite可能也需要改变。如果Sprite类足够智能,能检测到它们自身的尺寸改变,那么一切将工作得很好。然而,它们可能会以不同的方式移动,这就需要改变移动的方法。Sprite间的碰撞检测也可能改变。例如,一个更小的图像可能需要一个更小的碰撞检测区。在一些情况下,使用整个图像来进行碰撞检测的处理太耗费时间,因此我们要使用defineCollisionRectangle()方法来定义一个更小的区域。Sprite大小的改变可能意味着其碰撞检测区也要随之改变。
屏幕尺寸的改变可能需要更少的Sprite的副本。可能会有更小的空间来显示敌方角色,或者那些应该出现在屏幕上的Sprite落在了屏幕外。例如,在一个典型的Space Invaders游戏中,较小的屏幕尺寸可能意味着较少的攻击玩家角色的敌人。你希望在更大的屏幕上得到更多的攻击和子弹吗?你认为在不增加游戏难度的情况下,MIDlet应该在初始化时计算出多少次攻击是合适的吗?应该隐藏更少的或更小的障碍吗?这些值可能被硬编码在Sprite类的成员变量中。考虑创建一个资源包来提供这些值,或者将它们添加到JAD文件,使MIDlet能够在启动时查询到它们,这是不是更明智?
尽可能地使用游戏动作。它提供了一个通用的游戏动作的映射,比如开火、上、下、左、右等,可以很容易地在键盘上实现,如对应2、8、4和6。一些键盘有不同的布局,比如MIDP 1.0手机Siemens SX-1,可能以不同的方式映射这些动作。甚至像Sony Ericsson P900这样主要使用基于操纵杆的设备,其操纵杆也能被用于游戏动作的向上和向下。游戏设计可能需要简化,或者可以使用可卷动的Choice列表作为游戏菜单让用户选择。
一些设备提供了持续检测一个键的状态是否为“按下”或“释放”的能力。持续检测一个键当前是否被按下使我们能给予用户“快速开火”的能力。不是所有的设备都有这个功能,因此需要注意。
6.3.2 输入方式的不同
开发者需要意识到,不同的设备有不同的输入方式。至少,他们需要编写保护式的代码以允许不同的输入方式。为一个指针设备或一个键盘设备进行测试是明智的。例如,如果一个MIDlet是针对Sony Ericsson P900的,那么需要将按钮置于屏幕上,并需要更大的图像使得用户选择时更加方便。在一个键盘设备上,例如Nokia 6600等,用户就要依赖操纵杆来导航,并且需要自动选中项目。
Sony Ericsson P900提供了一个软键盘来弥补没有键盘的问题。这对于用户的游戏会有什么影响呢?他们会仍然喜欢类似一个键盘手机上的体验吗?除了这两种输入方式外,是否应该开发一种不同的用户界面?例如,不监听左右键,MIDlet可以检测屏幕上哪一部分被手写笔按下;如果按在角色的左边或右边,角色就应该向此方向移动。在角色身上按下手写笔将引发开火。操纵杆可以配合手写笔使用。换句话说,应该试图尝试其他捕获用户输入的方式,而不是模拟键盘。
也许开发者需要问他们自己,基于指针的设备是否对另一种用户仍旧有吸引力。游戏设计者是否应该考虑充分使用设备的特性,而不是试图移植一个不适合的游戏?最好的商业决定也许不是移植所有的应用,而是为设备创建其特有的感官。
6.3.3 高级用户界面组件
使用高级UI组件(如TextField、List和Form)而不是直接绘制到一个Canvas上,这通常能提供一个可移植的UI。这些组件及其布局都是抽象的,底层设备实现处理组件在屏幕上的显示。应用程序不关心如何捕获用户输入或单个的键,也不负责定义可视外观以及导航和卷动等动作。
这对于基于信息显示的应用程序来说效果很好,因为开发者可以更关注如何在屏幕上以一致的方式组织信息。开发者基本上没有控制外观的能力,因此,UI界面保持和本地应用程序的外观一致。
高级API中的一个例外是CustomItem,它允许开发者自定义他们自己的Form对象。尽管这是一个从Item派生的高级组件,但它的表现更像一个Canvas。尽管其他高级Form对象已经实现了用户交互管理和对象间切换,但是扩展了抽象类CustomItem的类将负责实现其行为。
Sony Ericsson P900和Nokia 6600对CustomItem的实现是不同的,反映在两种手机对用户交互的不同。在Nokia 6600上扩展CustomItem并重新定义keyPressed()、keyReleased()和keyRepeated()方法,而在Sony Ericsson P900上重定义pointerPressed()、pointerDragged()和pointerReleased()方法。这样,扩展的CustomItem能在两种平台上正确表现其行为。
6.3.4 适应私有API和可选API
当前参与MIDP 2.0标准的有许多对其感兴趣的合作伙伴,像设备制造商、网络运营商和包括Symbian在内的操作系统开发商。在某些情况下,为了促进使用下一代技术和一些可预见的技术,会随设备发布其私有的API,以允许开发者能够使用这些尚未成为(或许永远不会成为)标准的API来创建更为复杂的应用程序。 例如, Nokia为广播SMS消息创建了其私有API, 且Nokia MIDP 1.0设备的另一个私有的UI API使游戏开发者能控制Canvas是否充满整个屏幕。 这些功能后来加入到了标准中。JSR 120支持SMS,并且MIDP 2.0提供了Canvas.setFullScreenMode()的方法。在这种情况下,Nokia的UI API就申明为过时的(deprecated),尽管其实现仍将确保向后兼容。
开发者应该在假定他们使用的所有类都是标准的之前,认识到目标设备的能力。应该保守地编写代码,来确保当一个API不可用时MIDlet仍然可以运行,且Mzblet可以采取合适的动作而不是异常地关闭应用程序。对开发者而言,更好的做法是,认识到设备上的库并在此新设备上发布应用程序前对应用程序的功能做出主动的决定。
然而,这使得开发者进退两难。他们仅仅使用目标设备以及适合其需求的操作吗?还是试图编写突破限制的代码来达到相同的结果?例如,是否可以改变屏幕的布局或菜单次序来适应一个较小的屏幕尺寸?
设备之间的不同之处的另一个方面是它们对多媒体的支持能力。例如,MIDP 2.0中的Media API(在第3章中讨论过)以最小的子集为多媒体提供了有限的能力。如果设备有很好的本地多媒体功能,例如,内置的摄像头和麦克风,那么,开发者应该适当地使用它们来操作多媒体数据。然而,目前,仅有一部分功能更强的手机(如Nokia 3650和Nokia 6600)完整地实现了Mobile Media API(JSR 135),它能绘画和记录媒体数据(如音频和视频重放)以及捕获照片。这个API使第5章讨论的Picture Puzzle MIDlet之类的应用程序能从内置的摄像头捕获一个图像,然后操作并存储以便将来使用。然而,这样的应用程序的实现显然被限制在这些支持MMAPI和拥有图像捕获功能(JSR 135的可选功能)的设备上。
CLDC/MIDP API的分割被普遍认为是一个严重的问题。因此,人们成立了Java无线行业技术(Java Technology for the Wireless Industry,JTWI)专家组来处理这个问题(http://jcp.org)。第3章介绍了JTWI并关注构成JTWI蓝图第一版的组成JSR。JTWI的一个目标是提供一个最小的、强迫设备必须实现的API和功能。针对JTWI平台的应用程序,开发者能确保这些应用程序可以运行在尽可能多的设备上。JTWI针对特定的组成JSR还定义了在性能和可选功能方面的最小需求。这些已在第3章详细讨论,但是这里可以列出一部分相关的示例:
· 设备应当允许最大64KB的JAR文件、最大5KB的JAD文件和30KB的持久存储空间。
· 对于图像,除支持PNG外,还添加了对JPEG文件格式的支持,以提供更大的灵活性。
· 应当采用至少125×125像素大小的屏幕,并且颜色深度达到12位。
· 运行在GSM/UMTS网络上的设备必须支持SMS Push,它与Push Registry一同工作,一旦接收到一条SMS短消息,能唤醒MIDlet。
Symbian是JSR 185专家组成员,并且从Symbian OS 8.0版开始,Symbian的Java实现是JTWI兼容的。JTWI的第一个发布版的批准在MIDP 2.0标准之后,但是许多主要的MIDP 2.0设备可以在不久的将来符合JTWI标准。
6.3.5 下载限制
Symbian系统设备如Nokia 6600和Sony Ericsson P900并不指定MIDlet的JAR文件的最大尺寸限制;相反的,JAR文件的大小受到设备上可用的持久化存储空间的大小的限制。一般的,Symbian系统设备有16MB空间,但是随着操作系统和应用程序的不断添加,大约只剩下8MB。一些设备有记忆棒和MMC卡,这样的话,当然就有非常大的存储空间。其他的考虑还包括运营商在WAP网关设置的下载限制。一个太大的应用程序不会好卖,因为没有人能够下载它!混淆(在第7章讨论)提供了一种减少JAR文件大小的方法。
进一步地分析市场,开发者应该意识到:一些设备有一个最大下载限制。Nokia Serise 40设备有最大64KB的限制,而Sony Ericsson T610允许最大60KB的JAR文件。这些能给出一些建议:最终的JAR文件应该多大尺寸才最适合移植。
当然,大小是由文件的内部内容决定的,因此,仔细考虑我们应当包含进去的内容是值得的。确实需要添加声音文件吗?例如,目标设备可能没有播放某种格式的声音的能力,或者没有绘画某种格式的图像的能力。为了移植到一个不同的设备,我们可能要扔掉这些额外的内容。在一个比较低级的设备上,播放一个声音可能对MIDlet的速度和设备内存会有意想不到的负面效果。
也许一个较小的JAR文件意味着一个较小的游戏世界。可能我们应该考虑减少供用户游戏的通关数量?
混淆可以打乱代码来防止那些喜欢偷窥的人,它还有减小最终JAR文件大小的功能,并能改善性能,尤其是对于早期的VM。一些混淆器有更高的效率并能减小更多的JAR文件大小,因此可以尝试不同的混淆器(第7章还将简洁地讨论两种可用于Sun ONE Studio Mobile Edition的混淆器)。
6.3.6 堆内存
开发者需要意识到堆内存,尤其是把应用程序移植到另一个设备上时。堆内存保存所有的运行期代码、图像和其他与MIDlet相关的对象。如果没有将其大小保持在一个限度内的话,将导致一个OutOfMemory错误,并且MIDlet将终止运行。例如,一个用贴砖填充的背景可能需要使用屏幕外缓冲来优化设备性能,此时就可能导致此类问题。
通常,Symbian系统设备并不指定堆内存的限制,以便让开发者有足够的空间使用。Nokia 6600和Sony Ericsson P900/P908都允许最大达8MB的堆内存。当然,手机的其他应用程序也共享此内存空间,并且,在任一时间,应用程序管理软件可能决定哪些能运行、哪些不能运行。开发者可以采用一些策略来最小化内存使用。Flyweight设计模式、对象工厂和对象再生都能最小化内存中对象的数量,当对象不再使用时将其释放,确保应用程序有足够的内存使用,而不是仅仅依赖垃圾收集器来管理内存。
把MIDlet移植到更小的或不同的设备可能会有一系列挑战。这些设备可能只有少得多的堆内存,开发者应该意识到这一点。重要的一点是,记住,用于创建应用程序图像的图像文件的大小在运行期间对堆内存的使用有直接的影响。一个折衷的方案可能是减少图像内容来减少整个内存的消耗,例如,通过减小Sprite中的图像质量和图像细节。
此外,较少的堆内存可能引起垃圾收集器更加频繁地运行,从而影响整个MIDlet的性能。
6.4 小结
在这一章中,我们研究了为移动设备创建灵活的和可移植的应用程序所应当运用的技术和模式,以便最大限度地提高收入。我们还研究了一些设计模式,在编写MIDP 2.0代码时,你可以使用它们来解决面临的移植问题。你需要仔细考虑用户界面,尤其是图形内容。我们还讨论了在游戏开发中使用低级API带来的一些问题。
在第7章中,我们将讨论为受限设备开发应用程序的另一个重要问题:为J2ME平台优化代码。
分享到:
相关推荐
Java输出菱形代码可调节可移植
本文介绍了Java的可移植性特点,包括字节码、Java虚拟机(JVM)和跨平台开发。同时,提供了相应的Java示例代码。...建议您在阅读过程中结合实践,尝试运行示例代码,加深对Java可移植性特点的理解,并提升编程能力。
纯 Java 中的压缩 该库包含 用纯 Java 编写的LZ4、 Zstandard (Zstd)、 Snappy和 LZO的实现。它们通常比本地库的 JNI 包装器快 10-40%。 Hadoop 压缩编解码器 除了原始块编码器之外,每个算法都有 Hadoop ...
java + XML = 可移植性代码 + 可移植性数据
一个java图像处理功能源代码,功能完整,提倡使用此代码复用移植
javaSE源代码,学习笔记,查漏补缺。...Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等.
给出Cobol移植至Java的完整解决方案
NULL 博文链接:https://zwhc.iteye.com/blog/710107
该项目从原始 grbl 移植到 STM32 或其他 MCU。目前,它在stm32g0上运行良好;FreeRTOS是在原有的基础上添加的,可以扩展更多功能,使实际的雕刻机/...基于GRBL移植的项目,在GRBL的基础上将代码移植到STM32的MCU上执行。
1.2.7可移植性 1.2.8 解释型 1.2.9 高性能 1.2.10 多线程 1.2.11 多态性 1.3 Java Applet与Internet 1.4 Java发展简史 1.5 关于Java的常见误解 第2章 Java 程序设计环境 第3章 Java基本的程序设计程序 第4章 对象与...
很好的手机游戏.3
1.2.7可移植性 1.2.8 解释型 1.2.9 高性能 1.2.10 多线程 1.2.11 多态性 1.3 Java Applet与Internet 1.4 Java发展简史 1.5 关于Java的常见误解 第2章 Java程序设计环境 第3章 Java基本的程序设计程序 第4章 对象与类...
本物业管理系统是在服务器上先安装Windows NT操作系统,并在NT系统下安装数据库系统SQL Server 7.0和建立人员、住房、房产、收费四个...以达到在不同的操作系统下可以互相调用的目的,实现Java的重要特性:可移植性。
java开发的移植游戏“紫禁城”源代码,使用MyEclipse 10导入 方向键移动,空格键回退 ESC弹出配置菜单,左右键选关,上下键打开和关闭背景音乐 音量的调节搞不定,希望有大拿指点
java通用分页代码实例,适用于任何一种数据库,方便,快捷,可移植性高,简单易懂。
lwip移植代码,内含有lwip英文文档。接口部分代码不错,可以参考
JAVA的学生管理系统源代码,有运行效果图,方便移植
Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。在全球云计算和移动互联网的产业环境下...
纯java代码实现跨平台打印word、pdf、图片等信息,无需系统嵌入第三方dll文件等,方便,可移植性好。
众所周知,java开发语言提供了很方便的开发平台,而且开发出来的程序很容易在不同的平台上面进行移植,现在越来越多的人使用它开发软件。 Java有了它方便的一个方面,但是他同时也带给了开发者一个烦恼,这就是保护...