corner
Home      Know How         Artikel      Programmierung J2ME

Programmierung mit dem J2ME MIDP

von Karl Banke

Das Java "Mobile Information Device Profile", MIDP, ist die Ausprägung von Suns Programmierumgebung Java, die zur Erstellung von mobilen und vernetzten Java Anwendungen auf kleinen portablen Geräten verwendet findet. Zielplattform sind dabei insbesondere 3G Mobiltelefone, die über eine begrenzte Bandbreite, geringe Prozessorleistung und Monochrom- oder Farbdisplays geringer Auflösung verfügen. Aber auch Kassenterminals oder 2-Weg Pager Systeme kommen als Zielplatformen in Frage.

Dabei stellt MIDP basierend auf der CLDC (Connected Limited Device Configuration) Spezifikation Bibliotheken zur Verfügung. Als einer der großen Vorteile von Java im PC- und Server Bereich gilt bekanntlich die weitgehende Plattformunabhängigkeit der erstellten Software. Im Folgenden soll u.a. untersucht werden, ob und inwieweit dies auch für MIDP Anwendungen gilt.

Mein Name ist MIDlet

Ähnlich zu Applets - Java Bytecode, der aus dem Inter- oder Intranet geladen und im Webbrowser ausgeführt wird - definiert die MIDP sog. MIDlets. Diese werden von der MIDP Implementierung verwaltet und bilden den Einstiegspunkt für die Programmierung. Im Unterschied zu "normalen" Java Applikationen ist es nicht möglich, ein Programm mit einer main Routine zu starten. Vielmehr wird die Applikation von der Applikationsmanagementsoftware - im folgenden kurz Framework genannt - verwaltet.

Midlets werden in jar-Archiven ausgeliefert, die die erforderlichen Klassen und Konfigurationsparameter enthalten. Beim Start eines MIDlets wird vom Framework die Methode startApp() aufgerufen, in der die Initialisierung der Applikation durchgeführt wird. Das Framework kann ein MIDlet durch Aufruf von pauseApp() temporär stoppen, z.B. wenn eingehende Telefonanrufe beantwortet werden müssen. Schließlich kann das MIDlet durch den Aufruf der destroyApp() Methode vom Framework zerstört werden. Wird es explizit aus dem Programmcode beendet, so wird die Methode notifyDestroyed() verwendet, um das Framework vom Beenden des MIDlets zu benachrichtigen.

Das CLDC, auf dem das MIDP basiert, hat einige wesentliche Einschränkungen, die es von einer Java 2 Standard Edition (J2SE) basierten Java Umgebung unterscheiden. So gibt es z.B. keine Thread-Gruppen und keine Methode Object.finalize(). Die Menge der verfügbaren nativen Funktionen ist abgeschlossen. Das bedeutet u.a., das Bibliotheken die auf gerätespezifische Low Level Funktionalitäten zugreifen vom Hersteller des Geräts selbst bereitgestellt werden müssen. Der Java Reflection Mechanismus - die Abfrage von Typinformationen zur Laufzeit - steht im CLDC nicht zur Verfügung. Aus Sicherheitsgründen dürfen auch keine selbstgeschriebenen Classloader verwendet werden.

Während sich diese Einschränkungen im Alltag als relativ unspektakulär erweisen, gibt es ein fehlendes Feature, das sicherlich von vielen Entwicklern schmerzlich vermisst wird. Der CLDC fehlt nämlich - mit Hinweis auf Performance Überlegungen - jegliche Unterstützung für Fließkommaoperationen. Da eine Vielzahl von denkbaren Anwendungen, wie z.B. Taschenrechner, Bezahlsysteme, Messdatenanzeige usw. mit Fließkommazahlen arbeiten ist es zumindest erstaunlich, dass nicht zumindest eine Klassenbibliothek im Lieferumfang enthalten ist, um solche Operationen vereinheitlicht durchzuführen. Das jedes Projekt für solche grundlegenden Operation wieder ein eigenes Süppchen kochen soll, ist eigentlich nicht einzusehen.

Die Bibliotheken

Um plattformunabhängig programmieren zu können, sind natürlich entsprechend übergreifende Klassenbibliotheken notwendig. Hierzu liefert das MIDP die Bibliotheken javax.microedition.lcdui, javax.microedition.io und javax.microedition.rms. Sie dienen zur Erstellung grafischer Benutzeroberflächen, der Ein- und Ausgabe von Daten über Netzwerkverbindungen und zur persistenten Datenspeicherung auf dem mobilen Gerät selbst.

Oberflächen

Das Paradigma zur Verwendung grafischer Oberflächen sieht vor, dass immer genau ein Objekt vom Typ Displayable angezeigt wird. Dabei können jedem Objekt eine beliebige Anzahl an Commands hinzugefügt werden. Ereignisse an der Benutzeroberfläche werden mit Listener-Klassen behandelt. Dabei hat jedes Objekt - im Unterschied zu J2SE - höchstens einen Listener.

In der Oberfläche wird zwischen "High Level" und "Low Level" API unterschieden. High Level bezeichnet dabei Komponenten zur Definition und Behandlung von Formularen. Die Anzahl der High Level Komponenten ist aufgrund der geringen Displaygröße äußerst beschränkt. Es stehen im Prinzip nur Auswahlliste, Textfeld und Pegeleinstellung zur Verfügung. Diese können zu relativ komplexen Formularen groupiert werden. Ein High Level Formular kann mit einem Ticker zur fortlaufenden Informationsanzeige versehen werden.

Die Low Level API umfasst im wesentlichen ein Canvas Element, auf das direkt gezeichnet werden kann. Dabei unterstützt das MIDP zwar prinzipiell Farbdisplays. Leider werden aber weder Alpha Blending noch Farbmischung, geschweige denn verschiedene Grafik Layer angeboten. Dies ist bei der Programmierung grafischer Anzeigen allgemein und natürlich insbesondere bei der Erstellung von Spielen recht hinderlich.

