Previous Up Next
OBEX Object Passing Home (PDF)

Kapitel 4  Entwickeln mit OOP

In diesem Kapitel wird demonstriert, wie die OOP Bibliothek eingesetzt werden kann. Um die zur Demonstration entwickelte Beispielapplikation verstehen zu k�nnen, wird an dieser Stelle kurz auf die Grundlagen der J2ME Programmierung eingegangen. Die Kenntnis der Grundlegenden Sprachkonstrukte von Java sowie das Verst�ndnis einfacher Datenstrukturen und -container wird vorausgesetzt.

4.1  Grundlagen der J2ME Programmierung

Die J2ME ist, wie bereits in [Abb.: 2.3] gezeigt, im Java Umfeld einzuordnen. Java Programme, die auf einem mobilen Endger�t ausgef�hrt werden k�nnen, werden als MIDlets bezeichnet. Die Namensgebung folgt aus dem Zusammenschluss von MID (Mobile Information Device) und Applet. Der haupts�chliche Unterschied zur J2SE besteht im limiterten Sprachumfang der J2ME. Der signifikante Unterschied der beiden Umgebungen ist auf die Beschaffenheit der Hardware zur�ckzuf�hren, die wie bereits in [Kapitel 2.3] und [Kapitel 2.5.1] gezeigt, im J2ME Umfeld mit starken Einschr�nkungen belegt ist.

4.1.1  Lebenszyklus eines MIDlets

Jedes MIDlet ist gezwungen von der MIDlet Klasse zu erben. Sie erm�glicht das korrekte starten, stoppen und aufr�umen des MIDlets. Eine MIDlet darf, im Gegenteil zu J2SE Programmen, nicht �ber eine public static void main() Methode verf�gen. Ist dies trotzdem der Fall wird sie von der Application Management Software (AMS) ignoriert [VW02, S. 438].

Die AMS ist Bestandteil des Betriebssystems des mobilen Endger�ts. Sie erm�glicht die Ausf�hrung des MIDlets (und ggf. auch die Installation/Deinstallation dessen). Weiterhin ist die AMS in der Lage das MIDlet zu pausieren oder es zu stoppen. Der Zustandsautomat eines MIDlets ist in [Abb.: 4.1] dargestellt.

Abbildung 4.1: Zustandsautomat eines MIDlets (Vgl.: [VW02, S. 440])

Die Struktur des Zustandsautomaten wird im Code durch die an den Zustand�berg�ngen in [Abb.: 4.1] annotierten Methoden realisiert. Das Betriebssystem ist dadurch in der Lage beim Eintreffen eines externen Ereignisses, wie z. B. einem eingehenden Anruf, die Methode pauseApp() aufzurufen, durch die das MIDlet bis zu Fortf�hrung pausiert wird. [Listing 1] zeigt ein einfaches „Hello World“ MIDlet um den Sachverhalt zu verdeutlichen.

Listing 1: Hello World MIDlet

package hello; import javax.microedition.midlet.*; 5 import javax.microedition.lcdui.*; public class Test extends MIDlet { private TextBox tf; 10 public Test() { tf = new TextBox("Hello", "World", 20, TextField.UNEDITABLE); } public void startApp() { 15 Display.getDisplay(this).setCurrent(tf); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} 20 }


4.1.2  User-Interface Entwicklung

Um die User-Interface Entwicklung eines MIDlets zu vereinfachen, kann ein sogenannter Screen Designer eingesetzt werden. Die Netbeans Entwicklungsumgebung bietet einen solchen mit dem Mobility Pack an1. Des weiteren bietet es einen sogenannten Flow Designer, mit dessen Hilfe einzelne „Seiten“, sogenannte Forms, leicht untereinander verk�pft werden k�nnen. M�chte man keine Spiele oder Programme mit anspruchsvollen graphischen Elementen entwickeln, l�sst sich mit den dargebotenen Werkzeugen relativ schnell das Frontend einer Applikation entwickeln. Um das Basisset der graphischen Elemente dennoch mit einer ansprechenderen Optik zu versehen, wurde das J2ME Polish2 Projekt ins Leben gerufen. J2ME Polish l�sst sich, zumindest laut Angabe der Entwickler, ebenfalls in die Netbeans IDE integrieren3.

Abbildung 4.2: Netbeans Flow Designer

Die [Abb.: 4.2] zeigt den Flow Designer f�r ein „Hello World“ Projekt. Wie zu sehen ist, verbindet man den Startpunkt der Applikation direkt mit der nach dem Start des MIDlets anzuzeigenden Form. Wird der mit Exit beschriftete Button des MIDlets gedr�ckt, terminiert die Applikation. Die Handhabung der Netbeans IDE, bez�glich der Applikationsentwicklung im J2ME Umfeld, soll an dieser Stelle nicht weiter vertieft werden4.

4.2  Projektorganisation

