Логин:   Пароль:






Новости
Рассылки
Форум
Поиск


Java
- Апплеты
- Вопрос-ответ
- Классы
- Примеры
- Руководства
- Статьи
- IDE
- Словарь терминов
- Скачать

Мобильная Java
- Игры
- Примеры
- Статьи
- WAP, WML и пр.

JavaScript
- Вопрос-ответ
- Примеры
- Статьи

Веб-мастеринг
- HTML
- CSS
- SSI

Разминка для ума
Проекты
Книги
Ссылки
Программы
Юмор :)




Rambler's Top100
Rambler's Top100

Мобильная Java: СтатьиПрограммирование устройств с MIDP

Программирование устройств с MIDP

Часть 1

Майкл Саймерман

Концепция API MIDP и J2ME построения беспроводных межплатформенных приложений.

Обзор

Производители могут использовать устройства, совместимые с MIDP для разработки приложений, которые могут работать на различных беспроводных платформах, при этом доработка под платформу и настройка минимальны. В этой статье, которая является первой в серии из трех частей, рассматривается концепция API MIDP и платформы J2ME. Будут представлены API, используемые для создания графического, шаблонного, сохраняемого кода, который служит для соединения с внешними ресурсами. (3500 слов)

Беспроводная промышленность поражает очевидцев скоростью развития технологий. Из-за высоких темпов любой новый продукт может устареть в течение нескольких месяцев. Результатом динамичного развития является недостаток стандартизации рабочих платформ в беспроводной среде. Команды разработчиков сталкиваются с необходимостью осваивать многочисленные языки разметки и процессы, чтобы их продукт работал с разными устройствами. Отделу маркетинга постоянно приходится менять направление продвижения на изменяющемся рынке.

Устройства, совместимые с профилем мобильных информационных устройств (MIDP) позволят производителям разрабатывать приложения, которые будут работать на многочисленных платформах без больших усилий по настройке и переработке для каждой платформы. Это, в свою очередь, позволит разработчикам сконцентрироваться на функциональности систем.

Данная статья является первой из трех в цикле, имеющем целью представить читателю концепции API MIDP и платформы Java 2 Micro Edition (J2ME). Мы рассмотрим API, используемые для создания графического, шаблонного, сохраняемого кода, который позволит подключаться к внешним ресурсам.

Введение в J2ME

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

Платформа J2ME строится на языке программирования Java для того, чтобы обеспечить максимальную функциональность для устройств с ограниченными ресурсами. Обеспечивается базовый набор функций и ряд специализированных классов.

В этой статье основной упор делается на рассмотрение CLDC (конфигурации подключения устройств с ограничениями) и классов MIDP. Такие наборы классов составляют так называемый профиль в терминах J2ME. Профиль предусматривает сильные ограничения по памяти устройств, скорости процессора, емкости аккумуляторов и пропускной способности канала.

Введение в API CLDC

CLDC является базовой платформой для построения API MIDP. Классы CLDC состоят из стандартного набора функций, который будут поддерживать все производители телефонов, сертифицируемых по J2ME. Разработчику приложений не часто приходится работать с этими классами непосредственно, но для реализации определенных функций на отдельных устройствах придется работать с этими классами низкого уровня. При развитии устройств и платформ доступ к классам низкого уровня, вероятнее всего, будет запрещен.

Введение в профиль MIDP

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

Профиль содержит набор API, который позволяет создавать все, что угодна от видео-игр, использующих встроенную графику до полноценных приложений, работающих с внутренними и внешними источниками данных.

Некоторые производители устройств уже объявили, что их устройства будут поддерживать платформу MIDP. Во время создания этой статьи, фирма Nextel анонсировала поддержку MIDP в их устройствах в первом квартале 2001 года.

Короткий пример

Ниже приводится простой пример печати HelloWorld, который дает общее представление о цикле разработки мидлетов. Имя мидлет было дано кодам, которые выполняются на мобильных устройствах. Оно сродни апплету в том, что содержит интерфейс пользователя, данные, и возможности управления.


import javax.microedition.midlet.*; 
import javax.microedition.lcdui.*; 

