Автор/Источник: Антон Борисов» 04.02.2008 22:29, просмотров сегодня: 1, всего: 5872
статья размещена в группе: Программирование
оценка: 3.4, 10 голосов
Создание мульти-платформенных приложений может иногда приносить массу удовольствия и служить пищей для размышления. Как показывает практика, не проблема создать приложение под одну определенную операционную систему. Также не является трудным выбор языка программирования — все мы учились этому когда-нибудь и где-нибудь. Крайне актуальным является, на мой взгляд, следующее — перенос кода на новую платформу. При этом не изменяя функциональности оригинального кода или, если сформулировать иначе, не добавляя лишний функционал в код. Чтобы в результате у нас вместо одного исходного кода не получилось двух разных ветвей одного и того же кода.
Разрабатывая программу для настольных машин человек особо не задумывается, какой инструментарий использовать. Это может быть как wxWidgets (раньше известный как wxWindows), FLTK (Fast LightWeight ToolKit), QT (инструментарий от одной небольшой компании в Скандинавии) и некоторые другие. В любом случае, код написанный единожды, можно будет перекомпилировать как под Unix-, так и под Windows-платформу. Упор здесь делается на то, что разработчики данного инструментария сами прилагают определенные усилия, чтобы их решение (тулкит) было работоспособно под ту или иную операционную систему. Автору же оригинального кода, т.е. мультиплатформенного приложения, остается только грамотно использовать конструкции языка и того инструментария, на котором основано приложение wxWidgets, FLTK и т.д.
Повторюсь, что проблем с настольными системами на сегодняшнее время практически всё меньше и меньше. Ни для кого не будет сюрпризом, если окажется, что исполняемый (скомпилированный) код вам нужно предоставлять как для, например, Windows NT, Linux и MacOS X. Отмеченные выше тулкиты отлично покажут себя для указанных платформ. Вся острота проблемы возникнет при желании конечного потребителя получить приложение еще и под PocketPC-платформу. А как вы помните, то до появления термина PocketPC существовала, да, пожалуй, существует и сегодня, линейка устройств HandHeld PC (H/PC). По сути более ранняя линейка PocketPC-устройств.
Можно обратиться к eVC++ (embedded Visual C++) и Microsoft Visual Studio 2003/2005. Но в этом случае, для Windows Mobile 2002 придется использовать eVC++, для компиляции кода под Windows Mobile 2003 — Microsoft Visual Studio 2005. Конечно, исполняемый код для WM2002 будет запускаться и в более поздних версиях Windows CE. Но! Как только возникнет вопрос «A что делать в случае, когда тот же код желательно иметь и в Unix-системе", то сразу возникнет противоречие. И дело здесь не в том, что производители указанных операционных системы в этом случае разные. Мол, будь это одна корпорация или организация, то вопросы совместимости кода утряслись бы. А проблема в том, что для создания программы нужно будет вводить в код массу конструкций вида:
#if defined (__WIN32__)
... код, специфичный для WindowsNT ...
#endif
#if defined (__WINCE__)
... код, специфичный для WindowsCE ...
#endif
#if defined (__UNIX__)
... код, специфичный для UNIX ...
#endif
Понятно, что по мере роста кода программы, затраты на разработку такого приложения возрастают. Особенно интересна здесь отладка программ — под всеми системами, использованными в #if defined ... #endif. Плюс, и это подразумевается по умолчанию, вам нужны будут компиляторы под указанные платформы. Ну и, конечно, придется запастись терпением.
Использование тулкитов, указанных выше, решает проблему мульти-платформенности. Но и здесь есть подводные камни. В частности, компания Trolltech предлагает QT4/CE с заявленной поддержкой Windows Mobile 2003 и более поздних версий (WM5, WM6). И технологически, версии для Windows Mobile 2002 не будет. Реализация инструментария FLTK для PocketPC всё еще заявлена в планах, хотя есть пара сообщений, что некоторым удалось собрать FLTK для PocketPC. Однако повторюсь — официально, FLTK всё еще не поддерживает PocketPC. И более того, даже при внимательном рассмотрении выясняется, что портирование произведено для WM2003 и WM5. Чтоже касается wxWidgets, то и с ним также не всё так гладко, как хотелось бы.
В итоге, выясняется, что использование только решений от Microsoft, миром Microsoft и ограничивается. При использовании более универсального решения, в виде разных тулкитов, выявляются проблемы совместимости с ранними версиями операционной системы WinCE. При этом, вы явно или неявно работаете в качестве своеобразного контроля качества, т.е. тестируете не только свой код, но и код самого тулкита. Очевидно, что нужен толчок к более универсальному решению.
И такое решение на самом-то деле есть. Это настолько часто используемое решение, что зачастую деревьев из-за леса не видно. И называется оно Java. Достоверно неизвестно, какие суммарные затраты испытала Sun Microsystems, доводя до ума и выводя на рынок такой универсальный инструмент. Но что точно известно, так это то, что такой гигантский труд себя оправдал. Во-первых, сумасшедшее количество проектов так или иначе основано на Java. Во-вторых, использование Java не ограничивается только узким сегментом настольных ЭВМ вам должно быть известны такие аббревиатуры, как J2SE / J2EE / J2ME. Где последняя расшифровывается как MicroEdition, т.е. предназначена для устройств с малыми требованиями к памяти и ресурсам. И в третьих, открытая спецификация на Java. Только в этом году она была полностью открыта. Но некоторые механизмы были открыты еще несколько лет назад, что позволило создать и альтернативные варианты. Такие, как SuperWaba, из которой, в свою очередь, появилась и EWE. Вот с последней мы сегодня и познакомимся.
Изюминка концепции Java заключается в следующем — вы компилируете исходный код в промежуточный, так называемый байт-код. Который, в свою очередь, исполняется в виртуальной Java-машине (JVM). Почему виртуальная? В силу того, что доступа у этого кода к самой операционной системе нет. Корректность выполнения возлагается на JVM. Управление ресурсами также возлагается на плечи JVM. Т.е. фактически, имея безупречное поведение такого промежуточного слоя между программой и операционной системой, программисту оставили только право правильно использовать языковые конструкции. Отладка и некорректное поведение программы почти сходит на нет. Выигрыш? Несомненно.
Имея JVM для различных платформ автоматически приводит нас к выводу, что грамотнее всего полагаться именно на Java. Кроме того, сами JVM досконально тестируются самим изготовителем, так что все усилия можно перебросить непросредственно на создание программного обеспечения.
И вот на этом этапе нас поджидает несколько ловушек. Первое, и самое главное, Sun Microsystems прекратила распространять свою версию J2ME PersonalJava. Хотя ходят слухи, что разработка над проектом Captain America не прекращалась, и Sun просто дожидается насыщения ранка, чтобы выпустить обновленную версию. Которая теперь будет называться PhoneME. Впрочем, название вас не должно пугать — это все та же PersonalJava. И второй момент. Даже несмотря на ту открытость, что присуща Sun, и наличие на рынке нескольких вариантов Java-машин, почти все они являются платными. Варианты лицензирования для персонального использования могут отличаться, но для коммерческой эксплуатации необходимо будет покупать лицензии.
Чтобы использовать EWE в коммерческом применении, то ограничений и лицензирования не наблюдается. Данная реализация Java свободна. Правда, придется ознакомиться с теми различиями, которые в EWE по сравнению с чистой Java есть.
Библиотека классов в EWE другая, нежели в Java. Правда, используются несколько классов из чистой Java — это java.lang и java.lang.reflect. Второе различие — изменена потоковая модель. Функционал такой же, что и в настоящей Java, однако механизм реализации изменен. Поэтому, вам не следует использовать методы wait(), notify() и класс Thread. А следует использовать класс mThread с методами sleep(), nap() или yield(). И третье различие — запуск программ, написанных на EWE, отличается от привычного механизма, известного в Java.
Итак, что нам потребуется для написания приложения?
- SDK для EWE, в который входит библиотека классов и упаковщик объектов (Jewel Program Builder)
- Виртуальная машина EWE под те платформы, на которых вы предполагаете запускать приложение
- Компилятор Java-кода
В качестве компилятора может выступать javac из состава Java SDK от Sun Microsystems. Следует еще раз напомнить, что концептуальных различий между EWE и Java от Sun нет. Есть различия в реализации определенных механизмов, но байт-код един. Поэтому вы сможете запускать код не только в виртуальной машине EweVM, но и в Sun JVM.
Давайте приступим. Для начала воспользуемся тем классическим примером, что поставляется в комплекте с руководством Ewe Application Development.
Исходный текст Welcome.java
01) package test;
02) import ewe.ui.*;
03)
04)//##################################################################
05) public class Welcome{
06) //##################################################################
07)
08) //===================================================================
09) public static void main(String args[])
10) //===================================================================
11) {
12) ewe.sys.Vm.startEwe(args);
13) MessageBox mb = new MessageBox(
14) «Welcome»,
15) «Welcome to my first Program!\nI hope it works well.»,
16) MessageBox.MBOK);
17) mb.execute();
18) ewe.sys.Vm.exit(0);
19) }
20) //##################################################################
21) }
22) //##################################################################
Данный файл мы должны поместить в директорию test. Обратите внимание на первую строчку в файле Welcome.java. Мы как бы создаем отдельный пакет test, в котором у нас будут содержаться несколько классов будущей программы (имеется ввиду несколько скомпилированных классов). Если конечно программа дорастет до таких размеров.
В строке 2) подключаются объявления, необходимые для использования класса MessageBox. Между строками 5) и 21) находится реализация нашего класса Welcome. Строка 9) — объявление функции main() — ничем не отличается от классического аналога в Sun Java. Различия — в механизме старта программы — его особенности отражены в строках 12) и 18). Мы должны явно запустить EweVM и благополучно выйти из нее. В строке 13) объявили MessageBox с необходимыми параметрами. И показали форму на экране, запустив через метод execute() — строка 17).
Затем мы должны скомпилировать и полученный Welcome.class запустить на исполнение. Для этих целей целесообразно составить командный файл, например, jcompile.sh
Исходный текст командного файла jcompile.sh
#!/bin/sh
JAVA=/usr/bin/java
JAVAC=/usr/bin/javac
CLASSPATH=/home/anthony/src/ewe/classes/ewe.jar
JEWEL=/home/anthony/src/ewe/programs/Jewel.ewe
Print_Usage()
{
cat <<EOF
Usage: jcompile.sh Path_To_Java_Src
e.g.: jcompile.sh Samples/Welcome
EOF
}
if [ -z $«*" ]; then
Print_Usage;
exit;
fi
FILENAME=`echo $*`
$JAVAC -classpath $CLASSPATH $«FILENAME».java
$JAVA -cp $CLASSPATH:./ Ewe $FILENAME
$JAVA -cp $CLASSPATH:./ Ewe $JEWEL
Он предназначен для Unix-системы. Впрочем, не составит трудности переписать его и для Windows-платформы.
В ходе выполнения командного файла будет скомпилирован и запущен на выполнение байт-код, а затем запустится упаковщик объектов (Jewel Program Builder). Последний нужен для того, что получить полноценное .exe приложение для запуска на КПК. Там же можно будет поменять некоторые параметры в новом приложении, в частности, используемую пиктограмму.
Запускаем.
./jcompile test2/Welcome
Я забегу немного вперед и скажу, что конечный результат у вас должен получиться без всяких проблем.
Полученный код на Windows Mobile 2002 выглядит так:
Рис.1 — Тестовое приложение Welcome в среде WM2002
И, как видите, его внешний вид не сильно отличается и в Windows Mobile 6:
Рис.2 — Тестовое приложение Welcome в среде WM6
Впрочем, это было самое тривиальное приложение. Самое интересное сделать приложение, генерирующее знаменитую картинку фрактала Мандельброта.
Исходный текст SampleBox.java
package samples.paint;
import ewe.graphics.*;
import ewe.fx.*;
import ewe.ui.*;
//##################################################################
public class SampleBox extends InteractivePanel {
//##################################################################
public static int MAXITERATION = 1000;
public int Color;
public int Offset = 250;
//===================================================================
public void setupBox(int screenSize)
//===================================================================
{
Image b = new Image(screenSize, screenSize);
Graphics g = new Graphics(b);
for( int i = 0; i < screenSize; i++ )
for( int j = 0; j < screenSize; j++ )
{
Color = getColor(
(double)(i — Offset / 1.6) / screenSize / 0.5,
(double)(j — Offset / 2.5) / screenSize / 0.5 ) & 0xFF;
g.setColor(new Color(Color, Color, 0));
g.fillRect( i, j, 1, 1);
}
setAndSizeToBackgroundImage(b);
setPreferredSize(screenSize,screenSize);
}
public int getColor( double x0, double y0 )
{
int iteration = 0;
double x, y;
double xtemp, ytemp;
int color = 0;
x = x0; y = y0;
while( ( x * x + y * y < 4 ) && iteration < MAXITERATION )
{
xtemp = x * x — y * y + x0;
ytemp = 2 * x * y + y0;
x = xtemp;
y = ytemp;
iteration++;
}
if( iteration == MAXITERATION ) color = 0;
else color = iteration;
return(color);
}
//===================================================================
public static void main(String args[])
//===================================================================
{
ewe.sys.Vm.startEwe(args);
Form f = new Form();
SampleBox b = new SampleBox();
b.setupBox( 200 );
f.addLast(b);
f.exitSystemOnClose = true;
f.title = "SampleBox";
f.show();
//ewe.sys.Vm.exit(0);
}
//##################################################################
}
//##################################################################
Комментарий.
Мы помещаем на сей раз SampleBox.java в директорию samples/paint. О чем говорит строка package samples.paint;
Затем подключаем нужные определения классов
import ewe.graphics.*;
import ewe.fx.*;
import ewe.ui.*;
Объявляем наш класс SampleBox как производный от InteractivePanel. Последний, в свою очередь, является производным от класса Canvas, в котором возможна работа с графикой. Затем объявляем метод setupBox() и функцию getColor(), в которой и производится непосредственный обсчет значений для фрактала.
Посмотрим теперь, как оформлена функция main().
Мы по-прежнему запускаем EweVM как ewe.sys.Vm.startEwe(args);
Сделали экземпляр класса Form и SampleBox. В форму добавили SampleBox. Заполнили значения во фрактале с количеством точек 200 x 200:
b.setupBox( 200 );
Указали также, что при нажатии на кнопку X (Закрыть) завершать выполнение EweVM — это конструкция вида:
f.exitSystemOnClose = true;
По этой же причине, закомментировали явное завершение EweVM
ewe.sys.Vm.exit(0);
Придумали заголовок для приложения:
f.title = «SampleBox»;
И показали конечный вариант:
f.show();
Теперь давайте выясним, как на самом деле выполняется старт приложения. Допустимы 5 вариантов запуска: классически, через функцию main() или используя объекты Runnable, Form, LiveData, mApp.
Фактически, в данном примере использованы оба варианта — через функцию main() и объявляя объект Form. На самом деле, мы использовали объект типа Form, который был запущен через функцию show(). Закомментировав условие явного завершения виртуальной машины и используя f.exitSystemOnClose = true;, мы показали, что обработка выхода из EweVM реализована при закрытии формы.
Выполнялось данное приложение на устройстве с процессором PXA255, 400 MHz достаточно долго. Подсчет длился примерно 7-8 минут. Я думаю, что точное значение времени вы сможете узнать, когда найдете в EWE API нужные функции работы с датой. А как вывести кнопку — вы уже знаете.
И знакомую картинку мы сможем видеть даже на WM2002.
Рис.3 — Фрактал Мандельброта формируется за 7-8 минут на PocketPC
Тот же самый код аналогично будет выполнен как в Unix-системе ...
Рис.4 — Фрактал запускается на Linux-машине без перекомпиляции
... так и в Windows NT
Рис.5 — Фрактал не требует перекомпиляции и в Windows NT
Выше мы уже коснулись того, где формируется исполняемые .exe файлы под различные платформы. Это Jewel Program Builder. По сути, там производится генерация объектного кода, который состоит из байт-кода и так называемой stub-части. Которая является обычным пустым .exe под нужную платформу: Win32, WinCE 2.0, WinCE 3.0 и т.д. Из stub-кода также происходит вызов библиотеки Ewe.dll, которая является виртуальной машиной. Она-то и обработает байт-код.
Т.к. выполнение SampleBox все-таки связано с многочисленными математическими вычислениями, то я предлагаю немного упростить программный код. Метод setupBox() сделать таким:
//===================================================================
public void setupBox(int screenSize)
//===================================================================
{
Image b = new Image(screenSize, screenSize);
Graphics g = new Graphics(b);
for( int i = 0; i < screenSize; i++ )
for( int j = 0; j < screenSize; j++ )
{
g.setColor(new Color(i, j, 0));
g.fillRect( i, j, 1, 1);
}
setAndSizeToBackgroundImage(b);
setPreferredSize(screenSize,screenSize);
}
Теперь наше приложение будет выполняться на PocketPC намного быстрее. Хотя на настольной ЭВМ оно выполняется также быстро, как и предыдущее.
Рис.6 — Заменим функцию setupBox() на более простую
Последняя строка в файле jcompile.sh запускает Jewel Program Builder.
Рис.7 — Запускаем компоновщик Jewel Program Builder
Здесь от нас требуется выбрать скомпилированный класс в поле Starting Class, нажав на кнопку Single Class File. Далее вы должны нажать на Create Ewe File и затем перейти в следующий таб — Create Programs.
Рис.8 — Выбираем нужные платформы
Поставьте галки у тех платформ, исполняемый код для которых вам нужно получить.
Потом нажимаете на кнопку сборки Build Targets и дожидаетесь окончания процесса.
Рис.9 — Запускаем процесс формирования исполняемых файлов
Готовую продукцию ищите в директории, где у вас находится Jewel. В моем случае сформировались поддиректории SampleBox, SampleBox2 и Welcome в директории /home/anthony/src/ewe/programs/
В свою очередь, в них будут сформированы поддиректории для каждой платформы. Например, Jar, PocketPC-ARM, PocketPC2003. Т.е. для тех платформ, где вы поставили галки.
Скопировав полученный .exe файл на КПК и запустив его там, вы увидите картинку следующего характера:
Рис.10 — Обновленное приложение требует меньше математических вычислений
Сразу будут заметны своеобразные квадраты в изображении. Надеюсь, вы сможете догадаться почему ;-)
В случае, если приложение не запустилось, проверьте, а есть ли EweVM на вашем КПК. Не забыли ли вы его установить? В частности, должен быть файл Ewe.dll. Тем более, что вы помните — перед нами байт-код, а не native-приложение для WinCE. Поэтому-то и его размер порядка 10 Кб.
На сегодня все. Удачного изучения Java и EWE!
Полезные ссылки:
Виртуальная машина EweVM и SDK
http://www.ewesoft.com
|