Verbindungen

Allgemein werden Objekte vom Typ Connections verwendet, um Netzwerkverbindungen darzustellen. Eine Connection kann im Client- oder Server-Mode aktiv sein, so dass ein Gerät auch eingehende Verbindungen akzeptieren kann, z.B. mittels Bluetooth oder Infrarot Schnittstelle von anderen mobilen Geräten. Es werden Stream Connections und Datagram Connections unterschieden. Zur Verbindung auf zentrale Server kommt sicherlich der HttpConnection besondere Bedeutung zu. Diese steht auch in nicht IP Netzen, wie WAP, stets zur Verfügung.

Persistenz

Ein schönes Feature ist, dass jedes MIDlet verschiedene Stores anlegen kann, um sog. Records zu speichern. Dies ermöglichst eine Datenhaltung, z.B. von Adressen, Passwörtern, Benutzereinstellungen und High Score Listen. Auch hier ist es mit der Abstraktion nicht allzuweit her. Einzelne Records werden als Bytefeld abgespeichert und über eine laufende Nummer, die recordId identifiziert. Basierend auf den bestehenden Bibliotheken lassen sich aber durchaus abstraktere Komponenten, wie Adressdatenbank, Highscore Listen, Preference API u.ä. erstellen.

Was noch fehlt

Leider bietet das MIDP keine einheitliche Spezifikation für einen Zugriff auf Telefoniefunktionen. Damit ist eines der attraktivsten Anwendungsfelder zunächst nicht zugänglich. Hier haben wohl Sicherheitsüberlegungen eine Rolle gespielt. Wer kann sonst sicher sein, dass sich hinter dem netten Spielchen nicht ein perfider 0190 Dialer verbirgt. Auch die Tatsache, dass das MIDP eben nicht nur für Mobiltelefone, sondern auch für andere schmalbanding vernetzte Geräte eingesetzt werden soll, hat hier sicherlich eine gewisse Rolle gespielt.

Auch ist es schade, dass das MIDP keinerlei Zugriff auf Soundfähigkeiten der Geräte zulässt. Leider fehlt damit nicht nur die Möglichkeit zur Untermalung von Spielen. Es ist nicht einmal möglich, einfache akustische Signale vom Schlage eines System.beep() zu erzeugen.

Was schon geht

Trotz der hier formulierten Kritik ist es durchaus möglich auf Basis eines kleinsten gemeinsamen Nenners recht attraktive Applikationen für das MIDP zu entwickeln. Dies zeigt auch eine große Zahl von MIDlets, die online verfügbar sind. Die folgenden Screenshots der Emulatoren von Nokia und Javasoft zeigen ein relativ einfaches Beispiel für ein Geschicklichkeitsspiel inklusive einer Highscoreverwaltung, die auf dem Records Mechanismus basiert. Die zugehörige Jar Datei und der Applikation Deskriptor können heruntergeladen werden.

Zusammenfassend kann man sagen, dass das MIDP eine interessante Plattform bietet, um kleinere Applikationen für mobile Geräte zu erstellen. Dem Anspruch der Plattformunabhängigkeit wird man allerdings nur schwer gerecht werden können. Erfordern doch Anpassungen an unterschiedliche Displays schon einen erheblichen programmatischen Aufwand, der sich natürlich auch in entsprechend größeren Anwendungen niederschlägt. Wahrscheinlicher ist aus Sicht des Autors, dass Entwicklungen dediziert für Geräte eines bestimmten Herstellers durchgeführt werden. Hier stehen dann auch viele der Funktionalitäten zur Verfügung, die wir in der Spezifikation schmerzlich vermisst hatten.

Dennoch bietet Java hier den Vorteil, dass sich Entwickler zumindest einer gemeinsamen Basisplattform bedienen können. Ein Unternehmen, das Spiele entwickelt, muss zwar immer noch Versionen für unterschiedliche Geräte ausliefern. Die Softwareentwicklung selbst gestaltet sich aber - u.U. auch durch den Einsatz entsprechender Frameworks - effektiver. Auch ist es vorteilhaft, dass Java sich hier als allgemeine Programmiersprache für mobile Geräte definiert und nicht dediziert als ein Framework zur Spiele Erstellung oder zur Telefonie.

Ausblick

Viele der hier aufgeführten Defizite der MIDP 1.0 werden in der Version 2.0 behoben sein. So bietet die Version 2.0, die sich seit dem 18. April 2002 im Public Review befindet, u.a. Unterstützung für transparente PNG Bilder, Sound und für sichere Netzwerkverbindungen. Insbesondere Spieleprogrammierer werden sich über Sprites und die Unterstützung mehrerer Layer auf dem Display freuen. Optional werden MIDI Formate, der Zugriff auf vorhandene serielle Schnittstellen und die Möglichkeit verschiedener Push Formate unterstützt.

Literatur

  1. CLDC and the K Virtual Machine. Spezifikation und Referenzimplementierung für die CLDC.
  2. Mobile Information Device Profile. Spezifikation und Downloads zu MIDP.
  3. JSR 135 Mobile Media API. Spezifikation einer Multimedia API für CLDC und CDC J2ME Configurations
  4. JSR 178 Mobile Game API. Definition einer Spiele API als optionales Paket für MIDP
  5. JSR 118 Mobile Information Device Profile 2.0.
  6. Midlet.org bietet einige schöne Midlets an.
Karl Banke
2011/09/01
Kontakt/Impressum    Über Iternum    Rechtliche Hinweise    Datenschutz   © iternum GmbH 2011