public class HelloMidlet extends MIDlet 
            implements CommandListener 
{ 
 // инициализировать переменную Display мидлета
 private Display midletDisplay; 

 // инициализировать переменную для doneCommand
 private Command doneCommand; 

 public HelloMidlet() 
 { 
  // получить дисплей от статического объекта
  midletDisplay = Display.getDisplay(this); 

  // инициализировать переменную doneCommand
  doneCommand = new Command("DONE", Command.SCREEN, 1); 
 } 

 /** 
 * создать элемент TextBox с текстом 
 * Hello Midlet World 
 * и связать его с командой выхода и 
 * обработчиком событий. 
 */
 public void startApp() 
 { 
  // TextBox с текстом "Hello Midlet World!!"
  TextBox textBox = new TextBox("Hello Midlet", 
              "Hello Midlet World!!", 256, 0); 

  // добавить команду в TextBox
  textBox.addCommand(doneCommand); 

  // установить обработчик команд в 
  // текстовый элемент мидлета
  textBox.setCommandListener( (CommandListener) this); 

  // установить отображение текста на экране мидлета
  midletDisplay.setCurrent(textBox); 
 } 

 /** 
  * PauseApp - остановка фоновых задач и 
  * освобождение ресурсов устройства, 
  * когда мидлет не активен. 
  */
 public void pauseApp() 
 { 
 } 

 /** 
  * DestroyApp - остановка фоновых задач и 
  * освобождение ресурсов устройства, 
  * когда мидлет завершает работу 
  */
 public void destroyApp(boolean unconditional) 
 { 
 } 

 /* 
  * метод commandAction реализует интерфейс 
  * CommandListener для обработки действия 
  * над элементом. 
  */
 public void commandAction(Command command,
                        Displayable screen) 
 { 
  // если команда doneCommand
  if (command == doneCommand) 
  { 
   // вызов метода destroyApp
   destroyApp(false); 

   // сообщить платформу мидлета 
   //о завершении работы мидлета
   notifyDestroyed(); 
  } 
 } 
} 

На рисунке 1 представлена копия экрана эмулятора DefaultGrayPhone из набора J2ME Windows, на котором изображен результат работы мидлета.


Рисунок 1. результат работы мидлета HelloMidlet

Для поддержки класса MIDlet импортируются специальные классы, интерфейс CommandAction, и классы графического интерфейса (UI) пользователя. Эти классы имеются в составе API MIDP в составе модифицированного набора классов языка программирования Java. Ниже в этой статье мы обсудим более детально классы из состава API MIDP.


public class HelloMidlet extends MIDlet 
             implements CommandListener 

Эта строка объявляет, что класс HelloMidlet расширяет класс MIDlet и реализует интерфейс CommandListener. Каждый мидлет должен расширять абстрактный класс MIDlet, и реализовывать в нем три метода, описанные ниже, которые позволяют завершить разработку мидлета.

имя метода назначение метода
startApp Размещение требуемых системных ресурсов и инициализация приложения.
pauseApp Временная остановка проуессов, интенсивно потребляющих ресурсы.
destroyApp Освобождение ресурсов, использованных мидлетом и удаление мидлета из памяти.

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

Перед выполнением метода startApp выполняется код конструктора. В нашем примере конструктор получает дисплей из глобального объекта Display. Кроме того, конструктор инициализирует doneCommand.

Метод startApp создает экран для изображения в мидлете. Инициализация экрана TextBox выполняется следующим образом.


TextBox textBox = new TextBox("Hello Midlet", 
             "Hello Midlet World!!", 256, 0); 

Мидлет Screen может также содержать Commands. Команда - механизм создания меню в мидлете, как показано выше на картинке с кнопкой "Done". Код добавления кнопки "Done" к экрану TextBox показан ниже:


  // добавить команду done к TextBox
  textBox.addCommand(doneCommand); 

Исходный текст Command генерирует CommandActions при нажатии на него. В этом примере, HelloMidlet реализует интерфейс CommandListener и тем самым обрабатывает все события сам. При усложнении разрабатываемой системы может быть полезной реализация расширенной обработки событий.


  // установить обработчик команд 
  // в текстовом поле мидлета
  textBox.setCommandListener( (CommandListener) this); 

