Java ME
Transkrypt
Java ME
Java ME 1. Wprowadzenie. 2. Prerekwizyty. 3. Pisanie midletów ● cykl życia, ● kompilacja, dystrybucja i uruchomienie. 4. Tworzenie interfejsów użytkownika. 5. Grafika 2D. 6. Korzystanie z sieci. 7. Narzędzia programistyczne. 1 Java ME Java ME jest zbiorem technologii oraz specyfikacji, które są implementowane przez środowiska JRE dostępne na urządzeniach przenośnych. Najważniejsze technologie wchodzące w skład JME dla telefonów komórkowych to: ● CLDC (Connected Limited Device Configuration) – specyfikacja JSR- 30 (wersja 1.0) i JSR-139 (wersja 1.1) ● MIDP (Mobile Information Device Profile) – specyfikacja JSR-37 (wersja 1.0) i JSR-118 (wersja 2.0) Ponadto istnieje wiele dodatkowych technologii implementowanych przez poszczególne urządzenia, np. JSR-82 – Bluetooth, JSR-184 – Java 3D, JSR-135 – Mobile Media, ... 2 Prerekwizyty Aby pisać midlety należy zainstalować: ● JDK 1.2 lub nowszy, ● CLDC: http://www.sun.com/software/communitysource/j2me/ cldc/download.html ● MIDP http://java.sun.com/products/midp/index.jsp 3 Pierwszy midlet import import import import javax.microedition.lcdui.Display; javax.microedition.lcdui.Form; javax.microedition.midlet.MIDlet; javax.microedition.midlet.MIDletStateChangeException; public class HelloMidlet extends MIDlet { private Form form; public HelloMidlet() { this.form = new Form("HelloMidlet"); } protected void destroyApp(boolean b) throws MIDletStateChangeException { } protected void pauseApp() { } } protected void startApp() throws MIDletStateChangeException { Display d = Display.getDisplay(this); d.setCurrent(this.form); } 4 Midlet – cykl życia źródło: http://www.developer.com/java/j2me/article.php/10934_1561591_1 5 Kompilacja Do kompilacji midletu należy użyć polecenia javac: javac -d .\ -bootclasspath c:\pathTo\MIDP\classes HelloMidlet.java Po kompilacji należy wykonać tzw. preweryfikację, która przystosowuje klasę do uruchomienia przez KVM: preverify -classpath c:\pathTo\MIDP\classes; HelloMidlet Wynikowa klasa znajdzie się w podkatalogu output. Na zakończenie należy przygotować archiwum jar oraz deskryptor jad. 6 Dystrybucja oprogramowania Program JME składa się zwykle z dwóch plików: archiwum jar i deskryptora jad. Plik jad zawiera opis programu wraz z lokalizacją archiwum, które zawiera midlety. MIDlet-Jar-URL: mehello.jar MIDlet-1: HelloMidlet,,HelloMidlet MIDlet-Name: pierwszy zbior midletow MIDlet-Vendor: Jan Piotrowski MIDlet-Version: 0.0.1 MicroEdition-Configuration: CLDC-1.0 MicroEdition-Profile: MIDP-1.0 7 Dystrybucja oprogramowania W przypadku, gdy posiadamy lokalnie archiwum z programem plik jad nie jest wymagany. W takiej sytuacji odpowiednie wpisy muszą być dołączone do pliku META-INF/MANIFEST-MF: Manifest-Version: 1.0 MIDlet-1: HelloMidlet,,HelloMidlet MIDlet-Name: pierwszy zbior midletow MIDlet-Vendor: Jan Piotrowski MIDlet-Version: 0.0.1 MicroEdition-Configuration: CLDC-1.0 MicroEdition-Profile: MIDP-1.0 Testowanie programu: midp -descriptor hello.jad 8 Uruchomienie programu Program instalujemy w telefonie zgodnie z instrukcją obsługi. Po uruchomieniu ukaże sie następujący ekran: 9 Obsługa menu Aby utworzyć menu trzeba stworzyć komendy javax.microedition.lcdui.Command. Komendy dodaje się do obiektu implementującego javax.microedition.lcdui.Displayable. Ponadto komponent zawierający komendy musi ustawić obiekt nasłuchujący javax.microedition.lcdui.CommandListener, który będzie zawierał kod wykonany przy wybraniu pozycji w menu (Command). 10 Obsługa menu public class CommandMidlet extends MIDlet implements CommandListener{ private Command exitCommand, infoCommand, anyCommand; private TextBox box; public CommandMidlet() { this.exitCommand = new Command("Exit", Command.SCREEN, 1); this.infoCommand = new Command("Info", Command.SCREEN, 2); this.anyCommand = new Command("Command", Command.SCREEN, 2); } protected void startApp() { this.box = new TextBox("Command Midlet", "Witamy w midlecie", 256, 0); this.box.addCommand(this.exitCommand); this.box.addCommand(this.infoCommand); this.box.addCommand(this.anyCommand); this.box.setCommandListener(this); Display.getDisplay(this).setCurrent(this.box); } 11 Obsługa menu protected void destroyApp(boolean arg0) { } protected void pauseApp() { } } public void commandAction(Command c, Displayable d) { if (c == this.infoCommand) { this.box.setString("wybrano info"); return; } if (c == this.anyCommand) { this.box.setString("wybrano command"); return; } if (c == this.exitCommand) { this.notifyDestroyed(); } } 12 Uruchomienie programu Sposób realizacji menu jest uzależniony od modelu telefonu. Zwykle dostępne są dwa lub trzy przyciski oraz kierunki umożliwiające wybór odpowiednich opcji. 13 Klasa Ticker protected void startApp() { this.box = new TextBox("Ticker Midlet", "Witamy w kolejnym midlecie", 256, 0); this.box.addCommand(this.exitCommand); this.box.addCommand(this.infoCommand); this.box.addCommand(this.anyCommand); this.box.setCommandListener(this); this.box.setTicker(new Ticker("Java ME jest OK")); Display.getDisplay(this).setCurrent(this.box); } Efekt: 14 Formularze protected void startApp() { this.form = new Form("Formularz"); this.form.append(new TextField("Imie", "", 16, TextField.ANY)); this.form.append(new TextField("Nazwisko", "", 16, TextField.ANY)); this.form.append(new TextField("Wiek", "", 3, TextField.NUMERIC)); this.form.append(new TextField("tel.", "", 10, TextField.PHONENUMBER this.form.addCommand(this.exitCommand); this.form.setCommandListener(this); Display.getDisplay(this).setCurrent(this.form); } Wynik: 15 Grafika 2D – klasa GameCanvas źródło: http://developers.sun.com/techtopics/mobility/midp/articles/game/ index.html public class SimpleCanvas extends GameCanvas implements Runnable{ private volatile boolean isRunning; private long delay; private int x, y; private int size; public SimpleCanvas() { super(true); x = getWidth() / 2; y = getHeight() / 2; size = 0; delay = 20; } public void start() { isRunning = true; Thread t = new Thread(this); t.start(); } 16 Grafika 2D – klasa GameCanvas public void stop() { isRunning = false; } public void run() { Graphics g = getGraphics(); while (isRunning == true) { tick(); input(); render(g); try { Thread.sleep(delay); } catch (InterruptedException ie) { stop(); } } } private void tick() { size = (size + 1) % 20; } 17 Grafika 2D – klasa GameCanvas private void input() { int keyStates = getKeyStates(); if ((keyStates & LEFT_PRESSED)!=0) x=Math.max(0, x-1); if ((keyStates & RIGHT_PRESSED)!= 0)x=Math.min(getWidth(),x+1); if ((keyStates & UP_PRESSED)!= 0) y=Math.max(0, y-1); if ((keyStates & DOWN_PRESSED)!= 0)y=Math.min(getHeight(), y+1); } private void render(Graphics g) { g.setColor(0xffffff); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(0x0000ff); g.drawLine(x, y, x - 10 + size, g.drawLine(x, y, x + 10, y - 10 g.drawLine(x, y, x + 10 - size, g.drawLine(x, y, x - 10, y + 10 } } y + y - - 10); size); + 10); size); flushGraphics(); 18 Grafika 2D – Midlet public class GameMidlet extends MIDlet implements CommandListener { private Display display; private SimpleCanvas canvas; ... public void startApp() { if (canvas == null) { canvas = new SimpleCanvas(); canvas.start(); } display = Display.getDisplay(this); display.setCurrent(canvas); } } public void destroyApp(boolean unconditional) { canvas.stop(); } ... 19 Hierarchia lcdgui java.lang.Object Displayable Canvas Alert Form Command Screen List Graphics Item Gauge TextBox Stringtem DateField Klasa konkretna Ticker ChoiceGroup TextField ImageItem Klasa abstrakcyjna 20 Programowanie sieciowe CLDC 1.0 MIDP 1.0 MIDP 2.0 21 Programowanie sieciowe Nawiązanie połączenia odbywa się za pomocą klasy javax.microedition.io.Connector: try { Connection con = Connector.open("protocol:address;parameters"); } catch (ConnectionNotFoundExeption e) { // brak sterownika dla protokołu } Kilka przykładów url'i: ● HTTP: Connector.open("http://java.sun.com/wireless"); ● gniazdo: Connector.open("socket://java.sun.com:port"); ● datagram: Connector.open("datagram://java.sun.com:port"); 22 Programowanie sieciowe public class TimeMidlet extends MIDlet implements CommandListener{ private TimeClient client; private Command cExit = new Command("Exit", Command.EXIT, 1); private Command cStart = new Command("GetTime", Command.ITEM, 1); public TimeMidlet() { Form f = new Form("Time Demo"); f.append(new StringItem("Wybierz GetTime ...", " ")); f.addCommand(cExit); f.addCommand(cStart); f.setCommandListener(this); Display.getDisplay(this).setCurrent(f); } public void commandAction(Command c, Displayable s) { if (c == cExit) notifyDestroyed(); else if (c == cStart) { Thread t = new Thread(new TimeClient(this)); t.start(); } } ... } 23 Programowanie sieciowe public class TimeClient implements Runnable { private TimeMidlet parent; private StringItem sTime; public TimeClient(TimeMidlet m) { parent = m; Form f = new Form("Time Client"); sTime = new StringItem("Time:" , " "); f.append(sTime); Display.getDisplay(parent).setCurrent(f); } public void commandAction(Command c, Displayable s) { if (c == Alert.DISMISS_COMMAND) { parent.notifyDestroyed(); parent.destroyApp(true); } } 24 Programowanie sieciowe } public void run() { SocketConnection sc = null; InputStream is = null; try { sc = (SocketConnection) Connector.open("socket://theta.uoks.uj.edu.pl:13"); is = sc.openInputStream(); StringBuffer sb = new StringBuffer(); int c = 0; while (((c = is.read()) != '\n') && (c != -1)) sb.append((char) c); sTime.setText(sb.toString()); } catch(IOException e) { Alert a = new Alert("Time", "Błąd", null, AlertType.ERROR); a.setTimeout(Alert.FOREVER); Display.getDisplay(parent).setCurrent(a); } finally { try { if(is != null) is.close(); if(sc != null) sc.close(); } catch(IOException e) { e.printStackTrace(); } } } 25 Narzędzia programistyczne 1. Eclipse ● plugin: Eclpseme - http://www.eclipseme.org/ ● pakiet CLDC/MIDP – np: Sun Java Wireless Toolkit (http://java.sun.com/javame/downloads/index.jsp) lub ze stron producenta telefonu 2. Netbeans ● plugin do Netbeans: Netbeans Mobility Pack - http://www.netbeans.org/products/mobility/ 3. Inne narzędzia ● kompresor kodu (obfuscator) - http://proguard.sourceforge.net/ 26 Podsumowanie Specyfikacja JME składa się z wielu różnorodnych API implementowanych przez poszczególne urządzenia mobilne. Jest to szczególnie istotne w przypadku pisaniu kodu, który ma działać na wielu różnych modelach urządzeń. Ze wględu na szybki rozwój technologii i postępującą miniaturyzację telefony komórkowe potrafią obsługiwać coraz bardziej skomplikowane aplikacje napisane w Javie. Niemniej trzeba pamiętać, że urządzenia mobilne nadal wymagają specjalnego sposobu kompilacji i dystrybucji oprogramowania (midletów). 27