Модераторы: javastic, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Програмирование для J2ME 
:(
    Опции темы
LSD
Дата 2.11.2004, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15709
Регистрация: 24.3.2004

Репутация: 1
Всего: 537



Огромное спасибо g-r-i-n за этот цикл статей

Вопрос: Я умею программировать на Java, и хотел бы создавать приложения на J2ME. Что для этого нужно иметь и знать?

Ответ:


Как ни странно, создавать приложения для J2ME даже легче, чем обычные Java-приложения или апплеты. Связано это с тем, что библиотека J2ME сильно урезана и вполне умещается целиком в одну голову. Другой плюс - не нужно прописывать переменные PATH и CLASSPATH, т.е. сразу после установки эмулятора можно без перезагрузки начинать работать. Естественно есть в этом смысле и минусы: чтобы установить эмулятор, нужно прежде установить Java 2 Platform, Standard Edition, на текущий момент последняя версия - v 1.4.2. Все эти продукты БЕСПЛАТНЫ. Таким образом, чтобы установить весь необходимый софт нужно выполнить следующее (пп 1-2 для тех, у кого еще не установлена Java 2 Platform):
1. Скачать Java 2 Platform, Standard Edition
http://java.sun.com/javase/downloads/index.html
(там же можно отдельно скачать и документацию)
2. Запустить установку JSE и выбрать произвольный каталог для размещения файлов - его название и положение никак не сказывается на дальнейшей работе с ним (например D:/Java)
3. Скачать тулкит J2ME Wireless Toolkit 1.0.4_01 со страницы
http://java.sun.com/products/j2mewtoolkit/...t/download.html
(документация поставляется вместе с ним и доступна по маршруту МЕ_каталог/docs/api/index.html)
4. Запустить установку J2ME, согласиться с выбором найденной Java-машины (в нашем случае D:/Java), а затем указать каталог для размещения тулкита. ОБЯЗАТЕЛЬНОЕ УСЛОВИЕ: название всех папок в выбранном каталоге не должно содержать пробелов, иначе Sun не гарантирует адекватность работы приложений.

Чобы начать работать нужно сделать следующее:
5. Запустить kToolbar из меню Пуск или из папки МЕ_каталого/bin/kToolbar.bat
6. Создать новый проект (Create Project) - указать имя проекта и имя исполняемого файла. Автоматически создастся папка Ваш_проект в каталоге МЕ_каталог/apps
7. Ваши приложения должны будут располагаться в папке МЕ_каталог/apps/имя_Вашего_проекта/src Если у Вас есть правильно написанный файл имя_Вашего_класса.java, то поместите его в эту папку.
8. По нажатии кнопки Build в kToolbar будут созданны необходимые файлы *.class в папке classes и файл имя_Вашего_проекта.jad в папке bin.
9. По исполнении команды Project - Package - Create Package будет создан файл имя_Вашего_проекта.jar в папке bin.

На этом и заканчивается создание исполняемого оффлайнового приложения. Теперь пользователю Вашего приложения достаточно установить на свой Java-телефон эти два файла (имя_Вашего_поекта.jar и имя_Вашего_поекта.jad) - по шнуру, радио- или интернет связи и наслаждаться качественно сделанной работой.
Сами вы можете проверить действие вашего мидлета (а именно так называются приложения написанные на J2ME) нажав кнопку Run. Для выбора цветного телефона перед этим нужно выбрать DefaultColorPhone в строке Device. Все системные сообщения выводятся в окне kToolbar.
Остается добавить, что для тестирования программы под конкретный телефон, лучше пользоваться эмулятором производителя. Для Нокиа существует бесплатный эмулятор, который каждый (тоже бесплатно) зарегистрированный на сайте forum.nokia.com может себе скачать.

Полезные ссылки:
Java 2 Platform, Standard Edition
Java 2, Micro Edition (J2ME) Wireless Toolkit 2.2 Release

 Вопрос: Что может мидлет? Как это можно использовать?

Ответ:


Возможности мидлета по сравнению с апплетом весьма ограничены. Тем не менее он позволяет:
1. орабатывать высокоуровневые (напр. выбор значения в списке) и низкоуровневые (напр. нажатие на конкретную клавишу) события;
2. запускать таймер, который может выполнять нужный код каждые N миллисекунд начиная с M-й;
3. запускать несколько потоков одновременно;
4. рисовать в 2D графике, работать с готовыми картинками в формате png (и не только)
5. записывать данные в долговременную память (но не в файлы - из файлов можно только считывать информацию, т.е. они статичны)
6. взаимодействовать с интернет-ресурсами.

 Эти возможности, на мой взгляд, являются достаточными для создания приложений любой сложности (т.к. если приложение чего-то не может само, оно может послать информацию на обработку по нужному интернет-адресу и получить нужные результаты).
 Следующий мидлет реализует телефонный вариант известной игры "Пятнашки". Он содержит весь минимум классов, который необходим любому оффлайновому приложению. (прошу извинения за неоченьудобочитаемость, но во-первых я старался сократить его вертикальные размеры, а для этого пришлось давать переменным одобуквенные имена и иногда писать несколько команд в одной строке, а во-вторых отступы почему-то не сохраняются):

Код
import javax.microedition.lcdui.*;    
import javax.microedition.midlet.*;   
import java.util.*;   

public class Dve extends MIDlet   
{
  private Display display; 
  private Canvas canvas;    
  private Command ok, empty;    
  private Form form;    
  private TextField f1, f2; 
  private String m, showMode, show; // в m хранится текущее состояние поля 
  private int e, count; // е - координата "пустой" костяшки    
  private int [] n = {11,0,0,0,0,0,0,9,0,0,0,0,0,10,0,1,2,3,4,5,6,7,8};    
  private java.util.Timer tr;  
  private Random r = new Random ();    

  public Dve()
  {
    canvas = new MyCanvas();
    canvas.setCommandListener( (CommandListener) canvas);
    form = new Form("Двенашки");   
    form.setCommandListener( (CommandListener) canvas); 
    f1 = new TextField("Слово (11 букв)", "тирдарпупия", 11, 0);   
    f2 = new TextField("Сложность", "3", 1, 0);    
    form.append(f1);   
    form.append(f2);   
    ok = new Command("Ok", Command.SCREEN, 2); 
    empty = new Command("", Command.SCREEN, 1);    
    form.addCommand(ok);   
    canvas.addCommand(empty);  
    display = Display.getDisplay(this);    
    display.setCurrent(form);  
    showMode = "Display";   
  }

  private class Tsk extends TimerTask  
  {
    public Tsk()
    {
    }

    public void run()
    {
      tr.cancel ();
      showMode = "Display";
      display.setCurrent (form);
    }
  }

  private class MyCanvas extends Canvas implements CommandListener 
  {   
    public void commandAction(Command c, Displayable d) 
    {
      boolean b = true;

      if(showMode.equals("Display") && c.equals(ok) && b)
      {
        m = (f1.getString () + "           ").substring (0, 11) + " ";    
        showMode = "Canvas";
        count = 0;
        e = 11;
        show = "";
        canvas.addCommand (ok);
        display.setCurrent(canvas); 
        for(int i = 0; i < (Integer.parseInt(f2.getString ()) + 1) * 100; i++)
          touch(Math.abs (r.nextInt ())%12);
        b = false;
      }

      if(showMode.equals("Canvas")  && c.equals(ok) && b)  
      {
        show = "Слабо!?";
        canvas.removeCommand(ok);
        repaint();
        tr = new java.util.Timer();
        tr.scheduleAtFixedRate(new Tsk(), 1000, 1);
      }

      repaint(); 
    }

    protected void keyPressed(int code) 
    {
      boolean b = true;   

      if((code >= 35) && (code <= 57) && b)
      {
        touch (n[code - 35]);   
        count++;
        b = false;
      }

      if(showMode.equals("Canvas") && (canvas.getGameAction(code) == Canvas.FIRE) && b)
      {
        show = "Слабо!?";
        canvas.removeCommand(ok);
        repaint();
        tr = new java.util.Timer();    
        tr.scheduleAtFixedRate(new Tsk(), 1000, 1);}  
      
      if(m.equals(f1.getString() + " "))
      {
        show = "Победа!!!";
        canvas.removeCommand(ok);
        repaint();  
        tr = new java.util.Timer();    
        tr.scheduleAtFixedRate(new Tsk(), 2000, 1);
      }

      repaint(); 
    }   

    public void paint(Graphics g)   
    {
      g.setFont(Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE));
      g.setColor(0, 0, 0); 
      g.fillRect(0, 0, canvas.getWidth (), canvas.getHeight ()); 
      for(int i = 0; i < 12; i++)
      {
        g.setColor(0,0,150);
        g.drawRect(5 + (i % 3) * 20, 5 + (i / 3) * 20, 19, 19);
        g.setColor(0, 150, 0);   
        g.drawString("  " + m.substring(i, i + 1), 5 + (i % 3) * 20, 5 + (i / 3) * 20, 0);
      } 
      g.drawString(String.valueOf(count), 70, 5, 0);    
      g.drawString(show, 5, 83, 0);  
    }
  }

  public void startApp()
  {
  }

  public void destroyApp(boolean b)
  {
  }

  public void pauseApp()
  {
  }

  private void touch(int n)
  {
    if((n != e) && (n / 3 == e / 3))
    {
      for(int i = Math.abs(n % 3 - e % 3) / (n % 3 - e % 3); Math.abs(i) <= Math.abs(n % 3 - e % 3); i += Math.abs(n % 3 - e % 3) / (n % 3 - e % 3))
        m = m.substring(0, e + i - Math.abs(i) / i) + m.substring(e + i, e + i + 1) + m.substring(e + i - Math.abs(i) / i + 1);

      e = n;
      m = m.substring(0, n) + " " + m.substring(n+1, m.length());
    }

    if((n != e) && (n % 3 == e % 3))
    {
      for(int i = Math.abs(n / 3 - e / 3) / (n / 3 - e / 3); Math.abs(i) <= Math.abs(n / 3 - e / 3); i += Math.abs(n / 3 - e / 3) / (n / 3 - e / 3))
        m = m.substring(0, e + (i - Math.abs(i) / i) * 3) + m.substring(e + i * 3, e + i * 3 + 1) + m.substring(e + (i - Math.abs(i) / i) * 3 + 1);
     e = n;
     m = m.substring(0, n) + " " + m.substring(n + 1, m.length());
    }
  }
}

 При запуске приложения появляется окно с предложением ввести слово, буквы которого изображаются вместо цифр, и сложность - в насколько перемешанном состоянии будут находиться костяшки. По нажатии на кнопку под надписью "Ок" запускается сама игра. Перемещать можно одну или несколько костяшек нажатием на соответствующую клавишу (0-9, * или #). Справа на экране изображается количество шагов.  Если игрок сдается, он может нажать либо кнопку Enter (Fire), либо кнопку под надписью "Ок" и снова попасть в стартовое окно. Когда костяшки приведены в исходное положение, появляется уведомление о победе и через две секунды автоматически открывается стартовое окно, в котором снова можно выбрать слово и сложность.
 Код может показаться сложным, но на самом деле он очень прост, достаточно только разложить его на уровни.
 Итак, первый уровень - методы программы. С 18-й по 35-ю строку реализуется конструктор класса Dve. С 37-й по 49-ю - метод, переводящий программу в режим стартового окна в момент срабатывания "будильника". С 51-й строки строится внутренний класс, отвечающий за прорисовку графики и реакцию на нажатия клавиш. В строках 53-81 обрабатываются высокоуровневые события (в данном приложении выполнение команды "Ок"), в строках 83-112 - низкоуровневые (нажатия на клавиши). 114-128 - собственно прорисовка игры. 131-141 методы не обязательные для реализации с точки зрения программиста, но обязательные с точки зрения компилятора - класс Canvas абстрактный и требует их реализации. 143-161 метод, вникать в который совершенно не обязательно, в его реализации нет ничего специфичного для Java и функция у него одна - "передвинуть" костяшки.
 Второй уровень - классы MIDP 1.0 с помощью которых и реализованы методы. Первый класс, который почти всегда используется в приложениях - javax.microedition.lcdui.Screen, абстрактный, который в данном примере реализует другой встроенный класс - javax.microedition.lcdui.Form. Эти классы (есть еще несколько классов, реализующих Screen) предоставляют один из двух способов работы с экраном - в текстовом режиме. Максимум графики, которая возможна при их использовании - изображение иконки рядом с надписью. В класс Form, например, можно добавлять (метод append ()) надписи, техтовые поля, радиокнопки и обрабатывать соответствующие события, с ними связанные.
 Некая альтернатива семейству "текстовых" классов - javax.microedition.lcdui.Canvas - второй из двух способов работы с экраном: с его помощью можно реализовать в графическом режим все то же самое и даже красивее, только события по навигации по экрану нужно будет обрабатывать вручную.
 Работа остальных классов, по-моему, интуитивно понятна в контексте этой программы.
 Третий уровень - методы стандартных классов. Не знаю, стоит ли вдаваться в подробности работы этих и остальных классов и методов, этому можно посвятить метры описаний, вопрос только нужно ли. В сети существует достаточно руководств по полноценному их использованию, я же попытался привести наглядный и несложный пример, использующий весь необходимый минимум, и который, я надеюсь, рассказывает сам за себя.

 Что может и чего не может мидлет?

Ответ:

 Следующий топик полностью списан с указанного в конце адреса. Автором является Mank.

Что может и чего не может мидлет  
Автор: Mank
 Дата публикации: 01.09.2003 09:58
 

J2ME 
  

Многие люди имеющие опыт программирования, когда сталкиваются с технологией J2ME, попадают впросак, в связи с тем, что хоть мидлет и является небольшой программкой в телефоне, но оказывается, что он многого не может сделать принципиально. Здесь перечислены основные моменты того, что не может делать стандартный мидлет. (В данной статье рассматривается MIDP 1.0)  

Итак по-порядку. 

Нет поддержки чисел с плавающей точкой (floating point). Это связано с тем, что в устройствах с ограниченными ресурсами отсутствует поддержка floating point. Поддержка же на программном уровне была бы слишком дорогим удовольствием. В JVM которая поддерживает CLDC отсутствуют байткоды связанный с типами float и double. 

Что из этого следует. Придется вам работать только с целочисленными значениями. О float и double забудьте. 

java.lang.Math - элементарен до безобразия. Те, кто знаком с технологией Java, знают, что данный класс содержит методы, совершающие основные числовые операции, такие как экспонента, логарифм, тригонометрические операции. Так вот, в мидлете они не доступны. java.lang.Math имеет только 3 метода: 

abs (int a), 
max (int a, int b), 
min (int a, int b). 
Отсутствует метод finalize(). Это требование связано с необходимостью упрощения механизма сборки мусора. Для тех кто не знаком с Jav'ой, можно перефразировать иначе, нет никаких деструкторов. Хотя метод finalize() - это не деструктор или это не удавшийся деструкторsmile). Кто не согласен с этим, читайте здесь. Для тех, кто знаком с Jav'ой, можно добавить, что нет weak references. Так же Object - не имеет метода clone. И, слава богу. 

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

Отсутсвует Java Native Interface (JNI). Поддержка JNI была отклонена по двум причинам. Первая, ограничения, накладываемые security моделью. (Данная модель запрещает использовать native вызовы.) Вторая, полная реализация JNI была признана слишком дорогой для устройств с ограниченными ресурсами. Таким образом, вам доступна только Java и ничего больше. Даже если у вас и телефон с Symbian, запустив на нем мидлет, о возможностях Symbian не вспоминайте. (Это касается конечно, если производитель телефонов, не выходит за рамки MIDP 1.0.) 

Нельзя создать свой ClassLoader. Это ограничение накладываемое security моделью. Так, что нельзя управлять динамической загрузкой классов. 

Нет Reflection механизма. Java приложения не могут инспектировать классы, объекты, методы, поля, нитки, выполняемые стэки в виртуальной машине. Как следствие сериализация отсутствуют. 

Есть многопоточность, но нет ThreadGroup и демонов. Операции, такие как запуск и остановка нитки, могут быть применены только над отдельной ниткой. Thread к тому же "безыимянен", и к счастью не имеет методов stop, resume, suspend (которые были deprecated в J2SE). Также нет методов enumerate и interrupt. 

Class - важные методы, которые у него есть это: forName(), getName(), getResourceAsStream(), newInstance(). Так, что создать экземпляр класса, при помощи методов forName() и newInstance() можно. (Так, что можно сказать, что кусочек Reflection механизма все же есть, но не более.) А при помощи метода getResourceAsStream() можно найти ресурс. 

Throwable - отсутсвует метод getCause(). Нельзя выстроить цепочку исключений (exception chaining). Метод printStackTrace() позволяет печатать Throwable, только в стандартный поток ошибок. 

Boolean, Byte, Character, Integer, Long, Short - Классы-обертки для простых типов есть! 

String, StringBuffer - тоже есть!. Правда в урезанном варианте. 

System - присутсвуют методы arraycopy, currentTimeMillis, gc, getProperty, identityHashCode вот и все. О методе exit() забудьте. Жизненый цикл мидлета основан на трех методах класса MIDlet: startApp, pauseApp, destroyApp. 

Collection API - представлен следующими классами: Hashtable, Vector, Stack, Enumeration. 

java.util - представлен следующими классами: Random, Date, Timer, TimerTask, Calendar, TimeZone. 

java.io - 11 классов, но их хватает. 

Connection MIDP 1.0 обязывает производителей опираться только на http. (MIDP 2.0 еще и https) Но не обольщайтесь. Если есть http, это не значит, что есть сокеты. http может быть реализован как на TCP/IP, так и на wap или i-mode. Все остальное (Bluetouth, comm, socket, datagramm и т.д.) может быть, а может и не быть, это опционально (зависит от производителя). 

Оконный интерфейс отсутсвует. Нет никаких объектов Window, Dialog, Frame. Центральным звеном пользовательского интерфейса MIDP является объект Displayable. Каждый мидлет имеет Display, на котором одновременно может показываться только один Displayable объект. Displayable объект, является функциональной единицей, которая инкапсулирует специфичный для устройства графический интерфейс и взаимодействие с пользователем. Display отвечает за то, какой Displayable объект должен показываться на экране. Существует только один Display экземпляр для одного мидлета. Метод Display.getDisplay() возвращает объект Display для мидлета. Главным методом этого класса являеться метод setCurrent (Displayable next), который позволяет менять различные объекты на экране. 
К Displayable можно добавить комманду и установить 'слушателя' для комманды. 

Существует пять классов, которые расширяют Displayable: 

List позволяет выбрать пользователю елементы из списка. Каждый элемент в списке представляется строчкой и может иметь Image. 
TextBox позволяет пользователю вводить и редактировать текст. 
Alert можно сравнить с диалоговым окном, оповещающим о какой-то произошедшей ситуации. 
Form может содержать комбинацию элементов, которые могут представлять строчки, изображения, поля ввода, списки. 
Canvas позволяет приложению самому обеспечивать отрисовку, переопределив метод paint (Graphics g) 
Graphics - позволяет нарисовать изображение, строчку, элипс, прямоугольник, линию. Вот почти и все. 

Font - Можно получить только тот шрифт который предоставит телефон. Для этого есть статический метод Font.getFont (int face, int style, int size). Все многообразие шрифтов, предоставляемое мидлету, заключено в параметрах этого метода. (А метод setFont (Font f), есть только у Graphics, а Graphics только у Canvas.) 

RMS API позволяет сохранять небольшие небольшие порции данных в постоянное место хранения. Эти данные хранятся до тех пор, пока не будет удален мидлет. Но другим мидлетам, данная информация не будет доступна. (MIDP 2.0 позволяет другому мидлету, иметь доступ к этим данным, при условии, если тот, имеет необходимые привелегии.) Но не пытайтесь думать, что это какие-то файлы. Понятие File для MIDP не существует. 

Подсветка экрана и вибратор, звук. В MIDP 1.0 отсутсвуют, появились только в MIDP 2.0. 

Теперь, зная все это, хорошенько подумайте, а нужен ли вам телефон с Jav'ой, и нужно ли вам лезть в J2ME? smile)) 
(Надеюсь, ваш ответ все равно будет положительным.) 

P.S. 
Вы можете сказать, почему же, несмотря на то, что многих возможностей в MIDP 1.0 нет, многие телефоны обладают такими возможностями. Это касается, например подсветки экрана, вибратора, звука, файлов (на Siemens). А это потому, что производители добавляют свой API, реализуюший данные возможности. В связи с этим, мидлет сделанный для одного телефона, может не работать на другом. Здесь видна проблема того, что стандартизация отстает от рынка. С выходом MIDP 2.0 многое сгладится. 

Адрес оригинала: http://www.midlet.ru


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса

  • Прежде чем задать вопрос прочтите это!
  • Литература по Java находится здесь.
  • Литературу по Java обсуждаем здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда

  • FAQ раздела лежит здесь!
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java ME (J2ME) | Следующая тема »


 




[ Время генерации скрипта: 0.1153 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.