Теперь TextBox можно отображать на экране устройства. Следующая строка устанавливает в текущем дисплее отображение TextBox:


 midletDisplay.setCurrent(textBox); 

В этом простом примера мидлет HelloWorld использует всего лишь несколько из классов платформы MIDP. В следующей части, мы изучим полный набор API MIDP.

Обзор API MIDP/CLDC

В силу ограниченности ресурсов устройств, в которых должны выполняться коды библиотек MIDP/CLDC, большинство стандартных функций Java в них изменены или отсутствуют вовсе API MIDP/CLDC содежит следующие библиотеки классов:

  • java.lang.*
  • java.io.*
  • java.util.*
  • javax.microedition.io.*
  • javax.microedition.ui.*
  • javax.microedition.rms.*
  • javax.microedition.midlet.*

Библиотека java.lang

В состав пакета вошли ряд стандартных функций, содержащихся в библиотеке java.lang J2SE. Одним из примечательных исключений является класс Float. MIDP не поддерживает вычисления с плавающей запятой. Ниже приводится полный список классов:

  • Object
  • Class
  • Runtime
  • System
  • Thread
  • Runnable
  • Throwable
  • Math
  • String
  • Boolean
  • Short
  • Long
  • Byte
  • Character
  • Integer
  • StringBuffer

Библиотека java.io

Библиотека java.io содержит методы, необходимые для получения информации от удаленных систем. В API CLDC вошли следующие классы:

  • InputStream
  • OutputStream
  • Reader
  • Writer
  • DataInput
  • DataOutput
  • DataInputStream
  • DataOutputStream
  • ByteArrayInputStream
  • ByteArrayOutputStream
  • InputStreamReader
  • OutputStreamReader
  • PrintStream

Библиотека java.util

Библиотека java.util содержит небольшой набор функций исходной библиотеки util. Остались следующие классы:

  • Calendar
  • Date
  • TimeZone
  • Enumeration
  • Vector
  • Stack
  • Hashtable
  • Random

Библиотека javax.microedition.io

В библиотеке javax.microedition.io основным объектом является класс Connector. Используя интерфейс соединений, этот класс можно преобразовывать в различные типы соединаний, которые описаны ниже.

Интерфейс соединения Цель соединения
StreamConnection Открыть простейшее соединение, которое просто читает и записывает данные.
ContentConnection Открыть соединение, которое сообщает длину, тип, и информацию о кодировке. Этот интерфейс расширяет интерфейс StreamConnection.
HttpConnection Открыть соединение с возможностями связи через HTTP с использованием заголовков и специфических команд HTTP. Этот интерфейс расширяет ContentConnection.

Метод Connector open() имеет следующие основные формы:


Connector.open(":;");

Библиотека javax.microedition.ui

Библиотека javax.microedition.ui содержит классы, которые можно использовать при разработке пользовательского интерфейса мидлета. API ориентировано на создание одного из двух типов дизайна.

Класс Canvas, использование которого будет рассмотрено в следующем примере, используется для разработки пользовательского интерфейса на базе объекта Graphics. Использование Canvas позволяет разрабатывать многопоточные видеоигры или нетрадиционные интерфейсы.

Объект Screen и его подклассы, которые мы рассмотрим позже в примере HelloMidlet, используются для создания интерфейсов в виде форм. Во второй части мы рассмотрим возможности этих интерфейсов, кроме того их можно изучить посредством документации Javadoc.

Библиотека javax.microedition.rms

Библиотека javax.microedition.rms содержит классы, необходимые для реализации временных хранилищ данных в устройстве. Такого рода базы данных имеют ограниченные возможности по хранению и выборке данных из-за ограничений размеров устройств.

API баз данных будет рассмотрено во второй части этой серии.

Библиотека javax.microedition.midlet

Библиотека javax.microedition.midlet содержит класс MIDlet. Класс MIDlet выполняет главный цикл мидлета и имеет метод getAppProperty(key) для доступа к информации о свойствах программы, установленных в файле jad.

Приступаем

Усвоив урок предыдущего примера, и разобравшись с составом платформы MIDP, перейдем к рассмотрению процесса инсталляции среды MIDP. Мы дополнительно исследуем процесс построения и запуска классов мидлета.

Инсталляция