Wie bei jedem gr�sseren Projekt, ist es auch bei der Entwicklung von Applikationen f�r mobile Endger�te sinnvoll, f�r die verwendeten Entit�tsobjekte eine Bibliothek zu erzeugen. Dadurch kann eine mehrfache Implementierung der Entit�tsobjekte f�r differente Plattformen vermieden werden. M�chte man also eine Applikation entwickeln, die es erm�glicht, Daten zwischen einem Desktop-Computer und einem mobilen Endger�t auszutauschen, ist dieser Ansatz jedem anderen vorzuziehen. Da die OOP Bibliothek in der Lage ist, sowohl im J2SE, als auch im J2ME Umfeld zu operieren, bietet es sich an diese Form der Projektorganisation prinzipiell zu verwenden, da man sich so die M�glichkeit offen h�lt, einen Client f�r andere Plattformen zu implementieren. Eine beispielhafte Projektkonfiguration ist dann wie folgt gestaltet.
MeineApplikation-J2ME
Dieses Projekt beinhaltet den Code der notwendig ist, um die Logik und die Anzeige des mobilen Endger�ts entsprechend der Anforderung zu manipulieren.
MeineApplikation-J2SE
Dieses Projekt beinhaltet den Code der Applikationslogik sowie die notwendigen Manipulationen der Anzeige, um eine �nderung der Entit�tsobjekte zu erm�glichen.
MeineApplikation-Entit�tsobjekte
In diesem Projekt sind einzig die zu beiden Projekten geh�renden Entit�tsobjekte zu finden. Sollte eine �nderung der Entit�tsobjekte erfolgen, wirkt sich die �nderung unweigerlich auf beide Projekte aus, womit sich eine Duplikation des Codes vermeiden l�sst.

4.3  Beispielapplikation

Die Funktionsweise sowie der konkrete Einsatz der Bibliothek wird anhand einer J2ME Beispielapplikation demonstriert. Die Applikation ist bewusst sehr einfach gehalten. So existieren keine zus�tzlichen Forms mit deren Hilfe die Entit�tsobjekte manipuliert werden k�nnen. Eine Manipulation der Daten ist f�r die Demonstration nicht erforderlich. Die Applikation bietet allerdings die M�glichkeit zur visuellen Repr�sentation der Daten, damit die korrekte �bertragung derer verifiziert werden kann.

Die Beispielapplikation ist mit Hilfe des in Netbeans integrierten Emulators entwickelt worden. Zur Demonstration der Bibliothek muss der Emulator zweimal gestartet werden. Durch die F�higkeit des Emulators eine Bluetooth-Schnittstelle zu emulieren, kann die Applikation ohne einen vorhandenen Bluetooth-Stack getestet werden. Netbeans ist allerdings nicht in der Lage die Bluetooth-Schnittstelle von einer J2SE Applikation auf ein J2ME Projekt zu emulieren, weswegen sich die Beispielapplikation auf ein J2ME Programm beschr�nkt.

Die Funktionsweise des Programms ist relativ einfach. Nachdem das Projekt in Netbeans importiert wurde, muss das Programm zweimal gestartet werden. Auf einem der beiden simulierten Ger�te wird nun der Empfangsdienst gestartet. Man kann sich nun auf Wunsch die vorhandenen Daten anzeigen lassen. Das Programm reagiert mit einer Fehlermeldung, dass keine Daten vorhanden sind. Auf dem anderen Ger�t wird im n�chsten Schritt die �bertragung der (im Code konfigurierten) Daten veranlasst. Ist die �bertragung der Daten abgeschlossen, wird ein Dialogelement angezeigt, welches das Ende der �bertragung signalisiert. Auf dem empfangenden Ger�t k�nnen die Daten jetzt angezeigt werden. Die Zustands�berg�nge der Beispielapplikation sind in [Abb.: 4.3], ein bebilderter Ablauf in [Abb.: 4.4] dargestellt.

Abbildung 4.3: Zustands�berg�nge der J2ME Beispielapplikation

Da innerhalb der Applikation keine M�glichkeit besteht die zu �bertragenden Daten zu manipulieren bzw. zu setzen, werden die Daten innerhalb des Programmcodes direkt zugewiesen. Die Konfiguration eines Person Objekts, das die Schnittstelle IObexObjectPassing implementiert, erfolgt wie in Listing [Listing 2] gezeigt. Das Beispiel zeigt wie zwei Person Objekte konfiguriert, und anschliessend mit der Klasse BulkObjectPusher versendet werden k�nnen.

Listing 2: Verwendung von BulkObjectPusher

Person p = new Person(); p.setName("Schneider"); p.setVorname("Rosemarie"); p.setAge(37); 5 Person hans = new Person(); hans.setName("Peter"); hans.setVorname("Hans"); hans.setAge(37); 10 Vector transferringObjects = new Vector(); transferringObjects.addElement(p); transferringObjects.addElement(hans); 15 new BulkObjectPusher(transferringObjects).addObserver(this);


