The Next Big Thing
Mobile: The Next Big Thing?
Kann ja immerhin sein, also ist es vermutlich nicht ganz falsch mal zu schauen, was sich mit den kleinen Krachmachern so alles anstellen läßt. Immerhin lassen sich die meisten ja in Java programmieren, also sollte die Einstiegshürde doch relativ gering sein. Dachten wir. Allerdings ist es gar nicht wirklich Java, sondern Java-ME, eine doch deutlich abgespeckte Java-Variante für kleine Geräte. Java-ME ist dabei auch kein monolithischer Block, sondern besteht aus einer Kern API, zu der es Ergänzungspakete gibt. Die sind jeweils nach der entsprechenden JSR benannt und erschließen beispielsweise Grafik- und Medienformate, das Dateisystem, das Netz oder Bluetooth der Programmierung. Daher ist es nicht immer leicht herauszufinden, welches Gerät nun welches Feature auch tatsächlich unterstützt.
Wer den schnellen Einstieg sucht ist wie immer mit Netbeans gut bedient, hier gibt es die Mobile Edition, die außer dem JDK schon alles mitbringt, was man braucht. Wer lieber etwas Tool-übergreifender arbeitet, braucht das JDK sowie das Mobile SDK, das ebenfalls die komplette API-Dokumentation auch aller Ergänzungspakete sowie umfangreiche Beispiele mitbringt. Die Beispiele werden übrigens in einem hübschen Emulator ausgeführt, der verschiedene Handy-Profile darstellen kann. Netbeans integriert ihn ebenfalls. Wer lieber mit Eclipse arbeitet, dem sei EclipseME empfohlen, ein Plugin, das das Mobile SDK in Eclipse verfügbar macht. Auch dann steht der Emulator zur Verfügung.
Die Core-API nach der letzten Spezifikation 2.0 (JSR 118) enthält einige Klassen aus java.io, java.lang und java.util, daneben Userinterface - Klassen in javax.microedition.lcdui und javax.microedition.lcdui.game. javax.microedition.rms bietet eine einfache Möglichkeit, beschränkte Datenmengen zu persistieren, javax.microedition.media und javax.microedition.media.control bieten Zugriff auf die vom Gerät angebotenen Multimediafeatures.
Midlet
Mobile-Programme sind ein bisschen wie Applets, sie müssen allerdings nicht java.applet.Applet, sondern javax.microedition.midlet.MIDlet erweitern und die drei abstrakten Methoden startApp(), pauseApp() und destroyApp(boolean) implementieren, womit dann auch schon alles über den Lebenszyklus des Midlets gesagt wäre. Midlets selbst sind anders als Applets keine visuellen Komponenten, sondern erzeugen eine visuelle Komponente, die sie an das Display übergeben. Alle visuellen Komponenten leiten sich von javax.microedition.lcdui.Displayable ab, wobei über javax.microedition.lcdui.Screen einige der aus dem AWT bekannten UI-Komponenten bereitgestellt werden, währen die Linie über javax.microedition.lcdui.Canvas zum Zeichnen dient. In unserem Beispiel verwenden wir als UI-Komponente eine javax.microedition.lcdui.Form, das ist eine Komponente, die weitere Elemente aufnehmen kann, und fügen einen enfachen Text hinzu. Im Mobile SDK-Emulator oder der Entwicklungsumgebung ist dieses Programm bereits lauffähig und zeigt Text und Überschrift an.
package de.java1.blog.mobile;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
/**
* Midlet Beispiel
* @author Hans Joachim Herbertz
* @created 28.10.2008
*/
public class HelloWorldMidlet extends MIDlet {
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
Form form=new Form("Hello World Form");
form.append("Hello World");
Display.getDisplay(this).setCurrent(form);
}
}
Um auf Benutzereingaben zu reagieren wird wie im AWT das Listerner-Konzept verwenden, der wichtigste Listener ist hier der javax.microedition.lcdui.CommandListener. CommandListener können an allen visuellen Komponenten angehängt werden, da die entsprechende Methode setCommandListener(CommandListener) bereits in javax.microedition.lcdui.Displayable implementiert ist. In unserem Beispiel machen wir unser Midlet selbst zum CommandListener, wie wir es auch gern mit einfachen Applets machen, und implementieren die entsprechende Methode commandAction(Command, Displayable).
package de.java1.blog.mobile;
import java.util.Date;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class HelloWorldMidlet2 extends MIDlet implements CommandListener {
private Command exitCommand,messageCommand;
private void log(String msg) {
System.out.println(new Date()+" "+msg);
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
log("destroy");
}
protected void pauseApp() {
log("pauseApp");
}
protected void startApp() throws MIDletStateChangeException {
log("startApp");
Form form=new Form("Hello World Form");
form.append("Hello World");
exitCommand=new Command("Exit",Command.EXIT,1);
messageCommand=new Command("Show Message",Command.SCREEN,2);
form.addCommand(exitCommand);
form.addCommand(messageCommand);
form.setCommandListener(this);
Display.getDisplay(this).setCurrent(form);
}
public void commandAction(Command command, Displayable displ) {
log("commandAction: "+command.getLabel());
if (exitCommand.equals(command)) {
notifyDestroyed();
} else if (messageCommand.equals(command)){
Alert alert=new Alert("Alert goes here.");
Display.getDisplay(this).setCurrent(alert, Display.getDisplay(this).getCurrent());
}
}
}
Wie man hier bereits erkennt, basiert das Eventsystem auf Commands der Klasse javax.microedition.lcdui.Command. Diese Kommands erzeugen wir in Zeile 34f und fügen sie direkt der UI-Komponente hinzu (addCommand(Command)). Für die visuelle Repräsentation der Commands sind wir als Programmierer nämlich gar nicht zuständig, darum kümmert sich die Laufzeitumgebung, bzw. das Gerät. Wir können nur in so fern darauf Einfluß nehmen, indem wir beim Erzeugen der Commands angeben, um welche Art von Command es sich handelt (Command.EXIT, Command.SCREEN usw.) und die Bedeutung des Commands angeben; je niedriger die Zahl des dritten Parameters, um so bedeutender das Command. Beendet schließlich wird das Midlet durch Aufruf von notifyDestroyed(), wodurch die Laufzeitumgebung angewiesen wird, das Midlet zu beenden.
Insgesamt fällt der Einstieg also leicht. Was man natürlich sehr vermißt ist Javas umfangreiche Klassenbibliothek, die im Java-ME doch arg eindedampft ist.