如何处理 J2ME 上缺少的最常见类

我正在尝试编写一个运行不同Java平台的应用程序,如J2SE,J2ME,Android等。我已经知道我必须为每个平台重写大部分UI,但希望重用核心逻辑。

保持这个核心可移植性涉及我所知道的三个缺点:

  1. 保持旧的Java 1.4语法,不使用Java 5.0的任何不错的语言功能
  2. 仅使用已知可在这些平台上工作的外部库(即:不要使用 JNI,并且不依赖于其他违反此规则的库)
  3. 仅使用所有这些平台上存在的类

我知道克服(1)的方法:以5.0风格编写代码并自动将其转换为1.4(retroweaver - 尚未尝试过,但似乎还可以)。

我认为(2)是一个我必须接受的问题。

现在我想知道(3)的最佳工作周期是什么,特别是我最想念的集合类。我能想到这些:

  • 我认识的大多数程序员只是不使用 、 、 等,而是回退到和普通数组。我认为这首先使代码变得丑陋。但我也知道,在或之间做出正确的选择对于性能至关重要,并且始终使用和 Arrays 不可能是正确的。SetMapListVectorTreeSet/HashsetLinkedList/ArrayListVector
  • 我可以编写我自己的类的实现。这似乎是在重新发明轮子,我认为我无法像其他人那样做得那么好。
  • 由于Java是开源的,因此在为J2ME构建时,我可以获取J2SE集合框架的源代码并将其包含在我的应用程序中。不过,我不知道这是否是一个好主意。有充分的理由不这样做。
  • 也许已经存在库,它们重建了集合框架中最重要的功能,但针对低端系统进行了优化,通过不实现不经常使用的功能来说明。你知道吗?

感谢您的回答和意见!

编辑:我终于找到了一个(复杂但很好)的解决方案,我认为通过提供我自己的答案并接受它,解决方案将在顶部变得可见。但恰恰相反,我的答案仍然在最底层。


答案 1

J2ME是残酷的,你只需要听天由命地去做其他平台的一些细节。习惯 Hashtable 和 Vector,并在这些之上编写自己的包装器。另外,不要错误地认为J2ME是标准的,因为每个制造商的JVM都可以以截然不同的方式做事。我最初不会太担心性能,因为仅仅在 J2ME 上获得正确性就足以构成挑战。可以编写一个在J2ME,J2SE和Android上运行的应用程序,就像我所做的那样,但这需要大量的工作。我有一个建议是,你编写应用程序逻辑的核心,并严格遵守java.lang,java.util和 java.io。在任何地方,只要您要执行可能与平台交互的操作(例如文件系统或网络),都可以创建一个核心应用程序代码与之交互的接口,该接口针对不同的环境具有不同的实现。例如,你可以有一个接口来包装HTTP的东西,并在Android上使用javax.microedition.io.HttpConnection和J2ME和java.net.HttpURLConnection。这很痛苦,但如果你想保持一个应用程序在所有这三个环境上运行,它可以让你到达那里。祝你好运。


答案 2

自从我问这个问题以来已经有一段时间了,自从我找到了一个很好的,有效的解决方案以来,我已经忘记了告诉你。

我的主要关注点是Java Collections Framework,它是软件包的一部分。java.util

我终于采用了 Suns Java 6.0 的源代码,并将属于 Collections 框架的所有类复制到我自己的项目中。这是一个 Java 6.0 项目,但我使用 J2ME 中的 jar 作为类路径。我复制的大多数类都依赖于其他 J2SE 类,因此存在损坏的依赖项。无论如何,通过省略处理序列化的所有内容(这对我来说不是优先事项)和一些小的调整,很容易减少这些偏差。

我用Java 6编译器编译了整个事情,并使用反转录器将生成的字节码移植回Java 1.2。

下一个问题是包名称,因为您无法从 J2ME 应用程序传递类并加载它们 - 引导类装入器不会查看应用程序 jar 文件,不允许其他引导装入程序使用该包名称加载某些内容,并且在 J2ME 上,您无法定义自定义类装入器。Retrotranslator不仅可以转换字节码,还可以帮助更改现有字节码中的名称引用。我必须移动并重命名项目中的所有类,例如 成为。java.utiljava.util.TreeMapmy.company.backport.java.util.TreeMap_

我能够在第二个Java 6.0项目中编写实际的J2ME应用程序,该项目引用了通常的,使用通用语法创建类型安全集合,将该应用程序编译为Java 6.0字节代码,并通过反转录器运行它以创建现在引用的Java 1.2代码。请注意,这只是一个例子,它实际上适用于整个集合框架,甚至适用于引用该框架的第三方J2SE Jar。java.util.TreeMapmy.company.backport.java.util.TreeMap_TreeMap

生成的应用程序可以打包为jar和jad文件,并且可以在J2ME仿真器和实际设备上运行良好(在索尼爱立信W880i上进行测试)。

整个过程似乎相当复杂,但是由于我使用Ant进行构建自动化,并且无论如何我都需要重译器,因此设置收集框架向后移植只有一次性开销。

如上所述,我在将近一年前就已经这样做了,并且主要是从我的头顶上写的,所以我希望它没有错误。如果您对更多细节感兴趣,请给我留言。我有几页关于这个过程的德语文档,如果有任何需求,我可以提供。


推荐