Как бороться с наиболее распространенными классами, отсутствующими в J2ME

StackOverflow https://stackoverflow.com/questions/859449

Вопрос

Я пытаюсь написать приложение, которое работает на разных Java-платформах, таких как J2SE, J2ME, Android и т. д.Я уже знаю, что мне придется переписать большую часть пользовательского интерфейса для каждой платформы, но хочу повторно использовать основную логику.

Сохранение этого ядра портативным связано с тремя известными мне недостатками:

  1. Придерживаясь старого Синтаксис Java 1.4, не используя ни одной из приятных особенностей языка Java 5.0.
  2. только используя внешние библиотеки которые, как известно, работают на этих платформах (то есть:не используйте JNI и не имейте зависимостей от других библиотек, нарушающих эти правила)
  3. только используя классы, которые присутствуют на всех этих платформах

Я знаю способы преодоления (1):код в стиле 5.0 и автоматически конвертировать его в 1.4 (ретроткач - еще не пробовал, но вроде нормально).

Я думаю (2) это проблема, которую я просто должен принять.

Теперь я хотел бы знать, какой лучший обходной путь для (3), особенно занятия по коллекционированию, по которым я скучаю больше всего.Я могу думать о них:

  • Большинство программистов, которых я знаю, просто не используют Set, Map, List, и т. д.и возврат к Vector и простые массивы.Я думаю, что это в первую очередь делает код уродливым.Но я также знаю, что правильный выбор между TreeSet/Hashset или LinkedList/ArrayList имеет решающее значение для производительности, и всегда используйте Vector и массивы не могут быть правильными.
  • Я мог бы написать свои собственные реализации этих классов.Кажется, это изобретение велосипеда, и я думаю, что не смогу сделать это так хорошо, как другие.
  • Поскольку Java имеет открытый исходный код, я мог бы получить исходный код платформы J2SE Collections и включить его в свое приложение при сборке для J2ME.Хотя я не знаю, хорошая ли это идея.Возможно, есть веские причины не делать этого.
  • Возможно, уже существуют библиотеки, которые перестраивают наиболее важные функции структуры коллекций, но оптимизированы для систем начального уровня, возможно, за счет отсутствия реализации функций, которые используются нечасто.Знаешь ли ты какой-нибудь?

Спасибо за ваши ответы и мнения!

Редактировать: Наконец я нашел (сложное, но красивое) решение и подумал, что, предоставив свой собственный ответ и приняв его, решение станет видимым вверху.Но, наоборот, мой ответ все еще находится в самом низу.

Это было полезно?

Решение 2

Прошло много времени с тех пор, как я задавал этот вопрос, и с тех пор, как я нашел хорошее, работающее решение проблемы, но я забыл вам сказать.

Мое основное внимание уделялось Java Collections Framework, которая является частью java.util упаковка.

Наконец я взял исходный код Suns Java 6.0 и скопировал все классы, принадлежащие платформе Collections, в свой собственный проект.Это был проект Java 6.0, но в качестве пути к классам я использовал jar-файлы из J2ME.Большинство тех классов, которые я скопировал, зависят от других классов J2SE, поэтому зависимости есть неработающие.В любом случае, было довольно легко избавиться от этих зависимостей, оставив все, что связано с сериализацией (что для меня не является приоритетом), и внести некоторые незначительные изменения.

Я скомпилировал все это с помощью компилятора Java 6, а ретротранслятор использовался для портирования полученного байт-кода обратно в Java 1.2.

Следующая проблема — имя пакета, потому что вы не можете доставлять классы из java.util с приложением J2ME и загрузите их - загрузчик классов начальной загрузки не будет просматривать файл jar приложения, другим загрузчикам не разрешено загружать что-либо с этим именем пакета, а в J2ME вы не можете определять собственные загрузчики классов.Retrotranslator не только преобразует байт-код, но и помогает изменять ссылки на имена в существующем байт-коде.Мне пришлось переместить и переименовать все классы в моем проекте, например. java.util.TreeMap стал my.company.backport.java.util.TreeMap_.