Die Klassen der OOP Bibliothek sind in ihrer Anwendung sehr einfach. Der in [Listing 2] gedruckte Code f�hrt den Transfer der Daten in Zeile 15 durch. Wie zu sehen ist, wird die Klasse ohne Zuweisung initialisiert. Eine Zuweisung auf eine lokal verf�gbare Variable ist nicht notwendig. Durch den an die Klasse angeschlossenen Observer5 ist es m�glich, �ber das Ende der Daten�bertragung informiert zu werden. Es ist weiterhin zu erkennen, dass dem Objekt keine Zieladresse �bergeben wurde. Das ist ebenfalls nicht notwendig, da die Bibliothek in der Lage ist, ihren Kommunikationspartner selbstst�ndig zu lokalisieren.

Um auf dem entfernten Ger�t Daten empfangen zu k�nnen muss der ObjectReceiver instanziiert werden. Er ist, ebenso wie die Klassen ObjectPusher und BulkObjectPusher nicht blockierend implementiert.
Listing 3: Verwendung von ObjectReceiver

Vector receivedObjects = new Vector(); new ObjectReceiver(receivedObjects);


Der vorgestellte Code in [Listing 3] empf�ngt die �bertragenen Objekte und speichert sie in den Vector receivedObjects, aus dem die empfangenen Daten zu einem sp�teren Zeitpunkt wieder ausgelesen und weiterverabeitet werden k�nnen.

Damit dies alles m�glich ist, muss das zu �bertragende Objekt lediglich das Interface IObexObjectPassing implementieren. Ein partieller Ausschnitt der Implementierung des Person Objekts ist in [Listing 4] dargestellt. Die restlichen Methoden sind ausschliesslich Accessor/Mutator Methoden des Objekts.

Listing 4: Implementierung von IObexObjectPassing

public byte[] getAsByteArray() { bout = new ByteArrayOutputStream(); dout = new DataOutputStream( bout ); 5 byte[] ret = null; try { /* Write values */ 10 dout.writeUTF(name); dout.writeUTF(vorname); dout.writeInt(age); dout.flush(); 15 /* do temp copy so we can close * the writers */ ret = bout.toByteArray(); dout.close(); 20 bout.close(); } catch (IOException ex) { ex.printStackTrace(); 25 } return ret; } 30 public void setObjectData(byte[] ba) { bin = new ByteArrayInputStream(ba); din = new DataInputStream(bin); try 35 { this.name = din.readUTF(); this.vorname = din.readUTF(); this.age = din.readInt(); 40 din.close(); bin.close(); } catch (IOException ex) { 45 ex.printStackTrace(); } }


Die wichtigsten Elemente, des in [Listing 4] dargestellten Codes sind die Zeilen 10-12 sowie die Zeilen 36-38. Mit diesen Zeilen werden die Daten des Objekts in ein Byte-Array geschrieben (10-12) und k�nnen ebenfalls von einem Byte-Array gelesen werden (36-38). Dieser Mechanismus ist zur korrekten Funktionsweise der OOP-Bibliothek notwendig6.

Der Ablauf der Beispielapplikation ist in [Abb.: 4.4] dargestellt. Da die Applikation auf zwei Mobiltelefonen gestartet werden muss, wird im Begleittext das jeweilige Ger�t mit >>1<< oder >>2<< markiert. Ist keine Markierung angegeben, so bezieht sich die Anzeige auf beide Telefone.

[Auf beiden Telefonen muss zun�chst das Programm mittels “Launch” gestartet werden.]

[Anzeige nach dem Programmstart.]

[>>1<< Der Server muss gestartet werden.]

[>>1<< Der Start des Servers muss einmalig best�tigt werden, da ein Zugriff auf das Bluetooth API erfolgt.]

[>>1<< Die vorhandenen Daten sollen angezeigt werden.]

[>>1<< Es sind keine Daten verf�gbar, mit “Back” verlassen]

[>>2<< Daten sollen �bertragen werden.]

[>>2<< Zum senden “Send” w�hlen.]

[>>2<< Der Zugriff auf das Bluetooth API muss einmalig best�tigt werden.]

[>>2<< Die �bertragung wird best�tigt, mit “Done” verlassen.]

[>>1<< Empfangene Daten k�nnen angezeigt werden.]

Abbildung 4.4: Ablauf der Beispielapplikation


1
Entwicklungsumgebung und Mobility Pack k�nnen unter https://www.netbeans.org bezogen werden.
2
Siehe https://www.j2mepolish.org/
3
Siehe https://www.j2mepolish.org/docs/install.html#netbeans5
4
Eine Einf�hrung in die MIDP Entwicklung mit Hilfe des Mobility Packs f�r Netbeans ist unter [Net06] zu finden.
5
Siehe [Kapitel 3.2.2]
6
Siehe [Kapitel 3.3]
OBEX Object Passing Home (PDF) CCGLogo

Previous Up Next