在针对尽可能多的功能手机(诺基亚3110 Classic,三星E250,摩托罗拉SLVR L7等)的项目中,如何在代码结构方面进行高级设计?我并不是指每个手机的支持,因为我们正在使用波兰语。
我是一名经验丰富的C#开发人员,正在我公司内部进行J2ME开发。几个月前,管理层聘请了一名高级J2ME开发人员,因为现有开发人员缺乏任何J2ME经验。我现在正在和另一位C#开发人员一起加入该团队,我们对我们所看到的内容都有所保留。虽然软件运行并满足业务需求,但应用程序的设计对我来说似乎完全错误。
不是使用OO,大多数代码都是由静态方法和常量组成,并且尽可能少的类(15,据我所知),因为“手机上的内存限制”。其中一些是数千行。显然,除了Canvas之外,没有使用任何内置的UI元素,因为它们“没有提供足够的控制”。
所有表单/窗口/页面(不确定正确的术语)在一个类中都有一个静态方法,其中我们有代码来设置该窗体/窗口/页面的UI。它如下:
UiElement items[] = new UiElement[8 + (fieldCount * 4)];
int y = 0;
items[y++] = new UiElement("name", UiElement.TYPE_TEXT_FIELD, "Name", TextField.ANY, true, "", true, null, -1, 0);
items[y++] = new UiElement("address", UiElement.TYPE_TEXT_FIELD, "Mobile", TextField.PHONENUMBER, true, "", true, null, -1, 0);
// ...
items[y++] = UiElement.LINE;
items[y++] = new UiElement("button", UiElement.TYPE_BUTTON, "Save", -1, false, "", true, null, UiElement.TYPE_LINK, ActionHandler.LINK_UPDATE_USER);
items[y++] = new UiElement("", UiElement.TYPE_RED_BUTTON, "Delete user", -1, false, "", true, null, UiElement.TYPE_LINK, ActionHandler.LINK_DELETE_USER);
items[y++] = UiElement.LINE;
items[y++] = new UiElement("", UiElement.TYPE_LINK_ARROWS, "Back to choose category", 0, false, "", true, null, -1, ActionHandler.LINK_MC_SELECT_CATEGORY);
items[y++] = UiElement.LINE;
UiElement的主要构造函数是
public UiElement(String RMSref, int inputType, String displayText, int additionalInputType, boolean mandatory, String aditional, boolean selectable, Image img, int displayType, int actionLink)
最后,调用将items数组保存在扩展Canvas的类上。该类有一个带有巨大开关块的paint方法,在UiElement的inputType上进行分支。从那里开始,它将转到“图形”类的静态方法,该方法为每种不同类型的“控件”提供了处理“控件”绘画的方法。
实际上,似乎所有事情都是程序性的,只有在必要时才使用OO。我已经问过高级开发人员为什么我们没有基类Control类,然后是子类,每个都有自包含的绘画,属性等,而不是这个通用的UiElement类,而且显然是因为很多类耗尽太多记忆。我也被告知有些手机有错误的Java运行时,因此他们没有正确释放内存。这也是只有一个Canvas的原因。
另一个例子是,所有文本输出都是通过使用位图字体完成的,而不是使用手机的内部字体渲染。我们被告知,它是为手机提供统一的渲染,而不是依赖于它们的内部字体集和大小。
这是正确的方法吗?我们被告知的事情是否正确?我希望尽量避免这种情况变成对TheDailyWTF的提交。
答案 0 :(得分:5)
欢迎来到j2me的世界。
随着时间的推移,情况变得更好了。但你所看到的实际上是最古老的手机(特别是诺基亚40系列(第1代))和古老的samsungs上的东西。这是一个事实,任何添加的类将使你的jar大小上升。由于某些手机的限制为64kb,因此任何字节都会计算。
如果这些旧手机不再被定位,你可以放弃这种古老的做法,更多地采用OO方式。
位图字体也是如此。在每个手机品牌(甚至是同一品牌的不同型号)上,手机拥有的字体大小差别很大。在摩托罗拉,如果要求一个小字体,一个人得到一个巨大的字体。更好的是,摩托罗拉上要求的任何字体都是巨大且不可行的。
手机字体的优缺点: - 手机字体不会花费宝贵的jar内存。位图字体代价高昂 - 位图字体在任何手机上看起来都一样 - 手机字体可以用任何颜色绘制(如果你想让它们有两种颜色,则必须将位图字体加倍。) - 最新的诺基亚手机实际上绘制了手机字体反锯齿,给出了非常好的结果。 Bitmp字体永远不会被抗锯齿,除非它已经在位图中完成,这意味着你只能在一种背景颜色上使用它们(也是一种抗锯齿颜色)。
无论如何,听起来你有一个开发人员有很多经验(行李?)的j2me编码。也许有点太多了。如果没有必要针对古老的手机,那么清理代码并使其更现代化。
答案 1 :(得分:2)
在J2ME开发中我们不能使用OOP原则,最好的方法是将所有内容保持在单个类中,即使没有任何软件包可以实现最佳内存使用。但是在编程方面,我们需要一些OO概念,比如将代码分成有用的类和包。但是你最好不要去那个Sub分类概念。在开发J2ME应用程序时,J2ME Polish非常有用。 IMO你正走在正确的道路上,由于堆大小有限,我们不能在开发J2ME应用程序时应用所有OOP,特别是在寻找涉及大量手机设备的通用J2ME应用程序时。
答案 2 :(得分:1)
我的价值0.02英镑:
内置UI组件(LCDUI)通常很可怕。如果您希望您的应用看起来像“手机原生”应用,它们会非常有用;但是你几乎无法控制它们的外观。在一部手机上看起来很漂亮的东西在另一部手机上看起来很糟糕而且不合适。使用LCDUI编写跨手机友好代码非常困难,我就像瘟疫一样避免使用。
滚动自己的基于画布的组件意味着您可以更好地控制手机的外观和行为。
关于字体,我个人不喜欢打扰位图字体。它们是缓慢的,重量级的,繁琐的,并且可能很难看起来正确,因为您需要实现自己的字距调整等,再加上国际化的内容?确实,一些手机字体是可恶的(旧的Motos,特别是重新提到的)。但是,请记住用户将习惯使用该手机,并且仔细的UI设计(和组件实现)意味着您可以使用任何大小的字体(请注意旧Motos给您的原因)如果你要求小,那就是它们实际上只有一种字体。
根据您的应用程序的作用,您需要解决许多很多模糊的手机错误。是的,有些手机在GC /内存分配方面有些怪癖会让你感到困惑。
然而,只有当你正在针对适当的古老/低记忆手机时,你才需要完全“把所有东西放在一个单一的类/方法中”极端。与IMO位图字体的开销相比,你在这个部门投入的任何努力都没有实际意义。
HTH
答案 3 :(得分:0)
我是第二个reiner的帖子。我想添加嵌入代码中的字符串是一个维护噩梦,最好将它们作为常量使用CustomStrings类。与图像/资产名称相同,它更容易维护。
我想要做的另一点是初始发布目标是高端(超过64k限制jar大小)手机。这种方式很轻松。稍后您可以添加对低端手机的支持。
此外,高级J2ME工程师似乎也知道他的方式,听听他关于J2ME开发的固有问题,不一定是解决方案。