Затем я смог написать настоящее приложение J2ME во втором проекте Java 6.0, который ссылался на обычный java.util.TreeMap, используя общий синтаксис для создания типобезопасных коллекций, скомпилируйте это приложение в байт-код Java 6.0 и запустите его через ретротранслятор, чтобы создать код Java 1.2, который теперь ссылается на my.company.backport.java.util.TreeMap_.Обратите внимание, что TreeMap это всего лишь пример, на самом деле он работает для всей структуры коллекций и даже для сторонних J2SE Jars, которые ссылаются на эту структуру.

Полученное приложение можно упаковать в виде файла jar и jad, и оно отлично работает как на эмуляторах J2ME, так и на реальных устройствах (проверено на Sony Ericsson W880i).

Весь процесс кажется довольно сложным, но поскольку я использовал Ant для автоматизации сборки и мне все равно нужен был ретранслятор, то на настройку резервного порта платформы сбора данных потребовались только единоразовые затраты.

Как указано выше, я сделал это почти год назад и пишу это в основном из головы, поэтому надеюсь, что в нем нет ошибок.Если вас интересует более подробная информация, оставьте мне комментарий.У меня есть несколько страниц немецкой документации по этому процессу, которую я мог бы предоставить, если возникнет необходимость.

Другие советы

J2ME жесток, и вам просто придется смириться с тем, что вам придется обойтись без некоторых тонкостей других платформ.Привыкайте к Hashtable и Vector и напишите поверх них свои собственные оболочки.Кроме того, не делайте ошибку, полагая, что J2ME является стандартом, поскольку JVM каждого производителя может выполнять действия совершенно по-разному.Поначалу я бы не особо беспокоился о производительности, поскольку просто добиться корректности на J2ME — уже достаточно сложная задача.Можно написать приложение, работающее на J2ME, J2SE и Android, как это сделал я, но это требует много работы.Я бы посоветовал вам написать ядро ​​логики вашего приложения и строго придерживаться java.lang, java.util и java.io.Везде, где вы собираетесь делать что-то, что может взаимодействовать с платформой, например с файловой системой или сетью, вы можете создать интерфейс, с которым взаимодействует код вашего основного приложения, и у вас будут разные реализации для разных сред.Например, у вас может быть интерфейс, который включает в себя HTTP-материалы и использует javax.microedition.io.HttpConnection с J2ME и java.net.HttpURLConnection на Android.Это неприятно, но если вы хотите, чтобы приложение работало во всех трех этих средах, оно поможет вам в этом.Удачи.

Именно с такой ситуацией мы столкнулись при разработке zxing.Если J2ME находится в вашем списке целей, это, безусловно, ваш ограничивающий фактор.Мы ориентировались на MIDP 2.0/CLDC 1.1.Если у вас аналогичные требования, вам нужно придерживаться Java 1.2.Функции языка Java 1.4 определенно отсутствуют (например, Assert), и в целом вы не найдете ничего после версии 1.2 в J2ME.

Мы не использовали внешние библиотеки, но вы можете без особых проблем упаковать их в развернутый файл .jar.Это приведет к увеличению размера полученного .jar, и это может стать проблемой.(Затем вы можете попробовать оптимизаторы/сжиматели, такие как ProGuard, чтобы смягчить это.)

В итоге я переопределил что-то вроде Collections.sort() и Comparator, поскольку они нам нужны, а в J2ME их нет.Так что да, вы можете рассмотреть возможность сделать это в некоторых случаях, но только там, где это необходимо.

Мы использовали Vector, Hashtable и массивы, поскольку в J2ME другого выбора фактически нет.Я бы просто использовал их, если у вас нет причин не делать этого, и я думаю, это будет производительность.Теоретически производители JVM уже оптимизируют свою реализацию, но это не значит, что вы не можете сделать лучшую...Думаю, я был бы удивлён, если бы оно того стоило в подавляющем большинстве случаев.Просто убедитесь, что вам действительно нужно это сделать, прежде чем прикладывать усилия.

Чтобы ответить на часть вашего вопроса, другая библиотека коллекций будет Яволюция который можно построить для j2me.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top