воскресенье, 4 сентября 2011 г.

Java головного мозга. Введение в разработку на JavaMe



“- Ассистент, где мой гальванизатор! - Доктор, снова вы за старое, сколько же можно издеваться над трупом? - Ничего, рано ей еще, пускай послужит людям!” - такой диалог пронесся в голове RED’а, когда он преступал к своим бесчеловечным опытам над Java ME.

Чем интересна платформа Java Me, я уже рассказывал в одной из своих статей. Сегодня пришло время разобраться, что из себя представляет разработка на этой платформе, какие подводные грабли она таит, и что стоит ожидать разработчику, привыкшему к современным языкам программирования.
Для начала нам понадобится среда разработки. Варианта три: Eclipse Pulsar, Netbeans и IDEA. Для своих экспериментов я выбрал Netbeans, т.к. это нативная среда разработки под Java Me (и бесплатная, что немаловажно), непосредственно от производителя платформы. Чтобы мы смогла отлаживать MIDlet’ы, нам понадобятся эмуляторы. И вот здесь начинаются проблемы... Java ME, платформа старая и эмуляторы под 64-битные системы отсутствуют (хотя может у Nokia они и есть), а 32-битные эмуляторы на вышеупомянутом типе систем ведут себя крайне странно, либо совсем не запускаются, либо запускаются после пляски с бубном. Поэтому, если вы серьезно решили заняться разработкой под JavaMe, обзаведитесь 32-битной операционной системой, скажем, в виртуальной машине. Мой выбор пал на Ubuntu, что не удивительно ;-)
Далее нам понадобится Java-машина. Но не абы какая, а sun’овская. OpenJDK не подойдет. Под Windows проблем на данном этапе возникнуть не должно, а вот под Ubuntu пакетов sun-java нет  в стандартном репозитории. Но это легко лечится добавлением следующей строки в файл /etc/apt/source.list
deb http://archive.canonical.com/ natty partner
Далее делаем apt-get update и apt-get install sun-java-6*. Если у вас ранее уже стояла OpenJDK, вам необходимо переключить контекст выбора Java-машины, для этого выполните update-alternatives --config java и выбирете нужный JDK.
Со средой разработки и платформой вроде разобрались, теперь коснемся самих эмуляторов. Существуют как классические (нативные) эмуляторы от sun, так и эмуляторы от производителей сотовых телефонов. Классические - это Java Wireless Toolkit (существует как для Windows, так и для Linux) и эмулятор, входящий в сборку Netbeans для Windows (бывший JavaMe SDK Emulator). От сторонних производителей следует выделить MOTODEV SDK и NOKIA SDK. Для обучения платформе хватит и классического Wireless Toolkit, но если вы хотите распространять ваш MIDlet на реальных телефонах, то стоит посмотреть в сторону сторонних SDK. Объясняется это тем, что Wireless Toolkit плохо учитывает некоторые ограничения реальных устройств, поддерживающих Java Me. В частности, если вы не будете закрывать, к примеру, сетевые сокеты, то на реальных устройствах при попытке создать ~10 подключение получите сообщение об ошибке, но на эмуляторе Wireless Tolkit все будет работать.
Далее, если вы выбрали в качестве среды разработки Netbeans, вас ждет интересный сюрприз. В Netbeans имеются так называемые Visual MIDlet. Если вы думаете, что это простая “рисовалка” формочек, то вы глубоко ошибаетесь, ведь это ни что иное, как графическое программирование. При желании можно написать работающее приложение накидав нужные блоки на экранчик и соединив их стрелочками. К примеру, нам надо написать приложение, которое стартует, показывает нам заставку, затем проверяет, имеются ли сохраненные настройки пользователей, если имеются, то произвести аутентификацию сразу, иначе вывести форму ввода логина и пароля. После аутентификации вывести рабочую форму. Взглянем на нижеприведенный скриншот:
Как видно из скриншота, логика работы программы полностью отражена на схеме. Сама схема и является программой. Разработчику остается лишь вставить необходимые обработчики (описать AuthTask и isLogedIn) и MIDlet готов к работе! Правда здорово? Такой подход очень применим к мобильным устройствам, т.к. их интерфейс - это набор маленьких экранов, каждый из которых выполняет свою операцию. Правда, по своему опыту хочу вас предупредить, писать крупное приложение при помощи визуалайзера не стоит - перестроение схемы начинает тормозить, на каждый чих приходится создавать объекты, и сложнее становится рефакторить приложение. Одним словом, теряется гибкость разработки. Но для небольших приложений и для начинающих разработчиков визуалайзер - ценнейшая находка.
Хорошо, на чем писать и как запускать мы знаем. Теперь поговорим о плюшках для разработчика и о базовых технологиях, а именно: базовые особенности платформы, работа с сетью, персистентное хранилище настроек, unit-тестирование.
Базовые особенности
К основной базовой особенности можно отнести отсутствие рефлексии. Но оно и понятно, зачем для мобильных устройств оно надо?  Но вот остальные особенности огорчают. Так в частности отсутствуют generic-объекты (правда, если очень хочется, есть Hashtable и Vector, очень примитивное подобие generics), необходимо явно закрывать все сессии и соединения, иначе получите невнятные сообщения об ошибках, а получите вы их очень скоро, т.к. лимит на число соединений в JavaMe не более ~10. Так же нет возможности выполнить дамп stacktrace в переменную. В stdout - пожалуйста, а вот в переменную барин запретил. Самое печальное в этой ситуации то, что stdout в JavaMe переназначить нельзя. Поле out класса System помечено как final. Из-за этого отладка JavaMe-приложений на реальных устройствах становится крайне затруднительной (на эмуляторах консоль можно просмотреть).
Работа с сетью
Имеющаяся поддержка сети заставляет разработчика биться головой об стену в истерике. C developers.sun.com позаимствовал схему имеющегося сетевого стека.
Если вы начали радостно прыгать и хлопать в ладоши с криками “ура! тут даже есть http и https”, то спешу вас разочаровать. Оно конечно есть... но это как кондиционер в отечественном авто - вроде дует, а толку мало. Вот и здесь поддержка http есть на уровне того, что можно поставить заголовки запроса и тело. А больше ничего нельзя. Поддержку cookie, http-форм, put\delete-запросов придется делать самому. Примеры кода я приводить не буду, вы можете посмотреть их здесь.
Хранилище записей
Хранилище записей, оно же Record Managеment System (RMS), позволяет сохранять данные в постоянное хранилище и восстановить их при следующем запуске MIDlet’а. Подробная информация о RMS доступна здесь. От себя же добавлю, что оно крайне неудобно. Это из-за того, что записи храняться в виде многомерного массива. Т.е. каждая запись - это набор байт, который привязывается к одной из ячеек хранилища. При этом хранилище можно заполнять лишь последовательно. Неудобство, на мой взгляд, в том, что нельзя использовать строковые ключи (потому что отсутствует понятие Map-объектов как таковых). Если у вас много параметров, которые нужно хранить - воспользуйтесь Google Protobuf для Java Me, сериализуйте объект параметров и сохраните его в единственной записи RMS.
Unit-тестирование
Существует библиотека JMUnit. На официальном сайте есть очень хороший PDF-мануал.  Но данная библиотека по концепции сильно отличается от классического JUnit. Все тестирования происходят в эмуляторе. Набор тестов - это MIDlet. По-умолчанию создается test-sute, объединяющий все test-case’ы. Тут всплывают подводные грабли.  Test-sute, так же как и test-case является MIDlet’ом. Но современные реализации JavaMe платформы запрещают вызов MIDlet из MIDlet’a. Так что не удивляйтесь, если ваши тесты не запустятся ни на чем кроме  Wireless Toolkit. На самом деле проблема решаема, нужно просто запускать каждый test-case отдельно. Создатели JMUnit так же позаботились и о mock-объектах, создав библиотеку Hammock.
На этом, наш небольшой экскурс в JavaMe закончен. Описанного в этой статье (с учетом внешних ссылок) хватит, чтобы гальванизировав труп JavaMe, начать его использовать ;-)

Комментариев нет:

Отправить комментарий