Sun предоставила новый пакет инструментов, служаший делу упрощения разработки мидлетов. 2 микроредакция беспроводного инструментария Java (см. J2MEWTK) имеет все необходимое для разработки мидлетов.

В настоящее время можно назвать два ограничения для инсталляции пакета. Во-первых, он может работать только под Windows. Возможно, скоро Sun объявит о выпуске версий для Solaris и Linux. Во-вторых, имя инсталляционной директории не должно содержать пробелов, чего требует внутренний процесс компиляции.

После загрузки тулкита, надо просто щелкнуть по нему мышью пару раз и он начнет работать. Перед началом инсталляция запрашивается путь для размещения программных файлов. J2MEWTK может интегрироваться со средой разработки Forte, которая также поставляется Sun. Для инсталляции расщирений Forte в тулките надо выбрать при установке пользовательскую конфигурацию, а не типовую.

В указанной директории создаётся следующая структура. Заметим, что, как и говорилось ранее, если имя директории содержит пробелы, то процесс предварительной проверки не будет выполнен правильно.

Директория Назначение
{путь инсталляции}/apps содержит файлы, относящиеся к отдельным проектам. Все исходники, ресурсы, конфигурации. Кроме того, здесь содержатся результаты компилции.
{путь инсталляции}/bin содержит исполняемые файлы для проверки и компиляции приложений для среды мидлетов.
{путь инсталляции}/lib/midpapi.zip содержит классы API CLDC и MIDP.
{путь инсталляции}/docs содержит документацию по API и руководство пользователя MIDP (pdf) file.

Запуск KToolbar

KToolbar запускается как из командной строки, так и из меню Start, где при инсталляции создается шорткат. Запускалка называется Ktoolbar.bat.

На экране должно появиться нечто похожее на изображение на рисунке 2.


Рис. 2. KToolbar беспроводного тулкита J2ME

Создание проекта

После запуска программы можно создать файл проекта HelloMidlet, который обсуждался ранее. Для этого надо нажать кнопку "New Project..." на рис. 2. Появится показанный на рис. 3 диалог.


Рис. 3. Диалог нового проекта.

В этом диалоговом окне запрашивается имя проекта и имя класса, который будет главным для мидлета, и который, соответственно, попадет сразу в проект. Проект может содержать много мидлетов, поэтому можно будет изменить имя мидлета в случае необходимости.

В нашем примере мы вводим HelloMidlet в качестве имени проекта, а также в поле класса. После ввода информации нажимаем кнопку "Create Project", в результате появится окно ввода установок для проекта, как показано на рис. 4.


Рис. 4. Установки проекта HelloMidlet.

Установки на рис. 4 являются заданными по умолчанию. Значение MIDlet-Jar-URL составляется по имени проекта. Изменять появившиеся значения не обязательно.


Рис. 5. Необязательные аттрибуты проекта HelloMidlet

На рис. 5 показаны экраны KToolbar, на которых можно задать аттрибута проекта. Мидлет может использовать эти аттрибуты в приложении. Поэтому рекомендуется задавать константные значения здесь, а не прописывать их в коде.


Рис. 6. Мидлеты в проекте HelloMidlet

На рис. 6 показан список всех мидлетов, которые вошли в состав проекта HelloMidlet. Тулкит J2ME для Windows позволяет также изменять порядок запуска мидлетов на эмуляторе из файла jar. В нашем случае мидлет всего один - MIDlet-1.

Компиляция мидлета

J2MEWTK имеет встроенную утилиту, которая выполняет процесс компиляции проекта. Для компиляции надо нажать кнопку "Build", которая видна на рис. 2. В этом тулките процесс компиляции автоматизирован, но в других так может не случиться. Поэтому опишем процесс по шагам:

  1. для работы компиляции создаются директории classes and tmpclasses
  2. результаты компилияции исходных кодов Java помещаются в директорию tmpclasses
  3. файлы классов проходят предварительную проверку и переписываются в директорию classes
  4. проверенные файлы складываются в jar
  5. в jar добавляются файлы ресурсов
  6. генерируется напоминание обновить размеры файлов jar и jad

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

Файл jad

Файл jad содержит полную информацию о мидлете, именах и значениях его свойств. Файл jad для класса HelloMidlet из нашего примера выглядит следующим образом:

MIDlet-1: HelloMidlet, HelloMidlet.png, HelloMidlet 
MIDlet-Jar-Size: 1387 
MIDlet-Jar-URL: HelloMidlet.jar 
MIDlet-Name: HelloMidlet 
MIDlet-Vendor: Sun Microsystems 
MIDlet-Version: 1.0 

Здесь среди прочих полей перечислены имя мидлета, URL, размер, версия. Наиболее интересна строка MIDlet-1. В данном файле jad сообщается всего об одном мидлете, поэтому такая строка одна. Если бы мы имели дело с n мидлетами, получилось бы n строк:

MIDlet-1: ... 
MIDlet-2: ... 
... 
MIDlet-n: ... 

Каждая строка содержит при этом имя мидлета, файл рисунка мидлета и имя класса мидлета.

Зачем нужна предварительная проверка?

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

KVM, работающая на памяти в 1 K, оптимизирована для процессов в таких устройствах, а не для элементарных операций, которые можно утстранить с помощью предварительных проверок.

Выполнение мидлета

Выполнением мидлета также можно управлять из J2MEWTK. На рис. 2 показан KToolbar с запрещенной кнопкой "Run". Эта кнопка доступна, когда загружен проект. Для запуска мидлета надо выбрать устройство, на котором можно его тестировать, из следующего списка:

  • DefaultColorPhone: цветная версия телефона
  • DefaultGrayPhone: простой телефон
  • MinimumPhone: простейший эмулятор
  • Pager: двунаправленный пейджер

После выбора устройства надо нажать кнопку Run и запустить эмулятор. Мидлет можно запустить из командной строки командой:

java -cp \lib\kvem.jar;\
        lib\kenv.zip;\lib\lime.jar 

-Dkvem.home= 
[-D=] 
com.sun.kvem.midp.Main  
-descriptor  

Командный синтакс описан в разделе 5.5.2.1 руководства пользователя дистрибутива Sun.

Пример графической среды

В следующем примере иллюстрируется работа простой графической среды, которая может помочь освоить разработку кодов графики в среде MIDP.

Простой пример с графикой содержит следующие классы:

  • GraphicalMidlet: класс мидлета, обеспечивающий взаимодействие с устройством
  • GraphicalCanvas: область рисования графических объектов
  • GraphicalObject: графический объект, реализующий интерфейс Runnable
  • MovingTextObject: двигающийся текстовый объект
  • VerticalScrollingTextObject: расширение текстового объекта

В примере класс GraphicalMidlet расширяет класс MIDlet и наследует его образ поведения. Этот класс также отвечает за реализацию интерфейса CommandAction для обработки команды Exit при завершении пользователем работы с приложением.

Конструктор класса GraphicalMidlet работает со статическим объектом Display. Конструктор создаёт экземпляр класса GraphicalCanvas, для которого он выполняет CommandListener.


public GraphicalMidlet() 
{ 
 display = Display.getDisplay(this); 
 canvas = new GraphicalCanvas(display); 
 canvas.addCommand(exitCommand); 
 canvas.setCommandListener(this); 
} 

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


public GraphicalCanvas(Display d) 
{ 
 display = d; // запомнить дисплей

 graphicalObject = 
 new VerticalScrollingTextObject (
         this, "Hello Midlet World!!"); 
 height = this.getHeight(); 
 width = this.getWidth(); 
} 

используется Приложение GraphicalCanvas использует метод paint для перерисовки экрана приложения. В данном случае, область рисования стирает все предыдущие рисунки и дает GraphicalObject нарисоваться самостоятельно.


protected void paint(Graphics g) 
{ 
 g.setColor(255,255,255); 
 g.fillRect(0,0,width,height); 
 graphicalObject.paint(g); 
} 

start() GraphicalMidlet вызывает метод start(), чтобы сообщить GraphicalCanvas о начале работы. В этом примере, класс canvas создает новый программный поток, содержащий Runnable GraphicalObject. Затем класс canvas запускает новый поток, так что он может выполнять обработку перед тем, как вызвать метод repaint и инициализировать рисунок в области рисования.

Можно также развить этот пример до создания более чем одного графического объекта. GraphicalObject на области рисования и запускать их одновременно.


void start() 
{ 
 display.setCurrent(this); 
 Thread t = new Thread(graphicalObject); 
 t.start(); 
 repaint(); 
} 

Класс GraphicalObject релизует интерфейс Runnable и может запускаться потоками класса GraphicalCanvas в методе start(). Thread будет работать, пока ее не завершит метод stopThread.


public void run() 
{ 
 stopThread = false; 
 while (!stopThread) 
 { 
  move(); 
  canvas.repaint(); 
  try
  { 
   Thread.sleep(100); 
  }
  catch(InterruptedException ie)
  { 
   stopThread = true;
  } 
 } 
} 

GraphicalObject не знает, когда ему рисовать или двигать создаваемые на его базе объекты, но он определяет два метода, которые следует переопределить. Это следующие методы:


 public abstract void move(); 
 public abstract void paint(Graphics g); 

Переопределяя эти методы, можно реализовать желаемое движение объекта MovingTextObject, а также способ его рисования. Таким образом, для реализации другого объекта, например, вращающейся шестерни, придется всего лишь изменить методы paint и move.


public void paint(Graphics graphics) 
{ 
 graphics.setColor(0,0,0); 
 graphics.drawString(stringValue, posX, 
      posY, Graphics.TOP| Graphics.LEFT); 
} 

public void move() 
{ 
 posX = getX(); 
 posY = getY(); 
} 

В методе move() вызываются методы getX() и getY() для получения позиций X и Y движущегося объекта. Это сделано для демонстрации возможных расширений среды. В данном случае расширение довольно простое, метод getX() возвращает постоянное значение, метод getY() увеличивает позицию по Y, пока не будет достигнута нижняя граница дисплея.

Создавая различные реализации MovingTextObject, можно реализовывать различные схемы движения. Например, класс RandomMovingTextObject может реализовать генератор случайных значений для позиций X и Y и возвращать их из методов getX и getY.

Далее в этой серии

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

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

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

Заключение

Реализация кода Java в беспроводных устройствах является следующим логичным шагом на пути развития платформы. Мидлеты имеют потенциал для революционного преобразования платформы, позволяя разработчикам предлагать мобильным пользователям все более функциональные простые в использовании решения. Мы объединили основные улучшения программисткого промысла, например, определение места расположения, а платформа оказалась подходяшей для мгновенной реализации.

Платформа MIDP будет представлена в устройствах с января 2001. Nextel будет с этого времени поддерживать Java-enabled телефоны Motorola.

Разработки в этой области очень приятны, поскольку позволяют разработчикам беспроводного мира освоить много нового благодаря API Java. Платформа дает концепции "Write Once, Run Anywhere" новое значение даже в рамках Java.

Об авторе

Michael Cymerman is the research and development director at GroupServe, a Washington, D.C.-based telecommunications firm that creates Internet applications to facilitate group communication.

Ресурсы

  • Other JavaWorld articles by Michael Cymerman:

    Reprinted with permission from the January 2001 edition of JavaWorld magazine. Copyright © ITworld.com, Inc., an IDG Communications company.
    View the original article at: http://www.javaworld.com/jw-01-2001/jw-0105-midp.html


  • Warning: mysql_connect() [function.mysql-connect]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/books/show2b.php on line 11

    Warning: mysql_db_query() [function.mysql-db-query]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/books/show2b.php on line 19

    Warning: mysql_db_query() [function.mysql-db-query]: A link to the server could not be established in /pub/home/javaport/javaportal/books/show2b.php on line 19

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /pub/home/javaport/javaportal/books/show2b.php on line 30
    Узнай о чем ты на самом деле сейчас думаешь тут.


    [an error occurred while processing this directive]



    Warning: mysql_connect() [function.mysql-connect]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/news/worldnews.php on line 91

    Warning: mysql_db_query() [function.mysql-db-query]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) in /pub/home/javaport/javaportal/news/worldnews.php on line 93

    Warning: mysql_db_query() [function.mysql-db-query]: A link to the server could not be established in /pub/home/javaport/javaportal/news/worldnews.php on line 93

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /pub/home/javaport/javaportal/news/worldnews.php on line 95