der Arbeit
Transcription
der Arbeit
Konzeption und Implementierung einer mobilen Geogrid®-Version mit J2ME (Öffentliche Version) Heiko Maaß Konstanz, 25.02.2005 St. Gallen, 30.10.2005 (Öffentliche Version) DIPLOMARBEIT Diplomarbeit zur Erlangung des akademischen Grades Diplom-Informatiker (FH) an der Fachhochschule Konstanz Hochschule für Technik, Wirtschaft und Gestaltung Fachbereich Informatik Studiengang WI Thema: Konzeption und Implementierung mobilen Geogrid®-Version mit J2ME einer Diplomand: Heiko Maaß, [Adresse aus Datenschutzgründen entfernt] 1. Prüfer: 2. Prüfer: Prof. Dr., Heiko von Drachenfels Dipl.-Inf. (FH), Marc Nädele EADS Deutschland GmbH, 88039 Friedrichshafen Abgabedatum: 25.02.2005 Ehrenwörtliche Erklärung Hiermit erkläre ich, Heiko Maaß, geboren am [aus Datenschutzgründen entfernt] , (1) dass ich meine Diplomarbeit mit dem Titel: „Konzeption und Implementierung einer mobilen Geogrid®-Version mit J2ME“ bei der EADS Deutschland GmbH unter Anleitung von Professor Dr. Heiko von Drachenfels und Dipl.-Inf. (FH) Marc Nädele selbständig und ohne fremde Hilfe angefertigt habe und keine anderen als die angeführten Hilfen benutzt habe; (2) dass ich die Übernahme wörtlicher Zitate, von Tabellen, Zeichnungen, Bildern und Programmen aus der Literatur oder anderen Quellen (Internet) sowie die Verwendung der Gedanken anderer Autoren an den entsprechenden Stellen innerhalb der Arbeit gekennzeichnet habe. Ich bin mir bewusst, dass eine falsche Erklärung rechtliche Folgen haben wird. Friedrichshafen, 25.02.2005 Heiko Maaß Zusammenfassung (Abstract) Thema: Konzeption und Implementierung einer mobilen Geogrid®Version mit J2ME Diplomand: Heiko Maaß Firma: EADS Deutschland GmbH Betreuer: Prof. Dr. Heiko von Drachenfels Dipl.-Inf. (FH) Marc Nädele Abgabedatum: 25.02.2005 Schlagworte: CDC/Personal Profile, CLDC/MIDP, digitale Karten, J2ME, Java, Geogrid®, GPS, Kartendarstellung, Mobile Geräte, Mobiltelefon, PDA, Second-Chance Algorithmus Schnellere Prozessoren, mehr Speicher, größere Displays. PDAs und insbesondere Mobiltelefone werden von Generation zu Generation leistungsfähiger. Diese Diplomarbeit untersucht, ob eine Kartendarstellung für mobile Geräte mit der J2ME-Plattform (Java 2 Mobile Edition) realisierbar ist und welche Einschränkungen in Kauf genommen werden müssen. Zunächst wurde die J2ME-Plattform und ihre Aufteilung in Konfigurationen, Profile und optionale Pakete analysiert. Dabei wurde insbesondere auf die Leistungsfähigkeit und die Verbreitung der beiden Konfiguration/Profil Kombinationen CLDC/MIDP und CDC/Personal Profile eingegangen. Anschließend wurde eine Anforderungsliste für eine mobile Geogrid®-Version erstellt. Aufgrund der größeren Verbreitung von CLDC/MIDP-fähigen mobilen Geräten auf dem Markt wurde die mobile Geogrid®-Version für diese Laufzeitumgebung implementiert. Der implementierte Prototyp ist in der Lage, Karten über einen (auch im Rahmen der Diplomarbeit erstellten) Kartenservers zu beziehen, sie mit Hilfe des Second-Chance Algorithmus zu cachen und sie auf dem Display des mobilen Gerätes darzustellen. Darüber hinaus kann die aktuelle Position über einen Bluetooth-GPS-Empfänger ermittelt werden und die angezeigte Karte auf diese Position zentriert werden. Die Diplomarbeit stellt die Softwarearchitektur des Prototyps vor und geht auf die Besonderheiten der J2ME-Entwicklung ein. Abschließend werden die Erfahrungen mit der Entwicklungs- und Testumgebung geschildert. Dankesworte Ich bedanke mich bei der EADS Deutschland GmbH für die Möglichkeit ein solch interessantes Diplomarbeitsthema bearbeiten zu können. Insbesondere möchte ich mich bei meinen beiden Betreuern • • Herrn Prof. Dr. Heiko von Drachenfels und Herrn Dipl.-Inf. (FH) Marc Nädele für die exzellente Betreuung meiner Diplomarbeit bedanken. Ebenso danke ich meinen Vorgesetzten und Kollegen bei der EADS Deutschland GmbH, die mich während der Arbeit unterstützt und immer wieder mit interessanten Artikeln und Tipps versorgt haben. Heiko Maaß Nachtrag 30.10.2005: An dieser Stelle möchte ich mich bei dem FBTI (Fachbereichstag Informatik) für die Prämierung meiner Diplomarbeit in dem Fachgebiet Technische Informatik bedanken. Ein weiteres Dankeschön geht an die SYSGO AG, die den mit der Prämierung verbundenen Geldpreis gesponsort hat. Ebenso bedanke ich mich bei der EADS Deutschland GmbH für die Erlaubnis zur Veröffentlichung meiner Diplomarbeit. Folgende Kapitel habe ich in Absprache mit der EADS Deutschland GmbH entfernt: • 2.5 • 6.2 • 6.3.2 • 6.3.3 • 6.4 • 6.5 • 6.5.1 • 6.5.2 • 6.5.3 • 6.6.1 • 6.6.2 • 12.4 Diese Kapitel enthielten sensible Unternehmensdaten und können nicht veröffentlicht werden. 1 2 Einleitung............................................................................................................... 12 Geogrid® ................................................................................................................ 13 2.1 Produkte .......................................................................................................... 13 2.2 Kartenprojektion ............................................................................................. 14 2.3 Kartenformate ................................................................................................. 15 2.4 Overlays .......................................................................................................... 16 2.5 JavaMap .......................................................................................................... 16 2.6 Zusammenfassung .......................................................................................... 16 3 J2ME – Java-Plattform für mobile Geräte ........................................................ 18 3.1 Überblick ........................................................................................................ 18 3.2 Konfigurationen .............................................................................................. 19 3.3 Profile.............................................................................................................. 20 3.4 Optionale Pakete ............................................................................................. 21 3.4.1 Bluetooth API ......................................................................................... 21 3.4.2 Location API........................................................................................... 22 3.4.3 Webservices API..................................................................................... 22 3.5 Verbreitung ..................................................................................................... 23 3.6 PersonalJava.................................................................................................... 24 3.7 Blick über den Tellerrand: Alternative Plattformen ...................................... 24 3.7.1 Symbian OS ............................................................................................ 24 3.7.2 .net Compact Framework........................................................................ 25 3.8 Zusammenfassung .......................................................................................... 25 4 CLDC/MIDP im Vergleich mit CDC/Personal Profile ..................................... 26 4.1 Virtuelle Maschine.......................................................................................... 26 4.2 Applikationsmodelle: MIDlets und Xlets ....................................................... 28 4.3 Installation von MIDlets und Xlets................................................................. 28 4.4 Persistenzkonzepte.......................................................................................... 29 4.5 Benutzeroberfläche und Grafikfähigkeiten..................................................... 30 4.5.1 LCDUI High-Level API ......................................................................... 31 4.5.2 LCDUI Low-Level API .......................................................................... 32 4.5.3 MIDP Game API .................................................................................... 32 4.5.4 CDC AWT .............................................................................................. 35 4.6 Netzwerkverbindung....................................................................................... 35 4.7 Wireless Toolkit.............................................................................................. 35 4.8 Zusammenfassung .......................................................................................... 36 5 Anforderungen an eine mobile Geogrid®-Version............................................. 37 5.1 Bereits existierende Kartensoftware für mobile Geräte.................................. 37 5.2 Übersicht ......................................................................................................... 38 5.3 Karten.............................................................................................................. 39 5.4 Overlay............................................................................................................ 39 5.5 Caching von heruntergeladenen Informationen.............................................. 39 5.6 Positionsermittlung ......................................................................................... 39 6 Kartenserver.......................................................................................................... 40 6.1 Funktionalität des implementierten Prototypen .............................................. 40 6.2 Implementierte Requests................................................................................. 41 6.3 Struts Webframework ..................................................................................... 41 6.3.1 Überblick .................................................................................................41 6.3.2 Controller Komponente...........................................................................42 6.3.3 Konfiguration ..........................................................................................42 6.4 Technische Voraussetzungen ..........................................................................42 6.5 Architekturübersicht........................................................................................42 6.5.1 Modellschicht ..........................................................................................42 6.5.2 Controllerschicht .....................................................................................42 6.5.3 Viewschicht .............................................................................................42 6.6 Implementierungsdetails .................................................................................42 6.6.1 Zuordnung von Kartenname und MapID ................................................42 6.6.2 Packagestruktur .......................................................................................42 6.6.3 Logging ...................................................................................................43 6.6.4 MapLibraryLoader ..................................................................................43 6.7 Zusammenfassung...........................................................................................43 7 Mobile Geogrid®-Version mit CLDC/MIDP ......................................................44 7.1 Funktionalität der mobilen Geogrid®-Version ................................................44 7.2 Mindestanforderungen an das mobile Gerät ...................................................45 7.3 Wiederverwendung von Code aus JavaMap ...................................................46 7.4 Architekturübersicht........................................................................................46 7.5 Modellschicht ..................................................................................................47 7.5.1 Datenquelle..............................................................................................47 7.5.2 Kartenformat ...........................................................................................48 7.5.3 Kachelung der Karte................................................................................50 7.5.4 Sektion-Konzept......................................................................................52 7.5.5 Codebeispiel Sektion-Konzept................................................................57 7.5.6 Nachladestrategie ....................................................................................59 7.5.7 Kommunikation mit dem Kartenserver...................................................60 7.5.8 Caching der geladenen Karten und Kacheln ...........................................61 7.5.9 Positionsbestimmung ..............................................................................66 7.5.10 Noch nicht implementierte Features .......................................................68 7.6 Controllerschicht .............................................................................................69 7.6.1 Die zentrale Controller Klasse ................................................................69 7.6.2 Action-Thread Konzept...........................................................................70 7.6.3 Konsistenzüberlegungen .........................................................................73 7.7 Viewschicht .....................................................................................................73 7.7.1 High-Level-LCDUI Komponenten für die Menüführung.......................74 7.7.2 Low-Level-LCDUI Komponenten für die Kartendarstellung.................75 7.8 Zusammenfassung...........................................................................................78 8 Erfahrungen mit der Entwicklungsumgebung...................................................79 8.1 Netbeans 4.0 ....................................................................................................79 8.2 J2ME Wireless Toolkit....................................................................................81 8.3 Sony Ericsson SDK.........................................................................................81 9 Fazit ........................................................................................................................83 10 Ausblick..................................................................................................................84 11 Glossar....................................................................................................................85 12 Anhang ...................................................................................................................87 12.1 Installation von MobileJavaMap auf ein Siemens S65 ...................................87 12.2 Installation von MobileJavaMap auf ein SE K700i........................................ 87 12.3 MobileJavaMap Bedienungsanleitung............................................................ 88 12.3.1 Startmenü ................................................................................................ 88 12.3.2 Optionen.................................................................................................. 89 12.3.3 Kartenauswahl ........................................................................................ 89 12.3.4 GPS ......................................................................................................... 90 12.3.5 Karte anzeigen ........................................................................................ 90 12.3.6 Springen zu Koordinate .......................................................................... 91 12.4 MapServer Requests ....................................................................................... 92 12.5 Messungen ...................................................................................................... 93 12.5.1 Häufigkeit der Bytegrößen von Kacheln ................................................ 93 13 Abbildungen .......................................................................................................... 94 14 Tabellen.................................................................................................................. 95 15 Codefragmente ...................................................................................................... 96 16 Quellen ................................................................................................................... 97 12 1 Kapitel 1: Einleitung Einleitung Schnellere Prozessoren, mehr Speicher, größere Displays. PDAs und insbesondere Mobiltelefone werden von Generation zu Generation leistungsfähiger. Mit der zunehmenden Leistungsfähigkeit erschließen sich gleichzeitig auch neue Möglichkeiten, die bis vor kurzem noch nicht realisierbar waren. Gerade Videospiele erfreuen sich großer Beliebtheit. Sie bilden momentan den größten Anteil an der verfügbaren Software für Mobiltelefone. Allerdings sind mobile Geräte bezüglich des Betriebssystems sehr unterschiedlich: neben eigenen Betriebssystemen der Mobiltelefonhersteller, buhlen auch das Symbian OS von Symbian und Windows Mobile von Microsoft um die Vorherrschaft auf dem Mobiltelefon- und PDA-Markt. Die J2ME-Plattform von Sun verspricht dagegen die größtmögliche Kompatibilität und Verbreitung (350 Million mobile Geräte laut Jonathan Schwartz [@COMPUTER_RESELLER_NEWS04]), was zu einer hohen Anzahl von potentiellen Kunden führen würde. Aber reicht die Leistungsfähigkeit von J2ME-kompatiblen Geräten für die Darstellung von eingescannten Landkarten, so genannten Rasterkarten aus? Welche Leistungseinbußen müssen dafür in Kauf genommen werden? Und wie steht es mit der Plattformunabhängigkeit? Diese Diplomarbeit behandelt diese Fragen und zeigt anhand einer im Rahmen der Diplomarbeit implementierten mobilen Geogrid®-Version mit J2ME, was derzeit technisch machbar ist. Es gibt bereits wissenschaftliche Arbeiten mit ähnlichem Thema, wie z.B. [@ALCASAR04]: Die dort vorgestellte Lösung einer Kartendarstellung auf einem Mobiltelefon lagert allerdings die komplette Funktionalität auf einem Server aus, was eine ständige Verbindung zum Internet erforderlich macht. Eine andere Arbeit [@NISSEN03]) untersucht dagegen die Darstellung von reinen vektorbasierten Karten auf Mobiltelefonen, auch hier wird von einer ständigen Internetverbindung ausgegangen. Diese Diplomarbeit grenzt sich deutlich von diesen Arbeiten ab. Hier wird anhand einer konkreten Implementierung gezeigt, wie rasterbasierte Karten dargestellt werden können, und wie viel Funktionalität das mobile Gerät übernehmen kann. Zum besseren Verständnis der Konzeption und Implementierung sollte der Leser sich bereits mit der Programmiersprache Java und der Modellierungssprache UML auseinandergesetzt haben. Vorteilhaft sind auch HTTP-Kenntnisse; das zustandslose Protokoll wird in der Diplomarbeit nicht weiter beschrieben. Nach dieser Einleitung wird der Leser in die Geogrid®-Technologie und in einige geografische Grundbegriffe eingeführt. Einen Überblick über die J2ME-Plattform und die vielen Spezifikationen verschafft das dritte Kapitel. Im darauf folgenden Kapitel werden zwei J2ME-Laufzeitumgebungen im Hinblick auf mehrere technische Aspekte wie verwendete Virtuelle Maschine und Grafikfähigkeit untersucht. Dabei werden die Unterschiede zwischen den beiden Laufzeitumgebungen herausgearbeitet. Unter Berücksichtung der Einschränkungen werden im fünften Kapitel Anforderungen an eine mobile Geogrid®-Version mit J2ME gestellt. Das sechste Kapitel stellt einen Kartenserver vor, von dem die mobile Geogrid®-Version die Kartendaten bezieht. Der Kartenserver wurde ebenfalls im Rahmen der Diplomarbeit konzipiert und implementiert. Das siebte Kapitel bildet den Hauptteil dieser Arbeit und stellt detailliert die Softwarearchitektur der implementierten mobilen Geogrid®-Version vor. Dabei werden Designentscheidungen kommentiert und begründet. Darüber hinaus wird untersucht, welche der gestellten Anforderungen erfüllt werden konnten. Vor dem Fazit und Ausblick werden noch die bei Kapitel 2: Geogrid® 13 der Implementierung gesammelten Erfahrungen mit der Entwicklungs- und Testumgebung beleuchtet. 2 Geogrid® EADS definiert Geogrid® auf der Firmenwebseite folgendermaßen: „Der Begriff „Geogrid®“ definiert die Technologie für eine Familie von Softwareprodukten, die für die Darstellung von geographischen Informationen (Raster- / VektorKarten, georeferenzierte Bilddaten, Höhendaten, Geländedaten usw.) genutzt werden“. [@EADS04]. Unter einer Rasterkarte versteht man eine pixelbasierte Landkarte, vergleichbar mit einem Bitmap. Vektorkarten dagegen basieren auf einem Datenmodell, das die Umwelt anhand einzelner Punkte abstrahiert. In diesem Kapitel werden die wichtigsten Geogrid®-Produkte und die verwendeten Kartenformate vorgestellt. Zusätzlich werden kurz einige geographische Begriffe, wie Kartenprojektion und Kartendatum, erläutert. Im Anschluss daran wird die Softwarearchitektur von JavaMap, einer Geogrid®-Version für Java, vorgestellt. JavaMap ist das Vorbild für die später besprochene mobile Geogrid®-Version mit J2ME. 2.1 Produkte Die patentierte Geogrid®-Technologie wird sowohl in militärischen als auch in zivilen Produkten eingesetzt. Zu den zivilen Produkten gehört der Geogrid®-Viewer, der grundlegende Funktionen zur Betrachtung von topographischen Karten anbietet. Der Geogrid®-Viewer wird nicht direkt verkauft, sondern für Auftraggeber, wie das Landesvermessungsamt Baden-Württemberg, konfiguriert. Diese Auftraggeber vertreiben den angepassten Viewer unter eigenem Namen und mit eigenem Kartenmaterial. Ein bekanntes Geogrid®-Viewer Produkt ist die Top50 Serie der Deutschen Landesvermessungsbehörden, die ganz Deutschland mit topographischen Karten im Maßstab 1:50.000 abdeckt. Zu den militärischen Produkten gehören MilGeo-PCMAP, Geogrid® Sit-View, PCMAP Swissline und MAPS NT. MilGeo-PCMAP wurde für das Amt für Geoinformationswesen der Bundeswehr entwickelt und wird innerhalb der Bundeswehr in über 5000 Installationen benutzt. Gegenüber dem zivilen Geogrid®-Viewer bietet MilGeo-PCMap eine deutlich größere Funktionalität. Beispielsweise unterstützt es neben dem eigenen Kartenformat KMRG den Import von NATO-Rasterdatenformaten. Zusätzlich können eigene Rasterdaten georeferenziert und entzerrt werden. Noch mehr Funktionalität bietet Geogrid® Sit-View, dass MilGeo-PCMap unter anderem um militärische Lagedarstellung und Lagebearbeitung erweitert. (Eine Lage stellt eine militärische Situation eines Einsatzgebietes anhand von taktischen Symbolen dar). PCMAP Swissline ist eine für das Schweizer Militär angepasste Sit-View Version. MAPS NT (Map Preparation Software NT) wird hauptsächlich von militärischen Geoämtern eingesetzt und bietet Kartenaufbereitungs- und Konvertierungsfunktionalität. Dieses Tool wird für jeden Kunden individuell angepasst. Alle vorgestellten Produkte sind in C++ implementiert. Das einzige Java-Produkt ist JavaMap, das in einem separaten Unterkapitel vorgestellt wird. 14 2.2 Kapitel 2: Geogrid® Kartenprojektion Die in Geogrid® verwendeten Rasterkarten werden immer mit Hilfe einer Kartenprojektion erstellt. Unter einer Kartenprojektion versteht man die Abbildung der Erdoberfläche auf eine zwei-dimensionale Ebene. Da die so entstandene Abbildung nicht gleichzeitig linien-, flächen- und winkeltreu sein kann, gibt es verschiedene Projektionsverfahren, die mit unterschiedlichen mathematischen Modellen arbeiten. Kurz vorgestellt werden soll hier nur die Gauß-Krüger-Projektion, die für Abbildung der topographischen Karten in Deutschland verwendet wird. Bildlich gesprochen, wird in diesem Projektionsverfahren ein imaginärer Zylinder senkrecht (im Vergleich zum Mittelmeridian) um die Erde „gestülpt“. Dabei entspricht der Umfang des Zylinders genau dem Erdumfang am Längenkreis. Entlang des Mittelmeridians ist die Abbildung längentreu, außerhalb nimmt die Fehlerrate mit steigendem Abstand vom Mittelmeridian zu, von daher umfasst der Abbildungsbereich nur 3 Grad (1,5 Grad östlich bis 1,5 Grad westlich des Mittelmeridians, siehe grauer Bereich in Abbildung 2-1). Mit Hilfe von 120 solcher Streifen wird die gesamte Erde abgebildet. Eine Variante dieser Projektion ist die Universale Transversale Mercator-Projektion, deren verwendeter Zylinder einen kleineren Umfang als der Erdumfang besitzt und somit eine größere Streifenbreite zulässt. Die UTM-Projektion ist Basis für das weltweit umfassende UTM-Koordinatensystem und wird in Zukunft auch in Deutschland die Gauß-Krüger-Projektion ersetzen. Mit Hilfe von Projektionsberechnungen kann zu jedem Punkt auf einer Rasterkarte eine geografische Koordinate ermittelt werden. Umgekehrt kann aus einer geografischen Koordinate die dazugehörige „Pixelkoordinate“ errechnet werden. Vorraussetzung ist, dass die Rasterkarte georeferenziert wurde, d.h. dass für einzelne Punkte auf der Rasterkarte die geografischen Koordinaten quasi als Referenz für die spätere Berechnung angegeben worden sind. Mittelmeridian Abbildung 2-1: Transversale Mercator-Projektion (nach [@UNI_ROSTOCK_GEOSERVICE04]) Die Form der Erde entspricht nicht ganz einer Kugel, sondern ist viel komplexer aufgebaut. Mit Gravitationsberechnungen können exaktere Modelle erstellt werden, die das Gravitationsfeld der Erde beschreiben. Ein Geoid repräsentiert so ein Gravitationsmodell und geht dabei von einer planaren Oberfläche aus. Aufgrund der Komplexität werden Geoiden für Kartenberechnung und Georeferenzierung nicht eingesetzt, stattdessen wird versucht, das Geoidmodell mit Ellipsoiden anzunähern. Dabei kann ein Ellipsoid nur einen Teil der Erdoberfläche „korrekt“ repräsentieren. Abbildung 2-2 illustriert in Kapitel 2: Geogrid® 15 einer 2D-Darstellung einen Geoiden (graues Gebilde), der durch zwei Ellipsoiden angenähert wird. Die beiden Rechtecke umfassen die Bereiche der Erdoberfläche, die durch die Ellipsoiden korrekt repräsentiert werden. Man sieht deutlich, dass nur ein kleiner Teil der Oberfläche mit einem Ellipsoiden „korrekt“ beschrieben werden kann. Von daher gibt es sehr viele Referenzellipsoiden, die einen bestimmen Teil der Erdoberfläche beschreiben. Auf den Karten wird der verwendete Referenzellipsoid durch das Kartendatum, auch Kartenbezugssystem genannt, angegeben. Ein wichtiger Ellipsoid sei an dieser Stelle noch erwähnt: Der WGS-84-Ellipsoid ist Grundlage des GPS-Systems und versucht, den kompletten Geoiden möglichst genau zu umfassen. Abbildung 2-2: Annäherung an den Geoid mit Ellipsoiden ( 2D-Darstellung) 2.3 Kartenformate Militärische Geogrid®-Produkte verwenden das offene, standardisierte KMRG (Komprimierte MilGeo-Rastergrafik)-Format. Das firmeneigene, verschlüsselte MAPS (Map Preparation Software)-Format ist für zivile Produkte bestimmt und wird aufgrund von Interessen der Vermessungsämter nicht veröffentlicht. Von daher wird an dieser Stelle nur auf das KMRG-Format näher eingegangen. Das in zwei Dateien (Header und eigentliche Daten) aufgeteilte Format unterstützt Rasterkarten mit 1 Bit, 2 Bit, 4 Bit, 8 Bit Farbtiefe und dazugehöriger Farbtabelle. Anstatt der Farbtabelle kann die Rasterkarte auch RGB-Werte zu Beschreibung der Pixel verwenden. Neben den eigentlichen Kartendaten kann eine KMRG-Karte noch weitere Bilddaten enthalten. Die Bild- und Kartendaten werden in Kacheln aufgeteilt und können auf verschiedene Bildebenen verteilt werden. Dabei müssen die Kantenlängen der Kacheln einem Vielfachen von 64 Pixeln entsprechen. Abbildung 2-3 illustriert eine KMRG-Karte, die aus 9 Kacheln besteht. Jede Kachel ist dabei 256 * 256 Pixel groß. Um die Dateigröße zu verkleinern, können die Kacheln mit den Komprimieralgorithmen LZW (Lempel-Ziv Welch) und LZW2 einzeln komprimiert werden. 16 Kapitel 2: Geogrid® 768 768 0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 2,2 256 256 768 * 768 Pixel große KMRGKarte mit 3x3 Kacheln Einzelne Kachel mit 256 * 256 Pixeln Abbildung 2-3: KMRG Karte mit 3x3 Kacheln 2.4 Overlays Overlays sind Ebenen, die auf die eigentliche Karte gelegt werden können. Jede Ebene kann mehrere geometrische Formen, Bilder und andere graphische Elemente enthalten. Für Geogrid®-Produkte wurden drei Dateiformate spezifiziert: Ein ASCII-, XML- und ein binäres Dateiformat. Auf den genauen Aufbau der einzelnen Formate wird hier nicht weiter eingegangen. Abbildung 2-4 zeigt ein Overlay mit drei Elementen: Zwei Bildern und einer Ellipse. Ähnlich wie in einem Zeichenprogramm können die Elemente erstellt und bearbeitet werden, die Priorität eines Elements bestimmt dabei die Zeichenreihenfolge. Abbildung 2-4: Overlay Beispiel in JavaMap 2.5 JavaMap [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 2.6 Zusammenfassung Nach der Vorstellung der Geogrid®-Produktreihe, den notwenigen geografischen Begriffen und dem Kartenformat KMRG wurde der Leser in einen Teil der Softwarearchitektur von JavaMap eingeführt. JavaMap ist die Geogrid®-Implementierung in Java und somit die „erste Adresse“ für Klassen, die im Kartenserver und in der mobilen Geogrid®-Version wieder verwendet werden können. Spätere Kapitel gehen darauf ein, Kapitel 2: Geogrid® 17 welche Teile von JavaMap übernommen wurden. Zunächst wird der Leser im nächsten Kapitel in die J2ME-Welt eingeführt. 18 Kapitel 3: J2ME – Java-Plattform für mobile Geräte 3 J2ME – Java-Plattform für mobile Geräte Dieses Kapitel stellt die verschiedenen Spezifikationen der J2ME-Plattform vor und informiert über die tatsächliche Verbreitung auf dem Markt. Zusätzlich wird kurz auf zwei Konkurrenzplattformen eingegangen. (Symbian und .net Compact Framework). 3.1 Überblick Personal Profile Profil Personal Basis Profile MIDP Konfiguration Geräteklasse IMP CLDC KVM Mobiltelefone, Pager Abbildung 3-1: J2ME-Plattform Foundation Profile CDC JVM PDAs, Set-Top-Boxen JDBC RMI PDA WSA Location BT MMAPI Optionale Pakete WMA 1999 spezifizierte Sun Microsystems drei Java-Plattformen, um ein möglichst großes Anwendungsspektrum mit Java abzudecken zu können: J2SE (Java Standard Edition) und J2EE (Java Enterprise Edition) sind für den Desktop bzw. Servereinsatz vorgesehen. J2ME (Java Mobile Edition) konzentriert sich auf mobile Geräte wie PDAs, Set-Top-Boxen und Mobiltelefone. Mobile Geräte unterliegen naturbedingt starken Hardwareeinschränkungen wie geringem Hauptspeicher und langsamer CPU. Eine einzige allgemeingültige Spezifikation ist aufgrund der unterschiedlichen Hardwareausstattung und –leistung nicht möglich bzw. nicht sinnvoll. Aus diesem Grund ist die J2ME-Plattform in Konfigurationen, Profilen und optionalen Paketen aufgeteilt. Eine J2ME-Laufzeitumgebung setzt sich dabei aus einer Konfiguration, einem darauf aufbauenden Profil und mehreren optionalen Paketen zusammen. Die J2ME-Plattform legt sich auf zwei Geräteklassen fest: Die erste umfasst Mobiltelefone, Pager und kleinere PDAs. Charakterisierend für diese Geräte ist die geringe Speicher- und Rechenleistung. Die zweite Geräteklasse deckt PDAs und Set-Top-Boxen ab, die über erheblich mehr Speicher- und CPU-Leistung verfügen. Abbildung 3-1 veranschaulicht die Struktur der J2ME-Plattform. Auf die einzelnen dargestellten Konfigurationen, Profile und optionalen Pakete wird in den nächsten Kapiteln eingegangen. Kapitel 3: 3.2 J2ME – Java-Plattform für mobile Geräte 19 Konfigurationen Eine Konfiguration spezifiziert die unterstützten Sprachfeatures, die verfügbare Klassenbibliothek und die Einschränkungen der zu verwendenden virtuellen Maschine. Bedingt durch die eingeschränkte Hardwareleistung und Speicherkapazität kann eine Konfiguration immer nur eine Teilmenge der Funktionalität von J2SE offerieren. Momentan sieht J2ME zwei Konfigurationen vor, die sich deutlich in den Hardwareanforderungen und in der Leistungsfähigkeit unterscheiden: CDC (Connected Device Configuration) und CLDC (Connected Limited Device Configuration). CLDC zielt auf leistungsschwächere Geräte wie Mobiltelefone und Pager, wohin gegen CDC für Geräte mit schnellerem Prozessor und mehr Speicher spezifiziert wurde (z.B. PDAs, Set-Top-Boxen). Die einzelnen Anforderungen der Konfigurationen an RAM und ROM eines mobilen Gerätes kann der Tabelle 3-1 entnommen werden. Die festgelegte ROM-Größe wird für die Implementierung der virtuellen Maschine und der Klassenbibliotheken verwendet. Jede Spezifikation wurde im Rahmen des Java Community Process erarbeitet. Der Java Community Process ist eine Institution, in der mehrere Unternehmen und auch Einzelpersonen gemeinsam an Java-Spezifikationen arbeiten, um allgemein akzeptierte APIStandards zu schaffen. Die entsprechende JSR (Java Specification Request)-Nummer wird in letzten Spalte der Tabelle angegeben. Betrachtet werden hier nur Spezifikationen, die zum Zeitpunkt der Abgabe der Diplomarbeit in der endgültigen Version vorliegen. Es existiert zwar bereits eine Vorabversion einer neuen CDC-Spezifikation, die wird hier nicht weiter betrachtet, da sie sich noch ändern kann. Name Version ROM RAM JSR Nr. CLDC 1.0 128 KB 32 KB 30 CLDC 1.1 160 KB 32 KB 139 CDC 1.01 512 KB 256 KB 36 Tabelle 3-1 : J2ME-Konfigurationen Der verfügbare ROM-Speicher erlaubt nur eine sehr kleine Klassenbibliothek, CLDC 1.0 beschränkt sich auf das absolut Notwendige und spezifiziert nur 4 Packages, die zusammen auf 76 Klassen und Interfaces kommen. Um zusätzlich Speicher zu sparen, orientiert sich CLDC am JDK 1.1. Vereinzelt werden auch Klassen aus dem JDK 1.3 verwendet. CDC dagegen repräsentiert eine Teilmenge des JDK 1.3. Von daher fällt die Klassenbibliothek mit 13 Packages und 305 Klassen erheblich umfangreicher aus. Neben den Einschränkungen in der Klassenbibliothek fordert die CLDC-Spezifikation eine spezielle virtuelle Maschine, die an die begrenzte Speicher- und Rechenleistung und der mobilen Geräte angepasst ist. Die Referenzimplementierung K Virtual Machine (KVM) von Sun erfüllt diese Anforderungen. Im Kapitel 4.1 werden die Unterschiede zur Java Virtual Machine dargelegt. 20 Kapitel 3: J2ME – Java-Plattform für mobile Geräte CDC sieht dagegen keinen funktionellen Einschränkungen für die virtuelle Maschine vor. Sun bietet die CDC HotSpot Implementation an, eine ressourcenschonende aber dennoch vollwertige Java Virtual Machine, wie sie in der Java Language Specification [GOSLING00] spezifiziert ist. Momentan ist sie nur für Linux/x86 Systeme verfügbar. Dritthersteller offerieren zusätzlich für unterschiedliche Hardwareplattformen alternative virtuelle Maschinen für CDC (z.B. Esmertec Jeode oder IBM J9). 3.3 Profile Ein Profil baut auf einer Konfiguration auf und erweitert sie um zusätzliche High-Level APIs z.B. für die grafische Benutzeroberfläche und den Lebenszyklus von Anwendungen. Das Mobile Information Device Profile (MIDP) ist das gängige Profil für Mobiltelefone und spezifiziert das GUI-Framework LCDUI (Lowest Common Denominator User Interface), welches sich stark von AWT und Swing unterscheidet. (Das LCDUI wird im Kapitel 4.5 genauer erläutert). Das Information Module Profile (IMP) stellt keine Anforderungen an die Grafikfähigkeit eines mobilen Gerätes und ist für den Einsatz auf mobilen Geräten wie z.B. Notrufsäulen, Parkuhren und Alarmsystemen konzipiert. Beide Profile sind für die CLDC Konfiguration vorgesehen. Für CDC sind drei Profile spezifiziert, die aufeinander aufbauen. Das Foundation Profile ist das grundlegende Basisprofil und sieht keine GUI-Funktionalität vor. Dieses Profil wird vom Personal Basis Profile um leichtgewichtige AWT-Komponenten erweitert. Erst das Personal Profile führt schwergewichtige AWT-Komponenten ein. Wie auch Konfigurationen stellen Profile Mindestanforderungen an RAM und ROM eines mobilen Gerätes (siehe Tabelle 3-2). Die Anforderungen von Konfiguration und Profil sind kumulativ, so benötigt CLDC 1.0 zusammen mit MIDP 1.0 insgesamt 256 KB ROM und 64 KB RAM. Name Version Basiskonfiguration ROM RAM JSR Nr. MIDP 1.0 CLDC 1.0, 1.1 128 KB 32 KB 37 MIDP 2.0 CLDC 1.0, 1.1 256 KB 128 KB 118 IMP 1.0 CLDC 128 KB 32 KB 195 Foundation Profile 1.0 CDC 1.01 1024 KB 512 KB 46 Personal Profile 1.0 CDC 1.01 2048 KB 1024 KB 129 1.0 CDC 1.01 2560 KB 1024 KB 62 Basis Personal Profile 1.0, 1.1 Tabelle 3-2: J2ME-Profile Kapitel 3: 3.4 J2ME – Java-Plattform für mobile Geräte 21 Optionale Pakete Optionale Pakete sind zusätzliche standardisierte APIs, die unter anderem die Verwendung von Bluetooth, Webservices oder Datenbankzugriff ermöglichen. Einige optionale Pakete laufen nur in einer CDC-Laufzeitumgebung, wie z.B. das JDBC und das RMI-Paket. Andere wiederum sind für CLDC vorgesehen, können aber auch für CDC implementiert werden. Tabelle 3-3 liefert einen Überblick über die optionalen Pakete. Name Funktionalität Vorgesehen für JSR Nr. CLDC 1.0 CLDC 1.1 CDC 1.01 Unterstützung der Bluetooth Protokolle x x x 82 Mobile Media Unterstützung für Audio und Video. x x x 135 Wireless Messaging Versand und Empfang von Nachrichten innerhalb eines Mobilfunknetzes (SMS, Cell-Broadcast Nachrichten) x x x 120 Location Positionsbestimmung Verfahren. x x 179 Webservices Unterstützung für Webservices. x x x 172 Personal Information Management Kontakt, Termin Verwaltung. x x x 75 FileConnection Zugriff auf das Dateisystem. x x Remote Method Invocation Unterstützung für RMI. x 66 JDBC Datenbankzugriff mit JDBC x 169 Bluetooth (JABWT) API mit und mehreren Aufgaben 75 Tabelle 3-3: Optionale Pakete Die Verwendung von optionalen Paketen erweitert zwar den Möglichkeiten für J2MEApplikationen, allerdings muss dafür eine reduzierte Portabilität in Kauf genommen werden, da die optionalen Pakete von den Geräteherstellern nicht implementiert werden müssen und somit nicht auf jedem Gerät vorhanden sind. Im Folgenden werden einige APIs kurz vorgestellt, die bei der Konzeption und Realisierung der später vorgestellten mobilen Geogrid®-Version eine Rolle spielen. 3.4.1 Bluetooth API Die Bluetooth API (genauer Java APIs for Bluetooth wireless technology, kurz JABWT) kapselt mehrere Bluetooth Protokolle und ermöglicht somit einen einfachen Zugang zu der ansonsten komplexen Funktionalität. Neben der Verwendung der Protokolle RFCOMM und L2CAP ermöglicht JABWT die Suche von anderen Bluetooth-Geräten sowie das Auffinden und Registrieren von Bluetooth-Diensten. Die unterstützten Protokolle seien hier der Übersicht halber nur sehr kurz beschrieben: Das RFCOMM-Protokoll simuliert eine Verbindung zweier Geräte über die serielle Schnittstelle. Eine Schicht tiefer sitzt das L2CAP (Logical Link Control and Adaptation 22 Kapitel 3: J2ME – Java-Plattform für mobile Geräte Protocol)-Protokoll, das mit Paketen und Kanälen arbeitet und als Grundlage für höhere Protokolle verwendet wird. Optional unterstützt JABWT auch das OBEX (Object Exchange Protocol)-Protokoll, das auf dem RFCOMM-Protokoll sitzt und als Alternative zum HTTP-Protokoll konzipiert worden ist. OBEX wird z.B. für den Austausch von Dateien oder elektronischen Visitenkarten verwendet. Das JABWT verwendet das in CDC und CLDC spezifizierte Generic Connection Framework (kurz GCF) als Schnittstelle für die Bluetooth Verbindungen. Das GCF wird im Kapitel 4.6 vorgestellt. An dieser Stelle möchte ich auf [KUMAR04] hinweisen, das die Programmierung mit der API sehr gut beschreibt. Die Bluetooth API wird später verwendet, um einem Bluetooth-GPS-Empfänger anzusprechen. 3.4.2 Location API Die Location API benötigt als Untersatz die CLDC 1.1 Konfiguration und ermöglicht die Ermittlung der aktuellen Position des Mobiltelefons mit unterschiedlichen Verfahren, z.B. mit Hilfe des Netzbetreibers: Mobilfunknetze sind in viele Zellen aufgeteilt, die zusammen eine große Fläche abdecken. Beim Einschalten des Mobiltelefons bucht sich das Telefon in eine solche Zelle ein. Anhand der Zellinformationen können Netzbetreiber die Position des eingebuchten Mobiltelefons ermitteln. Diese Positionierungsdaten können mit Hilfe der Location API auf dem Endgerät in Form von Längen- und Breitenangaben ausgewertet werden. Vorraussetzung ist die Unterstützung der Location API durch die Netzbetreiber, was momentan in Deutschland noch nicht der Fall ist. Zusätzlich zu der Positionierungsermittlung über die Netzbetreiber ermöglicht die Location API das Ansprechen eines im Gerät befindlichen GPS-Empfängers. Momentan gibt es sehr wenige Mobiltelefone mit eingebauten GPS-Empfänger, das wird sich aber mit Sicherheit schlagartig ändern, da ab 2007 die neu verkauften Mobiltelefone in Japan mit einem GPS-Empfänger ausgestattet sein müssen (siehe auch [@HEISE04_47573]). Die Location API kann momentan aufgrund mangelnder Unterstützung seitens der Netzbetreiber und den fehlenden GPS-Empfängern in Mobiltelefonen nicht eingesetzt werden. Zukünftig bietet sie aber bei vorhandener Unterstützung eine Alternative zum separaten Bluetooth-GPS-Empfänger. 3.4.3 Webservices API Die Webservices API ermöglicht einen einfachen Zugriff auf Webservices. Die dazu notwendigen XML Verarbeitungsmethoden sind ebenfalls Bestandteil der API: Sie enthält eine Teilmenge der Java APIs for XML Processing (JAXP), die im Gegensatz zur J2SE Version nur über einen SAX (Simple API for XML Parsing)-Parser verfügt. Aufgrund der Speicherrestriktionen verzichtet die Webservices API auf einen DOM (Document Object Model)-Parser. Die Kommunikation zwischen mobilen Gerät und Server erfolgt über das SOAP (Simple Object Access Protocol)-Protokoll, dabei tritt das mobile Gerät mit der Webservices API immer nur als Klient auf. Das Erzeugen und Interpretieren einer SOAP-Nachricht wird durch die ebenfalls in der Webservices API enthaltenen JAX-RPC 1.1 (Java APIs for XML based Remote Procedure Calls) API gekapselt. Auf JAXP, SAX, DOM und JAX-RPC wird nicht näher eingegangen, da es den Rahmen der Diplomarbeit sprengen würde. Die Webservices API wird zwar in der Konzeptionsphase der mobilen Ge- Kapitel 3: J2ME – Java-Plattform für mobile Geräte 23 ogrid®-Version in Betracht gezogen, aber in der konkreten Implementierung nicht verwendet, da momentan kein Gerät mit dieser API ausgestattet ist. 3.5 Verbreitung Mitentscheidend für den Erfolg einer Software ist die Anzahl der kompatiblen Endgeräte. Laut Jonathan Schwartz, dem Geschäftsführer von Sun, existieren weltweit rund 350 Millionen Java-fähige Mobiltelefone: “There are 350 million Java mobile handsets. Three hundred and fifty million is an interesting number; it's a much more interesting number than 350 markets of one million because it provides the appeal of ubiquity and compatibility.” [@COMPUTER_RESELLER_NEWS04]. Der „Anreiz” der Kompatibilität wird allerdings durch die Vielfalt der Spezifikationen relativiert. Das Sun-Statement „Write once, run everywhere“ trifft für J2ME (wie auch für J2SE) leider nicht zu. Um der Vielfalt der Spezifikationen der J2ME-Plattform gerecht zu werden, ist eine Differenzierung der Endgeräte nach Konfiguration, Profil und optionalen Paketen erforderlich. Die nachfolgende Tabelle bietet eine Übersicht über die Anzahl der Mobiltelefone, die eine bestimmte Konfiguration/Profil Kombination unterstützen. Zusätzlich wird angegeben, wie viele der Geräte die Bluetooth und Location API unterstützen. Eine Garantie auf Vollständigkeit sei nicht gegeben, aber eine grundlegende Marktübersicht ist dennoch gewährleistet. Die Daten wurden aus der Device Database der J2ME Polish Webseite [@J2MEPOLISH05] entnommen (Stand: 24.1.05), die Informationen für fast jedes J2ME-fähige Endgerät bereitstellt. Einige der dort enthaltenen Modelle wurden bereits ausrangiert und können nicht mehr im Handel erworben werden. PDAs werden nicht in der Tabelle erfasst, dort kann die benötigte virtuelle Maschine vom Anwender selbst installiert werden. Auf Mobiltelefonen ist das nicht möglich, die bereits installierte Virtual Machine kann nicht durch den Anwender ausgetauscht werden. Kombination Anzahl Endgerättypen Mit Bluetooth API Mit Location API CLDC 1.0 / MIDP 1.0 163 3 0 CLDC 1.0 / MIDP 2.0 72 14 0 CLDC 1.1 / MIDP 1.0 0 0 0 CLDC 1.1 / MIDP 2.0 35 7 3 CDC / Personal Profile 2 2 0 Tabelle 3-4: Anzahl der Endgerättypen für J2ME Aus der Tabelle geht hervor, dass zurzeit die meisten Mobiltelefone CLDC 1.0/MIDP 1.0 unterstützen (163 Modelle), danach folgt CLDC 1.0/MIDP 2.0 (72 Modelle) und CLDC 1.1/MIDP 2.0 (35 Modelle). Ein Modell mit CLDC 1.1/MIDP 1.0 ist nicht in der Datenbank enthalten. Nur zwei Mobiltelefone (Nokia Communicator 9300 und 9500) unterstützen das für PDAs konzipierte CDC/Personal Profile. Die Bluetooth API wird ebenfalls nur von wenigen Geräten implementiert. Mit drei Geräten fällt die Unterstützung für die Location API auch recht mager aus. Wie im vorherigen Unterkapitel erwähnt, wird die Webservices API derzeit überhaupt nicht unterstützt. Weder Siemens, Sony Ericsson, noch 24 Kapitel 3: J2ME – Java-Plattform für mobile Geräte Motorola bieten Mobiltelefone mit dieser API an. Nokia will sogar eigene Standards definieren und definiert ein eigenes Webservices-Framework, welches in zukünftigen Nokiamodellen ausgeliefert wird. Aussagen zur Kompatibilität mit der Webservices API werden auf der Entwicklerseite von Nokia nicht getroffen. Persönlich halte ich Nokias Vorgehen für falsch, da die sowieso schon zersplitterte J2ME-Welt keine konkurrierenden Spezifikationen benötigt. Insgesamt betrachtet ist der J2ME-Entwickler mit einer sehr heterogenen Gerätelandschaft konfrontiert. Dabei besteht die Schwierigkeit, möglichst viele Geräte mit der gleichen Software ohne große Änderungen ansprechen zu können. 3.6 PersonalJava PersonalJava ist der Vorgänger von J2ME, genauer gesagt, der Vorgänger von CDC/Personal Profile. Es wird noch hier betrachtet, da PersonalJava von einigen aktuellen Mobiltelefonen noch unterstützt wird (z.B. Sony Ericsson P910i). Allerdings bietet Sun keinerlei Unterstützung für PersonalJava mehr an. Das geht soweit, dass die letzte Spezifikation (Version 1.2) nicht mehr von der Sun Webseite bezogen werden kann. PersonalJava basiert auf dem JDK 1.1 und wurde für PDAs und höherwertige Mobiltelefone konzipiert. Die Spezifikation Version 1.1 [@SUN98_PERSONALJAVA] definiert PersonalJava über die konkreten Unterschiede zum JDK 1.1: Packages, Klassen und Methoden des JDKs werden mit den Flags required, additional, optional, unsupported und modified markiert. PersonalJava unterstützt nicht die optionalen J2MEPakete, somit kann z.B. auch nicht die Bluetooth API mit PersonalJava angesprochen werden. Da Sun PersonalJava nicht mehr unterstützt, ist davon auszugehen, dass PersonalJava in den nächsten Jahren keine wichtige Rolle mehr spielen wird. 3.7 Blick über den Tellerrand: Alternative Plattformen Neben der J2ME-Plattform existieren weitere Plattformen für die Softwareentwicklung auf mobilen Geräten. Die wichtigsten sind Symbian OS von Symbian und das .net Compact Framework von Microsoft. Sie sind zwar für die Diplomarbeit nicht weiter von Relevanz, werden aber trotzdem als Gegenpol zu J2ME vorgestellt. 3.7.1 Symbian OS Symbian OS ist ein speziell für Mobiltelefone entwickeltes Betriebssystem. Zusätzlich zu der obligatorischen Unterstützung der Telephonieeigenschaften bietet Symbian OS ein Applikationsframework und „Personal Information Management“ (PIM) Funktionalität. PIM beschreibt die Verwaltung von persönlichen Daten wie Kontakte, Notizen und Kalendereinträgen. Die primäre Programmiersprache für Symbian OS ist C++. Da Symbian selbst in C++ geschrieben ist, kann der Anwendungsentwickler direkt auf die nativen APIs zugreifen, was einen Funktions- und Geschwindigkeitsvorteil gegenüber der J2ME-Plattform mit sich bringt. Diese Vorteile erkauft man sich aber mit Sicherheitsrisiken, denn die Applikationen laufen im Gegensatz zu Java nicht in einer eigenen Sandbox. Erste Trojaner sind bereits aufgetaucht (Siehe [@MOLITOR04]). Kapitel 3: J2ME – Java-Plattform für mobile Geräte 25 Das Symbian OS unterstützt die J2ME Plattform und wird mit CLDC/MIDP und neuerdings sogar CDC/Personal Profile Implementierungen (z.B. auf dem Nokia 9300 Communicator) ausgeliefert. Hersteller von Mobiltelefonen setzen Symbian hauptsächlich in Modellen im höheren Preissegment ein. Besonders Nokia stattet sehr viele Geräte mit Symbian OS aus. Die Hälfte der verfügbaren Modelle mit Symbian OS ist von Nokia (siehe auch http://www.symbian.com/phones/index.html). 3.7.2 .net Compact Framework Microsoft positioniert das .net Compact Framework als direkte Konkurrenz zum CDC/Personal Profile. Unterstützt werden Pocket PC 2002, Windows CE.NET und Smartphone 2003 (neuerdings Windows Mobile genannt). Das .net Compact Framework repräsentiert eine Teilmenge des .net Frameworks und bietet ebenfalls einen JIT Compiler. Die virtuelle Maschine von .net, die Common Language Runtime (CLR) wurde auf die Besonderheiten von mobilen Geräten abgestimmt. Wie in J2ME kann der Entwickler nur auf eine abgespeckte Klassenbibliothek zurückgreifen, allerdings steht es ihm offen, direkt auf Bibliotheken des Betriebssystems zuzugreifen. Bislang scheiterten die Versuche von Microsoft das Smartphone Betriebssystem erfolgreich auf dem Markt zu etablieren. Ende 2002 platzte ein Vertrag mit dem Mobiltelefonhersteller Sendo, der sich anschließend für das Symbian OS entschied ([@HEISE04_51000]). Die Mobilfunkbetreiber O2 und T-Mobile haben allerdings 2004 erste Mobiltelefone mit dem Smartphone 2003 Betriebssystem in ihr Sortiment aufgenommen. Ob das .net Compact Framework sich gegen CDC durchsetzen kann ist noch offen. 3.8 Zusammenfassung Dieses Kapitel hat die J2ME-Plattform und ihre Unterteilung in Konfiguration, Profil und optionalen Paketen vorgestellt. Dabei ist dem Leser die zersplitterte Struktur der J2ME-Plattform sowie die Verbreitung der einzelnen Implementierungen vermittelt worden. Darüber hinaus wurden zwei alternative Plattformen für die Softwareentwicklung auf mobilen Geräten vorgestellt. Das nächste Kapitel geht mehr ins Detail und vergleicht die beiden Konfiguration/Profil Kombinationen CLDC/MIDP und CDC/Personal Profile. 26 Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile 4 CLDC/MIDP im Vergleich mit CDC/Personal Profile CLDC/MIDP ist die gängige Konfiguration/Profil Kombination für Mobiltelefone. Für PDAs bietet sich CDC/Personal Profile an, da es die größtmögliche Funktionalität innerhalb der J2ME-Plattform spezifiziert. Dieses Unterkapitel verdeutlicht die Unterschiede zwischen CLDC/MIDP und CDC/Personal Profile und vergleicht die technischen Möglichkeiten und Einschränkungen in folgenden Bereichen: • • • • • • Virtuelle Maschine Applikationsmodell Installation von Applikationen Persistenzkonzepte GUI-Funktionalität und Grafikfähigkeiten Netzwerkanbindung Da sich CLDC/MIDP gegenüber CDC/Personal Profile wesentlich stärker von J2SE unterscheidet, wird verstärkt auf diese Kombination eingegangen. Ziel dieses Kapitels ist Hintergrundwissen zu vermitteln und somit den Leser auf die Vorstellung und Besprechung der mobilen Geogrid®-Version vorzubereiten. 4.1 Virtuelle Maschine Die KVM ist die Referenzimplementierung der von der CLDC geforderten virtuellen Maschine. Aufgrund der strikten Speicherrestriktionen und des fehlenden J2SESicherheitsmodells gelten gegenüber der Java Virtual Maschine folgende Einschränkungen: • • • • • • • • Kein JNI (Java Native Interface). Keine Finalizer. Eingeschränktes Errorhandling. Keine eigenen Classloader. Keine Fliesskomma-Unterstützung (nur CLDC 1.0). Keine Weak References (nur CLDC 1.0). Keine Threadgruppen und Daemon Threads. Keine Unterstützung für Reflection. CLDC 1.1 führt die Unterstützung für Flieskommazahlen und Weak References wieder ein, was den Speicherbedarf dieser Konfiguration erhöht. Java verlangt aus Sicherheitsgründen eine Verifikation der .class Dateien, dass heißt, es muss überprüft werden, ob der Bytecode gültig ist. Die standardmäßige Verifikation von .class Dateien, wie sie in der J2SE verwendet wird, verbraucht allerdings viel Speicher. Von daher wurde für CLDC ein alternativer Ansatz zur Verifikation konzipiert: Methoden in .class Dateien enthalten ein zusätzliches Stack-Map Attribut, welches die Verifikation auf der KVM vereinfacht. Ein Stack-Map Attribut beschreibt die Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile 27 die möglichen Zustände des Stacks und der lokalen Variablen nach der Ausführung der Methode. Dieses Verfahren benötigt zum einen weniger Bytecode innerhalb der Virtuellen Maschine und zum anderen weniger Speicher im Verifizierungsprozess. Abbildung 4-1 zeigt den Ablauf der Verifikation. Die Klasse wird auf dem Entwicklungsrechner mit dem J2SE-Compiler kompiliert, anschließend prüft der pre-verifier, ob der Bytecode für CLDC zulässig ist und fügt anschließend die zusätzlichen Stack-Map Attribute in die .class Dateien ein. Auf dem mobilen Gerät werden diese Attribute bei der Verifikation ausgewertet. Entwicklungsrechner MyApp.java Mobiles Gerät (KVM) download javac verifier MyApp.class interpreter preverifier MyApp.class Abbildung 4-1: Pre-Verifikation von Class Dateien für die KVM (nach [@SUN00_KVM_WP]) Es hat sich jedoch herausgestellt, dass dieses Verfahren ein Angriffspunkt zum Aushebeln der Java Sandbox bietet. Der polnische Sicherheitsexperte Adam Gowdiak konnte über die Stack-Map Attribute die Sandbox umgehen und direkt auf native Methoden des Betriebssystems zugreifen (siehe [GOWDIAK04]). Sun hat in der aktuellen Referenzimplementierung die Sicherheitslücke bereits gestopft, viele davor ausgelieferte Mobiltelefone sind aber von dieser Sicherheitslücke betroffen. Sun hat die KVM auf Plattformunabhängigkeit und Portabilität optimiert, ein Just-InTime Compiler war nicht vorgesehen. Dieser wurde erst mit der Monty VM eingeführt, die die ursprüngliche KVM ersetzt. Erstmalig vorgestellt auf der Java One Konferenz 2002, führt die Monty VM bedeutende Änderungen unter anderem in der Garbage Collection, im Threading-Mechanismus und Ressourcen-Management ein. Im Gegensatz zur KVM beschränkt die Monty VM nicht mehr die Anzahl der geladenen Klassen und der Objekte auf dem Heap. Einzig der verfügbare Speicher setzt der Anzahl der Klassen und Objekte Grenzen. 28 Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile Die Gerätehersteller setzten mittlerweile in ihren aktuellen Mobiltelefonen hauptsächlich die Monty VM ein. Weitere Informationen zur Monty VM sind dem Whitepaper [@SUN02_PROJECT_MONTY] zu entnehmen. 4.2 Applikationsmodelle: MIDlets und Xlets Applikationsmodelle legen fest in welcher Form Applikationen vom Betriebssystem aufgerufen und verwaltet werden. Ein sehr einfaches Applikationsmodell ist in der J2SE definiert: Als Einstiegspunkt dient die statische main() Methode. Einmal gestartet kontrolliert eine J2SE Applikation ihren Lebenszyklus selbst. MIDP erlaubt nur verwaltete Applikationen: die so genannten MIDlets, deren Lebenszyklus vom Betriebssystem kontrolliert werden. MIDlets werden ähnlich wie Applets von einer abstrakten Basisklasse abgeleitet. Die abstrakte MIDlet Klasse enthält Methoden, die beim Starten, Pausieren und Beenden der Applikation von der Application Management Software (AMS) aufgerufen werden. Das AMS kontrolliert den Lebenszyklus der installierten MIDlets und ist in jedem MIDP-fähigen Gerät vorhanden. Ein MIDlet kann sich in dem Zustand active, paused und destroyed befinden. Im Gegensatz zum MIDP unterstützt das Personal Profile drei Applikationsmodelle: • Eigenständige Applikation mit einer main() Methode (übernommen vom J2SE). • Applet Modell (übernommen vom J2SE). • Xlet Modell. Das Xlet Modell ist in zwei Teile aufgeteilt: Xlet Manager und Xlets. Xlets sind Klassen, die das Xlet Interface implementieren. Im Gegensatz zu Applets sind Xlets nicht mehr vom AWT abhängig. Gestartet und verwaltet werden Xlets vom Xlet Manager, der auch ihren Lebenszyklus kontrolliert. Dieser umfasst vier Zustände (loaded, active, paused und destroyed) und unterscheidet sich somit vom AppletLebenszyklus. Der Vorteil von Xlets und MIDlets gegenüber einer eigenständigen Applikation ist, dass mehrere verwaltete Applikationen gleichzeitig in einer virtuellen Maschine laufen können. Zudem können die verwalteten Applikationen untereinander kommunizieren. Das Personal Profile sieht sogar eine „Inter-Xlet Communication“ vor. 4.3 Installation von MIDlets und Xlets Einzelne MIDlets können nicht installiert werden. Dazu ist eine MIDlet-Suite erforderlich, die ein oder mehrere MIDlets umfasst. Abbildung 4-2 illustriert den Aufbau einer MIDlet-Suite. Als .jar Datei gepackt enthält sie neben den .class Dateien ein beschreibendes Manifest. Zusätzlich können weitere Ressourcen integriert werden (Bilder, Texte, usw.). Anhand von Attributen beschreibt das Manifest unter anderem die enthaltenen MIDlets, den Hersteller (Vendor) und die Vorraussetzung zum Installieren der MIDlets (also welche Konfiguration- und Profilversion erwartet werden). Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile MIDlet-Suite Manifest-Version: 1.0 MIDlet-1: MobileJavaMap, MobileJavaMapMIDlet MIDlet-Vendor: EADS MIDlet-Version: 1.0 MIDlet-Name: MobileJavaMap MicroEdition-Configuration: CLDC-1.1 MicroEdition-Profile: MIDP-2.0 29 Applikationsdeskriptor MIDlet-1: MobileJavaMap, MobileJavaMapMIDlet MIDlet-Jar-Size: 388281 MIDlet-Jar-URL: MobileJavaMap.jar MIDlet-Name: MobileJavaMap MIDlet-Vendor: EADS MIDlet-Version: 1.0 MicroEdition-Configuration: CLDC-1.1 MicroEdition-Profile: MIDP-2.0 .jad Datei Manifest .class Dateien Ressourcen .jar Datei Abbildung 4-2: MIDlet-Suite und Applikationsdeskriptor Der Applikationsdeskriptor in Form einer separaten .jad Datei enthält die gleichen Attribute mit identischen Werten, fügt aber noch die URL zum Laden der .jar Datei und deren Größe hinzu. Der Grund für einen separaten Applikationsdeskriptor ist, dass das mobile Gerät zunächst den Applikationsdeskriptor herunterladen kann, um zu entscheiden ob die MIDlet-Suite überhaupt für das Gerät geeignet ist. Dieses Verfahren wird als Over-the-Air Provisioning bezeichnet. Das Gerät lädt die .jad Datei, anschließend die .jar Datei und gibt nach erfolgreichen Download eine Rückmeldung an den Server zurück. Viele Mobiltelefone erlauben einen direkten Zugriff auf das Dateisystem über Bluetooth, Infrarot oder Datenkabel. In diesem Fall reicht das Kopieren der .jar Datei in den für MIDlets vorgesehenen Ordner. Dieser Ordner ist vom Mobiltelefonhersteller festgelegt und variiert von Modell zu Modell. Die Installation von Xlets dagegen ist abhängig vom implementierten Xlets Manager. Die Referenzimplementierung von Sun liefert eine einfache Starterklasse für Xlets mit, die als Argumente den Namen und den Pfad des Xlets erwartet. Die CDC-Spezifikation spezifiziert kein Format für Manifestdateien. Das ist dem Hersteller einer CDC Virtual Maschine überlassen. 4.4 Persistenzkonzepte CLDC/MIDP definiert keinen direkten Zugriff auf das Dateisystem des mobilen Gerätes. Der Entwickler kann nur auf die in der MIDlet-Suite mitgelieferten Ressourcen zurückgreifen. Dieser Zugriff ist nur in Form eines InputStreams möglich, eine Art RandomAccessFile Klasse existiert nicht. Das optionale Paket FileConnection API füllt zwar die Lücke, aber wird nur von den wenigsten Geräten unterstützt (3 Modelle laut Device Database der J2ME Polish Website [@J2MEPOLISH05]). 30 Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile Damit MIDlets dennoch Daten persistieren können, konzipiert MIDP das Record Management System kurz RMS, das die Persistierung von Daten in satzorientierten Datenbanken erlaubt. Einige Hersteller wie Siemens bieten eigene, nicht standardisierte Klassen zum Zugriff auf das Dateisystem an. Auf diese wird mangels Plattformunabhängigkeit nicht weiter eingegangen. Eine Datenbank im RMS wird als RecordStore bezeichnet und verwaltet eine Menge von Datensätzen (Record), die mit einer eindeutigen ID bestimmt werden. Über die gleichnamige Klasse RecordStore kann ein MIDlet mehrere RecordStores anlegen und verwalten. Abbildung 4-3 zeigt schematisch den Aufbau eines solchen RecordStores. Jeder Record enthält ein Bytefeld mit variabler Länge. Es ist die Aufgabe des Entwicklers die abzuspeichernden Daten in ein Bytefeld umzuwandeln und umgekehrt das Bytefeld beim Laden zu deserialisieren. Neben dem direkten Zugriff auf die einzelnen Records via ID steht dem Entwickler auch die sequentielle Verarbeitung offen. Die Reihenfolge der Aufzählung ist nicht definiert, bei Bedarf kann sie aber mit einer Klasse, die das RecordComparator Interface implementiert, bestimmt werden. Allerdings kostet die Verwendung eines RecordComparators Zeit, da die Klasse jeden Record auswerten muss. Ein gefüllter RecordStore kann nicht mit einer MIDlet-Suite mitgeliefert werden, die MIDlets müssen den RecordStore zur Laufzeit selbst erstellen und mit Daten füllen. id record 1 2 3 Abbildung 4-3: RecordStore (Beispiel) MIDP legt fest, dass für das RMS mindestens 8 KB Speicher zur Verfügung stehen muß. Viele Mobiltelefone erlauben aber weitaus mehr. So kann das K700i von Sony Ericsson den kompletten freien Speicher(40 MB!) für das RMS zur Verfügung stellen. Das RMS steht dem Personal Profile nicht zur Verfügung. Hier hat der Entwickler, wie in J2SE, direkten Zugriff auf das Dateisystem und kann bei Bedarf das JDBC Optional Package installieren, das eine Teilmenge des java.sql und javax.sql Package repräsentiert. 4.5 Benutzeroberfläche und Grafikfähigkeiten Die im Vergleich zu Desktopmonitoren winzigen Displays der Mobiltelefone lassen keine komplexe GUI zu. Deshalb spezifiziert MIDP ein GUI-Framework, welches auch auf kleineren Displays sinnvoll eingesetzt werden kann. Das LCDUI (Lowest Common Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile 31 Denominator User Interface) beschränkt sich auf den „kleinsten gemeinsamen Nenner“ von GUI-Oberflächen, so dass möglichst viele Geräte angesprochen werden können. Die nächsten Unterkapitel stellen die High-Level und die Low-Level API des LCDUIFrameworks vor. Das Klassendiagramm in Abbildung 4-4 dient als Übersicht über die nachfolgend besprochenen Klassen. Abbildung 4-4: LCDUI Komponenten 4.5.1 LCDUI High-Level API Formulare, Textfelder und Listen können sehr einfach mit der High-Level API realisiert werden, dabei ist das Aussehen von Gerät zu Gerät unterschiedlich, denn es werden die nativen GUI-Elemente des Betriebssystems abstrahiert. MIDlets haben keinen Einfluss auf Schriftfarbe, -form und -typ. Abbildung 4-5 zeigt die Kartenauswahl in der später vorgestellten mobilen Geogrid®-Version auf dem Sony Ericsson K700i (links) und dem Siemens S65 (rechts). Neben dem unterschiedlichen Schriftbild und Hintergrund sind auch die Tasten anders belegt. Der Code für beide Versionen ist identisch. Abbildung 4-5: Kartenauswahl auf SE K700i und Siemens S65 Alle UI-Komponenten leiten von der abstrakten Klasse Displayable ab, die unter anderem Methoden zur An- und Abmeldung von Aktionen definiert. Basisklasse für High-Level-LCDUI Komponenten wie List oder Form bildet die abstrakte Screen Klasse, die von Displayable erbt. 32 Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile Eine Aktion wird durch ein Command Objekt repräsentiert, das den Namen der Aktion, eine optionale Beschreibung, den Typ der Aktion (z.B. EXIT oder BACK) und eine Prioritätsangabe enthält. Displayable Objekte können mehrere Command Objekte enthalten, die Darstellung und Anordnung auf dem Display bestimmt dabei die MIDPImplementierung des mobilen Geräts. Trotz des gleichlautenden Namens implementiert die Command Klasse nicht das Command („Befehl“) Pattern (siehe [GAMMA96]). Das Verhalten der Aktion ist also nicht in dem Command Objekt gekapselt, sondern in dem zum Displayable Objekt zugeordneten CommandListener. Wählt der Anwender eine bestimmte Aktion aus, so wird die commandAction Methode des entsprechenden CommandListeners aufgerufen. Da für mehrere Aktionen dasselbe CommandListener Objekt verantwortlich ist, wird der commandAction Methode u.a. die Referenz des Command Objekts mitgegeben, damit bestimmt werden kann, welcher Command für den Aufruf verantwortlich war. 4.5.2 LCDUI Low-Level API Die LCDUI Low-Level API stellt dem Entwickler die abstrakte Canvas Klasse zur Verfügung, die unter anderem Methoden zur Ereignisverarbeitung anbietet. Canvas leitet von der Displayable Klasse ab. Zu den möglichen Ereignissen zählt ein Tastendruck oder die Betätigung eines ggf. vorhandenen Touchscreens. Die Displaygröße und Farbtiefe des mobilen Gerätes kann ermittelt werden, so dass ein sauber programmiertes MIDlet sich flexibel an die Umgebung anpassen kann. MIDP 2.0 erlaubt im Gegensatz zur Vorgängerversion die Verwendung der kompletten Displaygröße. Gezeichnet wird ein Canvas mit dem Aufruf der abstrakten Methode paint(Graphics g). Dass übergebene Graphics Objekt ermöglicht das Zeichnen von Text, Bildern und geometrischen Formen auf der Fläche des Canvas. Der direkte Zugriff auf die Pixel ist nicht vorgesehen. Im einfachsten Fall leitet der Entwickler von der Canvas Klasse ab und überschreibt neben der obligatorischen paint Methode bei Bedarf auch die Ereignismethoden wie keyPressed, die zwar nicht abstrakt sind, aber in der Oberklasse nur über einen leeren Methodenrumpf verfügen. Bilder können mittels der Image Klasse dargestellt werden, allerdings wird nur die Unterstützung des PNG-Formates garantiert, andere Formate sind optional. Image Objekte können aber auch aus RGB-Feldern erzeugt werden, dabei werden pro Pixel 32 Bit (24 Bit für RGB + 8 Bit für Transparenz) verbraucht. 4.5.3 MIDP Game API MIDP 2.0 führt die auf der Low-Level API basierende Game API ein, die Klassen gezielt für 2D-Videospiele spezifiziert. Dazu gehört auch die von Canvas abgeleitete GameCanvas Klasse, die zusätzlich das Double Buffering Verfahren einsetzt. Bei diesem Verfahren wird der Bildschirminhalt zuerst in einen Puffer gezeichnet und anschließend auf das Display kopiert. Da nicht mehr direkt auf dem Displayinhalt gezeichnet wird, entfällt auch mögliches Flackern. Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile 33 Zusätzlich bietet die Game API auch ein Schichtenkonzept, das die Verwaltung von mehreren so genannten Layern abstrahiert. Ein Layer befindet sich in einem Koordinatensystem und repräsentiert ein visuelles rechteckiges Element mit definierter Breite und Höhe. Die linke obere Ecke des Layers legt seine Position fest. Abbildung 4-6: LayerManager und Layer Layer werden von der abstrakten Layer Klasse abgeleitet und müssen die abstrakte paint Methode überschreiben. Verwaltet werden die Layer Objekte von einer Instanz der LayerManager Klasse, die die Ordnung der Layer festlegt und die paint Methode aller verwalteten Layer Objekte aufruft. In den Verantwortungsbereich des LayerManagers fällt auch das ViewWindow, welches den sichtbaren Ausschnitt der „Spielwelt“ definiert. Die Spielwelt ist üblicherweise größer als die Displaygröße. Von daher werden beim Zeichnen die Koordinaten der Spielwelt auf die Koordinaten des Displays transformiert. Um Rechenleistung einzusparen, wird nur der gerade sichtbare Bereich gezeichnet. Durch schrittweises Verschieben des ViewWindows lässt sich sehr einfach ein Scrollingeffekt erzielen. Abbildung 4-7 zeigt eine „Spielwelt“ mit drei Layer, die sich an unterschiedlichen Positionen befinden. Layer 2 ist in der Ordnung höher als Layer 3. Layer 1 und 3 werden nur teilweise auf dem Display dargestellt, da das ViewWindow (gestrichelte Linie) sie nicht ganz umschließt. Beim Zeichnen werden die Koordinaten der Layer relativ zum ViewWindow transformiert. 34 Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile x y Mobiltelefon (0/0) (140/40) (20/80) 1. (260/200) (120/160) (180/240) 2. (40/200) 3. Abbildung 4-7: Layerkonzept der Game-API MIDP 2.0 liefert zwei Implementierungen der abstrakten Layer Klasse mit: die Sprite Klasse und die TiledLayer Klasse. Im Folgenden wird nur auf letztere eingegangen. Die TiledLayer Klasse ermöglicht den Aufbau einer Spielwelt mit einzelnen Kacheln, die alle in einem einzigen Bild gespeichert werden. Jede Kachel besitzt dabei die dieselbe Breite und Höhe. Abbildung 4-8 demonstriert das Verfahren: 1. Das TiledLayer Objekt wird mit einem Bild und der Kachelgröße initialisiert. 2. Ein Integerfeld bestimmt die Anordnung der Kacheln. Soll keine Kachel auf einer Position verwendet werden, so wird das mit der 0 gekennzeichnet. 3. Beim Zeichnen wird das Integerfeld durchlaufen und die Kacheln entsprechend der Nummerierung gezeichnet. 1. Bild mit Kacheln. 1 2 3 4 5 2. Integerfeld bestimmt Anordnung der Kacheln. 6 7 8 3. Gekachelte Spielwelt Abbildung 4-8: Verwendung des TiledLayer (Bilder entnommen aus [@SUN02_MIDP_20]) Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile 35 Eigene Layers können nicht implementiert werden, da der Konstruktor der abstrakten Layer Klasse nur in dem Package javax.microedition.lcdui.game sichtbar ist. 4.5.4 CDC AWT CDC/Personal Profile bietet mit dem AWT (Abstract Window Toolkit) gegenüber dem LCDUI eine wesentlich mächtigere GUI- und 2D-Render Funktionalität. Allerdings unterscheidet sich das Personal Profile java.awt Package von der Version aus dem JDK 1.3. Nicht alle Methoden und Klassen wurden übernommen, teilweise wurde auch Funktionalität in andere Klassen transferiert. Beispiel dafür ist die Graphics2D Klasse: Im JDK 1.3 erweitert sie die Graphics Klasse um Methoden zur anspruchsvollen Bildverarbeitung. Dagegen definiert die Personal Profile Version nur drei Methoden. Einige der Methoden der JDK Graphics2D Klasse sind in die Graphics Klasse des Personal Profiles gewandert, andere wurden weggelassen. 4.6 Netzwerkverbindung J2SE sieht für Netzwerkverbindungen das java.net Package vor. Dieses hauptsächlich klassenorientierte Package wurde aufgrund des Speicherbedarfs nicht in CLDC übernommen. Stattdessen wurde das Generic Connection Framework (kurz GCF) spezifiziert; eine API die im Gegensatz zum java.net Package stark auf Interfaces setzt. Somit bleibt die Implementierung dem Hersteller des mobilen Gerätes überlassen. Das GCF befindet sich in dem Package javax.microedition.io. Die Interfacehierarchie ist flexibel erweiterbar, so dass auch zusätzliche Protokolle konsistent in das Framework eingebaut werden können. Lediglich die beiden Protokolle HTTP (Hypertext Transfer Protocol) und HTTPS (Hypertext Transfer Protocol Secure) müssen in MIDP 2.0-kompatiblen Geräten implementiert werden, weitere Protokolle sind optional. Eine Connection Fabrik (Connector Klasse) kümmert sich um das Instanzieren der Connections. Der erforderliche Typ wird über den mit übergebenen URL-String festgelegt. Das GCF ist ebenfalls in der CDC-Spezifikation enthalten. Somit können CDCApplikationen sowohl auf java.net als auch auf das GCF zurückgreifen. Das ist durchaus sinnvoll, denn einige optionale Pakete wie die Bluetooth API setzen das GCF voraus. 4.7 Wireless Toolkit Um die CLDC/MIDP Entwicklung zu vereinfachen, hat Sun das kostenlose Wireless Toolkit entwickelt, das verschiedene mobile Gerätetypen emuliert. Die Geschwindigkeit der CPU und Netzwerkverbindungen, der verfügbare Speicher für Heap und RecordStores sowie weitere Eigenschaften des emulierten Gerätes kann eingestellt werden, um das Verhalten der Applikation unter unterschiedlichen Bedingungen zu testen. Auch Ereignisse wie ein Telefonanruf oder Empfang einer SMS können simuliert werden. Für eine schnellere Entwicklungszeit sorgt auch die integrierte Unterstützung für den Buildpro- 36 Kapitel 4: CLDC/MIDP im Vergleich mit CDC/Personal Profile zess, der Preverification und Obfuscation umfasst. Preverification wurde bereits im Kapitel 4.1 erläutert. Obfuscation (engl. für „Verschleierung“) ist der Begriff für die Umbenennung der Klassen- und Methodennamen mit dem Ziel das Reengineering zu erschweren und gleichzeitig die Größe der kompilierten Klasse zu minimieren. Wie groß die Platzersparnis durch Obfuscation sein kann zeigt folgendes Beispiel: MobileJavaMap (der später vorgestellte Prototyp einer mobilen Geogrid®-Version) ist ohne Obfuscation 216 KB groß. Mit aktivierter Obfuscution benötigt die .jar Datei nur 111 KB. In mehreren IDEs kann das Wireless Toolkit integriert werden, um unnötige Kontextwechsel zu vermeiden. Abbildung 4-9 zeigt das Toolkit in Zusammenarbeit mit Netbeans 4.0. Die Integration erfolgt nahtlos, alle Funktionen und Optionseinstellungen können innerhalb der IDE angesprochen werden. Abbildung 4-9: Wireless Toolkit Integration in Netbeans 4.0 4.8 Zusammenfassung In diesem Kapitel wurden dem Leser die Besonderheiten und die Unterschiede der beiden Konfiguration/Profil Kombinationen vermittelt. Die Untersuchung der einzelnen Aspekte hat gezeigt, dass sich CLDC/MIDP gegenüber CDC/Personal Profile wesentlich stärker von der J2SE unterscheidet. Die Migration einer J2SE-Applikation auf eine CLDC/MIDP Laufzeitumgebung erfordert also wesentlich mehr Migrationsaufwand als für eine CDC/Personal Profile Laufzeitumgebung. Für beide Konfiguration/Profil Kombinationen gilt: Bei einer Migration von einer J2SE-Applikation kann die volle Funktionalitätsübernahme nicht garantiert werden. Allerdings ist die Wahrscheinlichkeit von Funktionalitätseinbußen auf einer CLDC/MIDP Laufzeitumgebung wesentlich höher. Dieses Vorwissen ist für das Verständnis des Kapitels 7 wichtig, in dem der Prototyp einer Geogrid®-Version mit CLDC/MIDP vorgestellt wird. Das nächste Kapitel spezifiziert die Anforderungen an eine mobile Geogrid®-Version. Kapitel 5: 5 Anforderungen an eine mobile Geogrid®-Version 37 Anforderungen an eine mobile Geogrid®-Version Zunächst stellt dieses Kapitel zwei bereits existierende Produkte zur Kartendarstellung auf mobilen Geräten vor und definiert anschließend die Anforderungen an eine mobile Geogrid®-Version bezüglich der Karten, ihrer Darstellung und den Overlays. Darüber hinaus werden Anforderungen an das Cachen der heruntergeladenen Informationen und an die GPS-Unterstützung gestellt. 5.1 Bereits existierende Kartensoftware für mobile Geräte Die auf dem Markt befindlichen Produkte lassen sich in zwei Kategorien einteilen: Lösungen für PDAs und Lösungen für Mobiltelefone. Ein weiteres Kriterium ist die Form des unterstützten Kartenmaterials. Es gibt vektor- und rasterbasierte Karten. Vektorbasierte Karten bilden die Grundlage für Routenberechnungen in einem Navigationssystem. Mit rasterbasierten Karten ist eine Routenberechnung dagegen nicht möglich, da die Karte quasi nur ein Bild darstellt. Da das KMRG- und MAPS-Format rasterbasiert sind, wird im Folgenden auf eine Betrachtung von vektorbasierten Lösungen verzichtet. Besonders interessant für die Spezifikation der Anforderungen wäre natürlich ein rasterbasiertes J2ME-Produkt. Allerdings gibt es so etwas noch nicht auf dem Markt. Um aber dennoch die potentiellen Möglichkeiten aufzuzeigen, werden zwei Produkte auf dem Markt vorgestellt: OziExplorerCE und Benefon ESC!. Der OziExplorerCE von Des Newman läuft auf PocketPC-PDAs und stellt Rasterdaten dar, die in einem eigenem Format vorliegen müssen. Die obligatorischen Konvertierungstools, die Rasterdaten von anderen Formaten in das OziExplorerCE Format konvertieren, werden mitgeliefert. Die darzustellenden Karten müssen auf den PDA kopiert werden, der Empfang von Karten über das Internet ist nicht möglich. Eine Zoomfunktion erlaubt das Vergrößern und Verkleinern der Karte bis zu einem bestimmten Prozentsatz. Die aktuelle Position kann OziExplorerCE über einen angeschlossenen GPSEmpfänger ermitteln. Allerdings werden die neueren Bluetooth Modelle nicht unterstützt. Aufgezeichnete Positionsdaten können zu einem so genannten Track zusammengefasst und dargestellt werden. Benefon ESC! kombiniert Mobiltelefon und GPS-Empfänger. Das monochrome Display ist für heutige Verhältnisse mit 100 x 160 Pixel eher unspektakulär. Die installierte Kartensoftware stellt Karten ebenfalls in einem eigenen Kartenformat dar. Der Anwender kann kostenpflichtig Karten über den Kartendienst Genimap auf den PC runterladen und auf das Mobiltelefon übertragen. Selbsteingescannte Karten können über ein PC-Tool georeferenziert werden. Erwähnenswert ist noch die Unterstützung für Point Of Interests. Ein „Point Of Interest“ (kurz POI) ist eine Position auf der Karte, die für den Betrachter von Interesse sein kann, z.B. ein Hotel oder eine Tankstelle. Das Benefon ESC! verschickt auf Wunsch eine SMS mit der aktuellen Position an ein Service Center, das wiederum in der nähe liegende POIs (kodiert in einer Antwort-SMS) zurückschickt. 38 5.2 Kapitel 5: Anforderungen an eine mobile Geogrid®-Version Übersicht Die nachfolgende Tabelle listet die Anforderungen an eine mobile Geogrid®-Version mit J2ME auf. Dabei werden die einzelnen Bereiche nach Muss-, Kann- und Wunschkriterien unterteilt. Musskriterien Karten Unterstützung KMRG-Karten. Kannkriterien für Unterstützung MAPS-Karten. Wunschkriterien für • • • • • Projektionen Alle Projektionen, die auch von JavaMap unterstützt werden. Overlay • • • • Verwaltung von mehreren grafischen Ebenen. Herunterladen von Overlays und POIs. Unterstützung von mindestens eines der in den Kannkriterien enthaltenen Overlayformate. Setzen von Referenzpunkten. • • • Binär ASCII XML • Caching • Positionsermittlung • • Positionsermittlung mit einem der im Kannblock enthaltenen Verfahren. Zentrieren der Karte auf die aktuelle Position. • • Direkte Speicherung der Karten auf dem Gerät. Darstellung im Vollbildmodus. Zoomen von Karten. Weiches Scrolling. Unterstützung von Höhendaten. Positionsbestimmung über Bluetooth-GPSEmpfänger. Positionsbestimmung über Location API. Tabelle 5-1: Anforderungen • • Caching der heruntergeladenen Kartendaten. Caching der heruntergeladenen Overlays. Aufzeichnung der ermittelten Positionen. Auswertung weiterer Informationen wie Bewegungsrichtung, usw. Kapitel 5: 5.3 Anforderungen an eine mobile Geogrid®-Version 39 Karten Die mobile Geogrid®-Version muss KMRG-Karten anzeigen können. Optional dagegen ist die Unterstützung für das MAPS-Format. Wenn möglich, sollten die Karten direkt auf dem Gerät gespeichert werden, eine Alternative dazu wäre der Empfang der Kartendaten über das Internet. Des Weiteren müssen alle Projektionen unterstützt werden, die auch von JavaMap unterstützt werden. Aufgrund der eingeschränkten Displaygröße müssen in der Darstellung einschneidende Einschränkungen in Kauf genommen werden. Um den verfügbaren Platz optimal auszunutzen, sollte die Kartendarstellung im Vollbildmodus erfolgen. Das Verschieben des Kartenausschnitts sollte ruckelfrei erfolgen, also ist ein weicher Scrollingmechanismus erforderlich. 5.4 Overlay Die Overlayfähigkeit muss gewährleistet sein, das bedeutet die Software muss in der Lage sein, mehrere grafische Ebenen zu verwalten. Es ist zu evaluieren, welches Overlayformat (Binär, ASCII oder XML-Variante) eingesetzt werden soll. Overlays müssen aber auf jeden Fall über das Internet herunterladbar sein, um dem Anwender „Point Of Interests“ in seiner unmittelbaren Umgebung anbieten zu können. Die Reihenfolge der Darstellung, also die Priorität der Overlays sollte der Anwender ändern können. Eine weitere Anforderung ist das Setzen von Referenzpunkten, die auch nach einem Maßstabwechsel bestehen bleiben. 5.5 Caching von heruntergeladenen Informationen Datenverbindungen über GPRS sind sehr teuer und langsam, von daher wäre es wünschenswert, wenn bereits heruntergeladene Kartendaten und POIs gecached werden können. Dabei sollte der Cache auf eine fixe Größe beschränkt bleiben. Bei einem vollen Cache müssen bei einem Neuzugang die am wenigsten verwendeten Cacheeinträge gelöscht werden. 5.6 Positionsermittlung Wie wir bereits in Kapitel 3.4.2 erfahren haben, gibt es mehrere Verfahren zur Positionsermittlung. Die mobile Geogrid®-Version muss mindestens eine davon unterstützen. Wenn möglich, sollten auch andere Informationen wie Bewegungsrichtung oder Anzahl der Satelliten dargestellt werden. Optional ist auch das Aufzeichnen von mehreren Positionsangaben, um später die Bewegung nachvollziehen zu können. 40 Kapitel 6: Kartenserver 6 Kartenserver Der Kartenserver ist nicht das Kernthema dieser Diplomarbeit, dennoch ist die Konzeption und Implementierung notwendig, um die mobile Geogrid®-Version zu testen und zu demonstrieren. Deshalb gehe ich auf die Funktionalität und den Aufbau des Prototyps ein und werde grundlegende Designentscheidungen kommentieren bzw. begründen. 6.1 Funktionalität des implementierten Prototypen Die später vorgestellte mobile Geogrid®-Version (künftig MobileJavaMap genannt) bezieht die Kartendaten über das Internet. Dazu ist ein spezieller Kartenserver notwendig, der den gewünschten Kartenausschnitt via HTTP auf das Mobiltelefon schickt. Für die Verwendung des HTTP-Protokolls sprechen mehrere Gründe: HTTP-Verbindungen werden im Gegensatz zu anderen Socketverbindungen von vielen Firewalls nicht blockiert. Hinzu kommt dass die Übergabe von Requestparametern (Anfrageparameter) mit dem Common Gateway Interface (CGI) für HTTP standardisiert ist. Der wichtigste Grund aber ist, dass MIDP 2.0 fähige Mobiltelefone oftmals nur HTTP und HTTPS (HTTP mit SSL Verschlüsselung) unterstützen. Die Socketprogrammierung ist dagegen optional. Der Kartenserver bietet über HTTP Zugriff auf KMRG-Karten, das zivile MAPSFormat wird derzeit nicht unterstützt. Er ist so konzipiert und implementiert, dass sowohl JavaMap als auch MobileJavaMap über HTTP-Requests Karten vom Server laden können. Darüber hinaus erlaubt er das Anzeigen von Kartenausschnitten im JPEG- und PNG-Format mit einem Internetbrowser. Abbildung 6-1 illustriert die beschriebenen Einsatzmöglichkeiten des Kartenservers. Die möglichen Requests werden im nächsten Unterkapitel vorgestellt. Internet Browser MobileJavaMap Kartenserver JavaMap Abbildung 6-1: Kartenserver kommuniziert mit mehreren Applikationen Kapitel 6: 6.2 Kartenserver 41 Implementierte Requests [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 6.3 Struts Webframework Der Kartenserver verwendet das Apache Struts Framework in der Version 1.2. Das als Open-Source freigegebene Framework setzt auf Standardtechnologien wie Servlets, JavaBeans und XML und erleichtert die Entwicklung von MVC (Model View Controller) Webapplikationen. Prinzipiell hätte auch ein anderes Java Web Framework z.B. Apache Turbine eingesetzt werden können. Struts ist aber mittlerweile der De-factoStandard für Java Webapplikationen: SAP und BEA verwenden beispielsweise modifizierte Versionen von Struts in ihren Produkten (SAP Portals und BEA WebLogic). Zudem konnte ich meine bisherige Struts-Erfahrung in den Prototypen mit einbringen. 6.3.1 Überblick Kern des Struts Frameworks ist die Controller Komponente, die mit unterschiedlichen Modell- und View Komponenten zusammenarbeiten kann. Die von Struts vorgesehene Architektur entspricht dem Model-2-Ansatz, eine Variante des Model View Controller Entwurfmusters für den Einsatz auf Webservern. In einer Model-2 Architektur (siehe Abbildung 6-2) agiert ein Servlet als Controller und nimmt alle ankommenden Requests entgegen (1) und verteilt sie auf die verarbeitenden Klassen. Diese werten die Requestparameter aus und greifen auf Modellkomponenten zu (2), die entsprechende Ergebnisobjekte generieren und zurückgeben. Anschließend leitet das Servlet zur Viewkomponente weiter (3). Häufig kommen JSP (Java Server Pages) zum Einsatz, sie greifen auf die Ergebnisobjekte (4) zu, erstellen dynamische Antwortseiten und schicken sie an den Client (5). Request 1. Servlet 2. Controller 3. Response 5. JSP, XSLT 4. View Client Model Server Persistenzschicht Abbildung 6-2: JSP Model-2 Architektur Für JSP-Programmierung liefert Struts eine Taglibrary mit, die unter anderem HTML Tags und Zugriff auf JavaBeans und Collections kapselt. Eine Taglibrary ist eine Bibliothek, die über XML-Tags angesprochen werden kann. Neben JSPs unterstützt Struts auch andere Viewtechnologien, wie XSLT (Extensible Stylesheet Language Transformations) oder Java Server Faces. Struts definiert kein eigenes Komponentenmodell für 42 Kapitel 6: Kartenserver Geschäftsobjekte, sondern schlägt den Einsatz von JavaBeans bzw. Enterprise JavaBeans vor. 6.3.2 Controller Komponente [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 6.3.3 Konfiguration [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 6.4 Technische Voraussetzungen [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 6.5 Architekturübersicht [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 6.5.1 Modellschicht [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 6.5.2 Controllerschicht [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 6.5.3 Viewschicht [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 6.6 6.6.1 Implementierungsdetails Zuordnung von Kartenname und MapID [Kapitel aufgrund sensibler Unternehmensdaten entfernt.]. 6.6.2 Packagestruktur [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] Kapitel 6: 6.6.3 Kartenserver 43 Logging Die Entwicklung von Webapplikationen erfordert den Einsatz eines Loggingframeworks, da das Debuggen gegenüber eigenständigen Applikationen erschwert ist. Der Struts User Guide [@APACHE04_STRUTS] schlägt den Einsatz des Jakarta Common Logging Package vor, dass unterschiedliche Loggingframeworks wie Log4J und das im JDK 1.4 enthaltene java.util.logging kapselt. Es sprechen aber einige Gründe gegen den Einsatz des Common Loggings, die in dem Artikel des Log4J Entwicklers Gülcu [GÜLCÜ02] erläutert werden. Gefährlich ist vor allem die Tatsache, dass Common Logging automatisch nach bereits geladenen Loggingframeworks sucht. Das kann in bestimmten Situationen zu Classloader-Problemen führen, die schwer nachvollziehbar sind. Von daher wurde bei der Implementierung des Kartenservers auf das Common Logging Package verzichtet. Stattdessen wird Log4J direkt eingesetzt. 6.6.4 MapLibraryLoader [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 6.7 Zusammenfassung [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] 44 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP Mobile Geogrid®-Version mit CLDC/MIDP 7 In diesem Kapitel wird die im Rahmen dieser Diplomarbeit erstellte mobile Geogrid®Version mit CLDC/MIDP vorgestellt. Nach der Funktionalitätsbeschreibung wird insbesondere auf die Softwarearchitektur und die Designentscheidungen eingegangen. Am Anfang der Konzeptionsphase stand ich vor der Entscheidung, ob ich die mobile Geogrid®-Version mit CLDC/MIDP oder mit CDC/Personal Profile realisieren soll. Ich habe mich für CLDC/MIDP entschieden, da diese Konfiguration/Profil Kombination auf Mobiltelefonen weiter verbreitet ist (siehe Kapitel 3.5) und somit sehr viele potentielle Kunden anvisiert werden können. Zudem existiert bereits ein PersonalJavaPrototyp von JavaMap, der einfach auf CDC/Personal Profile migriert werden kann. Der im Kapitel 4 durchgeführte Vergleich zwischen den beiden Konfiguration/Profil Kombinationen hat gezeigt, dass die Migration einer J2SE-Applikation auf eine CLDC/MIDP Laufzeitumgebung mit vielen Einschränkungen verbunden ist. Aufgrund der (gegenüber CDC/Personal Profile stärkeren) Einschränkungen ist eine mobile Geogrid®-Version mit CLDC/MIDP spannender zu implementieren, da das Ergebnis am Anfang noch nicht sicher ist. Funktionalität der mobilen Geogrid®-Version 7.1 Die Funktionalität der mobilen Geogrid®-Version (nachfolgend MobileJavaMap genannt) umfasst folgende Punkte: • • • • • • • • • • • • Indirekte Unterstützung von KMRG-Karten (Kartenserver transformiert KMRG-Format ins PNG-Format). Herunterladen der Karteninformationen (Name, Maßstab, Projektion, usw.). Herunterladen von PNG-Kacheln, die zusammen einen Kartenausschnitt bilden. Darstellen der Kartenausschnitte im Vollbildmodus. Weiches Scrolling des Kartenausschnitts. Nachladen des Kartenausschnitts. Darstellung von Längen- und Breitengrad der anvisierten Position auf dem Kartenausschnitt. Positionsbestimmung über einen Bluetooth-GPS-Empfänger, der das NMEAProtokoll unterstützt. Zentrieren der Karte auf die empfangenen Koordinaten des GPS-Empfängers. Setzen von Referenzpunkten. Cachen von bereits geladenen Karteninformationen und PNG-Kacheln. Menüstruktur mit Optionseinstellungen. Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 45 Abbildung 7-1: MobileJavaMap auf Siemens S65, Sony Ericsson K700i und Dell Axim PocketPC Abbildung 7-1 zeigt den Prototypen auf dem Siemens S65, dem Sony Ericsson K700i und dem Dell Axim Pocket PC. Weitere Screenshots sind in der Bedienungsanteilung im Kapitel 12.2 zu finden. Die Implementierung erfüllt nur eine Teilmenge der gestellten Anforderungen und ist somit als Prototyp aufzufassen. Folgende Kriterien sind noch nicht erfüllt: • • • • • • • Unterstützung von mindestens einem der in Kannkriterien enthaltenen Overlayformate (Binär, ASCII, XML). (Musskriterium) Herunterladen von Overlays. (Musskriterium) Direkte Speicherung der Karten auf dem Gerät. (Wunschkriterium) Zoomen von Karten. (Wunschkriterium) Unterstützung von Höhendaten. (Wunschkriterium) Positionsbestimmung über Location API. (Kannkriterium) Unterstützung für MAPS-Karten. (Kannkriterium) Die Anforderungen „Positionsbestimmung über Location API“ und „Direkte Speicherung der Karten auf dem Gerät“ konnten aus technischen Gründen nicht umgesetzt werden. Kapitel 7.5.1 und 7.5.9 gehen detailliert auf die zugrunde liegende Problematik ein. Die anderen Anforderungen konnten wegen der begrenzten Zeit für die Diplomarbeit nicht implementiert werden. Wie die nicht implementierten Anforderungen in den Prototyp eingebaut werden können und in wie weit die Architektur darauf vorbereitet ist, wird im Kapitel 7.5.10 erläutert. 7.2 Mindestanforderungen an das mobile Gerät MobileJavaMap benötigt eine CLDC 1.1/MIDP 2.0 Laufzeitumgebung. Aufgrund der fehlenden Unterstützung für die primitiven Datentypen double und float ist MobileJavaMap nicht unter CLDC 1.0 lauffähig. Theoretisch hätte die Fliesskommaarithmetik simuliert werden können, allerdings ist das Umschreiben der von JavaMap wieder verwendeten Projektionsklassen zeitaufwendig und fehlerträchtig, von daher habe ich darauf verzichtet. Zudem unterstützen viele Neuerscheinungen auf dem Mobiltelefonmarkt CLDC 1.1, so dass die Kompatibilität zu CLDC 1.0 in Zukunft immer unwichtiger wird. 46 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP Des Weiteren benötigt MobileJavaMap 512 KB RAM und 111 KB Speicherplatz für die .jar Datei. Für das Cachen der geladenen Kacheln sollte das Record Management System mindestens 128 KB zur Verfügung stellen können. Bei der Implementierung wurde auf die Verwendung von herstellerspezifischen Klassen verzichtet, um eine größtmögliche Kompatibilität zu erreichen. Das hat sich rentiert, denn der Prototyp wurde erfolgreich auf einem Sony Ericsson K700i, einem Siemens S65, einem Nokia 6230 und einem Dell Axim PocketPC1 getestet. 7.3 Wiederverwendung von Code aus JavaMap Der erste Schritt der Konzeption war eine Evaluierung, welche Codeteile aus JavaMap übernommen werden können. Aufgrund der eingeschränkten Möglichkeiten der LCDUI Low-Level API des MIDP kann das KMRG-Format nicht eingesetzt werden (Begründung siehe 7.5.2). Somit kann das in der abstrakten Map Klasse verwendete Verfahren zur Erzeugung eines Kartenausschnitts nicht übernommen werden. Die AWT- und Swingkomponenten sowie die ganze Ereignisbehandlung konnte ebenfalls nicht wieder verwendet werden, da das LCDUI Hi-Level API zu diesen APIs absolut inkompatibel ist. Probleme gab es auch bei den Projektionsklassen, die Methoden aus der java.lang.Math Klasse verwenden, die in der CLDC-Version der Math Klasse nicht vorhanden sind. MobileJavaMap verwendet eine fremde Hilfsklasse, die diese fehlenden Methoden implementiert. Die betreffenden Projektionsklassen mussten daraufhin angepasst werden. 7.4 Architekturübersicht Abbildung 7-2 illustriert eine stark abstrahierte Sicht auf die Architektur von MobileJavaMap, da die Anzahl der Klassen zu groß ist, ist um sie sinnvoll in einem Klassendiagramm darzustellen. MobileJavaMap teilt die Architektur in die drei Schichten Model, Controller und View auf. Die Interaktion zwischen den drei Schichten wird in den nächsten Kapiteln beschrieben. Zur Modelschicht gehört die Abstrahierung und Implementierung der Karte, der Projektionen und des GPS-Empfangs. Ebenfalls in der Modelschicht befinden sich Komponenten für den Zugriff auf die Datenquelle und für das Cachen der empfangenen Daten. Die Controllerschicht arbeitet mit einer zentralen Controller Instanz. Aktionen werden in separaten Aktionsklassen gekapselt, die definierte Aufgaben erfüllen und somit die Controller Instanz entlasten. Notwendige Initialisierungen beim Starten und Beenden werden, ähnlich wie im Struts-Framework (siehe auch Kapitel 6.6.4), in Plug-ins ausgelagert. Die Viewschicht enthält für die Menüdarstellung mehrere High-Level-LCDUI Komponenten. Für die Kartendarstellung werden dagegen Low-Level-LCDUI Komponenten verwendet. Zu ihnen gehören auch Layer-Komponenten, die die OverlayFähigkeit von MobileJavaMap implementieren und das Scrollen der Karte ermöglichen. 1 Mit vorheriger Installation der IBM J9 CLDC/MIDP Virtual Machine. Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP View High-Level-LCDUI Komponenten Controller Controller Instanz Model Karte 47 Low-Level-LCDUI Komponenten Aktionen Projektion GPS InitialisierungsPlug-Ins Datenquelle Cache Abbildung 7-2: Architekturübersicht MobileJavaMap 7.5 Modellschicht Dieses Unterkapitel beschreibt und begründet die Designentscheidungen in der Modellschicht von MobileJavaMap. Dabei wird auf das Kartenformat, auf die Kachelung der Karte und das Cachen der empfangen Daten eingegangen. Ebenfalls wird besprochen, woher die Kartendaten kommen und wie die Kommunikation mit dem Kartenserver abläuft. Auch die GPS-Komponente wird näher beleuchtet. Nicht besprochen wird die Implementierung der Projektionen, da diese aus JavaMap übernommen werden konnten. Dieses Unterkapitel schließt mit Überlegungen ab, wie noch fehlende Features, wie z.B. Höhendatenunterstützung, in den Prototyp eingebaut werden können. 7.5.1 Datenquelle Die Kartendaten holt sich der Prototyp nur über den Kartenserver, da ein direkter Zugriff auf das Dateisystem nur bei den wenigsten Mobiltelefonen möglich ist. CLDC erlaubt zwar den Zugriff auf Dateien, die sich in der MIDlet-Suite befinden, aber nur in Form eines InputStreams (siehe auch Kapitel 4.4). Damit die Implementierung nicht vom technischen Datenzugriff abhängig wird, wurde das Interface IMapDataProvider spezifiziert, das Operationen zum Zugriff auf Kartendaten definiert. Der Klient eines IMapDataProviders fordert die Kartendaten in Nachrichtenform an. Die Interfaces für die Nachrichten und die Implementierungen konnten vom Kartenserver übernommen werden. Die Nachrichten wurden bereits im Kapitel 6.5.1 vorgestellt. Vorraussetzung für die Wiederverwendung war natürlich, dass Interfaces und Implementierungen unter CLDC/MIDP kompilierbar sind. Einzige Ausnahme ist das Interface IPackedTilesMessageCLDC, das nur in einer MIDP-Umgebung lauffähig ist, da MIDP-spezifische Klassen eingesetzt werden. Woher die Nachrichten geholt werden, bestimmt die Implementierung des IMapDataProvider Interfaces. Momentan gibt es zwei Implementierungen: HTTPMapDataProvider, der die Nachrichten vom Kartenserver via HTTP holt und DummyLocalMapDataProvider, der immer die gleichen Testnachrichten zurückgibt. Mit steigender Hardwareleistung und Verfügbarkeit der entsprechenden optionalen Pakete 48 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP können später z.B. ein SOAPMapDataProvider oder LocalMapDataProvider hinzukommen. Allerdings müsste der LocalMapDataProvider die auf dem Dateisystem gespeicherten Daten auch in Form der Antwortnachrichten anbieten. Abbildung 7-3: IMapDataProvider und die Implementierungen Abbildung 7-4 zeigt alle Methoden des Interfaces. Eine Anforderung einer Nachricht ist blockierend, von daher muss sie von einem separaten Thread ausgeführt werden. Ein anderer Thread kann die gerade laufende Anforderung mit dem Aufruf der cancelRequest Methode unterbrechen. Der anfordernde Thread erhält dadurch eine Exception. Die Methode isCancelled gibt an, ob die letzte Anforderung abgebrochen wurde. Abbildung 7-4: Interface IMapDataProvider 7.5.2 Kartenformat Im Gegensatz zu JavaMap verwendet MobileJavaMap PNG als Datenformat für die Karte. Das im Kapitel 2.3 vorgestellte KMRG-Format wird momentan nicht direkt unterstützt. Um aber dennoch KMRG-Karten anzeigen zu können, muss der Kartenserver den angeforderten Kartenausschnitt vom KMRG- ins PNG-Format konvertieren. Der Kartenausschnitt kann nur mit Hilfe der im Kapitel 4.5.2 vorgestellten LCDUI-LowLevel API gezeichnet werden. Die Low-Level API ermöglicht das Zeichnen von Bildern im PNG- oder RGB-Format, von daher hätte man auf dem mobilen Gerät auch aus KMRG-Daten RGB-Werte erzeugen und diese über die Methoden drawRGB oder createRGBImage der Graphics Klasse darstellen können. Das hat aber gravierende Nachteile: Während PNGs nativ vom mobilen Gerät dekomprimiert und dargestellt werden können, müssen KMRG-Daten von einer eigenen LZW Klasse dekomprimiert werden, was Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 49 zusätzlichen Rechenaufwand bedeutet. Zudem benötigen die Methoden drawRGB und createRGBImage viel Speicher, da jeder Bildpunkt durch einen int Wert (32 Bit) repräsentiert wird. Bei einem Kartenausschnitt mit den Ausmaßen 176 * 220 werden somit satte 154880 Bytes verbraucht. Die bessere Alternative ist also der Einsatz von PNGs. Aus einer PNG Datei kann ein Image Objekt erzeugt werden, das über die drawImage Methode auf den Bildschirm gezeichnet wird. Ein Test, der den Verbrauch des Heapspeichers durch die Verwendung von drawRGB und drawImage vergleicht, unterstreicht deutlich die Speicherersparnis durch den Einsatz von PNGs. Das verwendete Testbild ist eine einfarbige Fläche mit 176 * 220 Pixeln. Im drawRGB Test wird ein Integerfeld mit der Größe 176 * 220 erzeugt und innerhalb einer Schleife mit dem Wert 0x00FF0000 (Integerwert für rot) gefüllt. Dagegen wird im drawImage Test das Bild aus einer PNG-Datei (176 * 220, 24 Bit + 8 Bit Transparenz) geladen. Die Messungen beginnen vor der Erzeugung des int Feldes bzw. vor dem Laden des PNG Bildes und enden nach dem Aufruf von drawRGB bzw. drawImage. Tabelle 7-1 listet die Messergebnisse auf, dabei ist deutlich zu erkennen, dass drawRGB durchgängig über 154880 Bytes an Speicher verbraucht. Nach dem Zeichnen kann die Referenz auf das Integer Feld auf null gesetzt werden, um es der Garbage Collection zu überlassen. Allerdings kostet der Aufruf der Garbage Collection wertvolle Rechenzeit. Das Zeichnen von PNGs mit drawImage ist dagegen wesentlich sparsamer und vermeidet unnötige Aufrufe der Garbage Collection. Allerdings treten erhebliche Unterschiede in den verschiedenen MIDP Implementierungen auf. Testumgebung drawRGB drawImage Wireless Toolkit 2.2 154896 Bytes 3612 Bytes Sony Ericsson K700i 154896 Bytes 984 Bytes Siemens S65 154888 Bytes 81608 Bytes Tabelle 7-1: Vergleich des Speicherbedarfs von drawRGB und drawImage Nicht nur beim Speicherverbrauch sondern auch in der Geschwindigkeit ist die Verwendung von drawImage die bessere Wahl. Tabelle 7-2 listet die Ergebnisse der Geschwingkeitsmessung auf. So ist die drawRGB Methode auf dem Sony Ericsson K700i 39 ms langsamer als drawImage. Auf dem Siemens S65 benötigt der drawRGB Aufruf sogar 554 ms. Dagegen ist auf dem Wireless Toolkit 2.2 kein Geschwindigkeitsunterschied zu messen. Die Messpunkte liegen direkt vor und nach dem Aufruf der jeweiligen Methode. Testumgebung Geschwindigkeit mit drawImage in ms Geschwindigkeit mit drawRGB in ms Wireless Toolkit 2.2 0 0 Sony Ericsson K700i 1 40 Siemens S65 14 554 Tabelle 7-2: Vergleich der Geschwindigkeit von drawRGB und drawImage 50 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP Aufgrund dieser Ergebnisse habe ich mich für den Einsatz von PNGs entschieden. Woher kommen diese massiven Geschwindigkeitsunterschiede? Die JavaDoc Dokumentation äußert sich folgendermaßen zu diesem Thema: „The mapping from ARGB values to the device-dependent pixels is platform-specific and may require significant computation.“ [@SUN02_MIDP20]. Diese Umrechnung ist aber bei den beiden Testgeräten so langsam, dass ein sinnvoller Einsatz der drawRGB Methode bei grafikintensiven Applikationen momentan nicht möglich ist. Dabei sind die getesteten Geräte immer noch aktuell: das K700i und das S65 sind erst im Sommer 2004 auf dem Markt erschienen und werden zum Zeitpunkt der Abgabe der Diplomarbeit noch verkauft. 7.5.3 Kachelung der Karte Jetzt wo wir wissen, welches Kartenformat verwendet wird, stellt sich die Frage wie der Kartenausschnitt übertragen wird. Es bieten sich zwei Alternativen an: Der Server überträgt den Kartenausschnitt am Stück, d.h. es wird nur ein PNG gesendet. Die andere Möglichkeit ist die Kachelung des Kartenausschnittes, also das Zerteilen des Kartenausschnitts in mehrere kleine PNGs. Dabei ist die Größe der einzelnen PNGs von den Kacheln in der ursprünglichen KMRG-Datei unabhängig, da der Server erst einen Kartenausschnitt generiert und anschließend daraus die einzelnen PNG-Kacheln erzeugt. Diese beiden Varianten werden in Abbildung 7-5 illustriert. Variante 1 zeigt einen Kartenausschnitt als einzelnes PNG, Variante 2 illustriert einen gekachelten Kartenausschnitt. Variante 1 Kartenausschnitt als einzelnes PNG Variante 2 Kartenausschnitt gesetzt aus 4 PNGs Abbildung 7-5: Kartenausschnitt In MobileJavaMap ist Variante 2 implementiert. Die Entscheidung für die Kachelung des Ausschnitts resultiert aus folgenden Überlegungen und Beobachtungen: Die Bildgröße ist bei mobilen Geräten begrenzt, da nicht so viel Speicher am Stück für das Bild allokiert werden kann. Beispielsweise erlaubt das Sony Ericsson K700i eine maximale Bildgröße von 448 * 448 Pixeln. Mit der Kachelung sind größere Kartenausschnitte möglich, weil so nur kleinere Speicherblöcke belegt werden. Zudem ist das Nachladen von Kartenausschnitten mit Kacheln flexibler, da nur die benötigten Kacheln geladen werden müssen. Bereits geladene Kacheln können in den neuen Kartenausschnitt wieder verwendet werden. In Variante 1 ist die Wiederverwendung schwieriger, aber nicht unmöglich. Der Kartenserver schickt ein PNG mit der gleichen Größe. Der Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 51 Teil, der sich mit dem bisherigen Kartenausschnitt überlappt, wird weiß gelassen, um die Grösse des PNGs zu optimieren. Auf dem mobilen Gerät wird der überlappende Teil vom alten Kartenausschnitt auf den neuen kopiert. Abbildung 7-6 illustriert die unterschiedlichen Nachladeverfahren der beiden Varianten, dabei umfasst der dicke schwarze Rahmen jeweils den neuen Kartenausschnitt. Variante 1: einzelnes PNG Kartenserver Variante 2: mehrere kleinere PNGs Abbildung 7-6: Nachladen des Kartenausschnitts Die Kachelung bringt auch beim Cachen der Kartenausschnitte Vorteile, da jede Kachel in den Ausmaßen gleich groß ist und einfach über die absolute Position der linken oberen Ecke identifiziert werden kann. Insgesamt gesehen bringt die Kachelung eines Kartenausschnitts deutliche Vorteile. Doch wie sieht die Implementierung einer Kachel aus? Abbildung 7-7 stellt die Interfaces und Klassen für eine Kachel vor. Eine Kachel wird durch das Interface ITile repräsentiert, welches lesenden Zugriff auf Breite, Höhe, Zoomfaktor, Positionsangabe (PixelCoordinate der linken oberen Ecke) und auf das eigentliche Image Objekt anbietet. Von ITile abgeleitet ist das Interface ILazyTile, das zwei Zustände für eine Kachel definiert: Initialisiert und nicht-initialisiert. Eine initialisierte Kachel enthält ein Image Objekt, eine nichtinitialisierte Kachel dagegen ein Bytefeld zum Erzeugen eines Image Objekts. Der Grund für diese beiden Zustände ist die fehlende Serialisierungsfähigkeit in CLDC/MIDP. Aus einem Image Objekt lässt sich nicht mehr das originale Bytefeld erzeugen, das für das Cachen benötigt wird. Erst wenn die Kachel gecached wurde, wird die Kachel initialisiert und kann gezeichnet werden. Bei dem Versuch auf das Image Objekt einer nicht initialisierten Kachel zuzugreifen wird eine IllegalStateException geworfen. Die einzige konkrete Implementierung des ILazyTile Interfaces ist die SquareTile Klasse. 52 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP Abbildung 7-7: ITile, ILazyTile und SquareTile Die vom Server empfangenen Kacheln befinden sich in einem Bytestrom, in dem die PNGs mit ihren absoluten Positionsangaben (in Form einer serialisierten PixelCoordinate) zusammengefasst sind (siehe auch Kapitel Fehler! Verweisquelle konnte nicht gefunden werden.). Durch die Zusammenfassung mehrerer Kacheln in einem Bytestrom wird die Anzahl von teuren HTTP-Connections minimiert. Interpretiert wird dieser Bytestrom von der PackedTilesMessageCLDC Klasse, die das IPackedTilesMessageCLDC Interface implementiert. Über die getTiles Methode erhält der Entwickler Zugriff auf die nicht-initialisierten Kacheln (ILazyTile Objekte). Die Kommunikation mit dem Kartenserver wird detaillierter in Kapitel 7.5.7 beschrieben. 7.5.4 Sektion-Konzept Die jetzigen Geräte sind nicht in der Lage, eine komplette Karte in den Hauptspeicher zu laden, deswegen kann nur ein kleiner Kartenausschnitt im Speicher gehalten werden. Dieser Kartenausschnitt besteht aus einer Sammlung von Kacheln, die zusammengesetzt eine Sektion auf der Karte abbilden. Je nach verfügbarer Speichergröße kann die Größe der Sektion (also die Anzahl der verwendeten Kacheln) konfiguriert werden. Sie sollte mindestens so groß sein, dass die Displaygröße abgedeckt wird. Abbildung 7-8 illustriert eine Sektion die 25 Kacheln enthält. Das gestrichelte Rechteck innerhalb der Sektion repräsentiert den sichtbaren Ausschnitt auf dem Display des mobilen Gerätes. Der Anwender kann den sichtbaren Ausschnitt innerhalb der Sektion bewegen, das erzeugt einen Scrollingeffekt. Wenn der sichtbare Ausschnitt an die Grenzen der Sektion stößt, wird die Sektion nachgeladen. Die verwendete Strategie zum Nachladen wird im Kapitel 7.5.6 vorgestellt. Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 53 Gesamte Karte Displaygrösse Sektion Abbildung 7-8: Sektion Die Karte und die Sektion werden in der Implementierung durch zwei Interfaces repräsentiert: IMap und ISection. Das Klassendiagramm in Abbildung 7-9 illustriert die Zusammenhänge, die im Anschluss erläutert werden. Abbildung 7-9: IMap und ISection Ein IMap Objekt enthält die Karteninformationen wie Breite, Höhe, Maßstab und Projektion (in Form eines aggregierten IProjection Objekt). Identifiziert werden IMap Objekte durch ein eindeutiges IMapIdentifier Objekt. Dieses Objekt setzt sich aus der MapID, dem Kartennamen und der URL des Kartenservers zusammen, um eine Identifikation der Karte zu ermöglichen. Es wird auch als Schlüsselobjekt für Hashtables verwendet, somit ist die konkrete Implementierung des Interfaces verpflichtet die (von der Object Klasse geerbten) Methoden hashCode und equals korrekt zu überschreiben (vgl. Thema 7 und 8 in [BLOCH02]). Wie im Kapitel 6.6.1 bereits erläutert, ist die Identifizierung der Karten durch den Kartennamen allerdings nicht ausreichend. Von daher muss das IMapIdentifier Objekt in einer kommerziellen Versi- 54 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP on die Karten über einen Hashcode eindeutig identifizieren. Die einzige Implementierung des IMap Interfaces ist MapCLDC. Eine Sektion wird durch ein ISection Objekt abstrahiert, das mehrere ITile Objekte enthält (Zur Erinnerung: Ein ITile Objekt repräsentiert eine Kachel). Ähnlich wie in einem Collection Objekt können Kacheln hinzugefügt oder gelöscht werden. Darüber hinaus hält das ISection Objekt eine Referenz auf ein IMap Objekt, d.h. die Sektion kennt ihre Karte. Die einzige Implementierung des ISection Interfaces ist die Klasse SectionSquare. Sie legt fest, dass die Sektion quadratisch ist. Allerdings kann das Löschen oder Hinzufügen einer Kachel diese Festlegung untergraben. Beispielsweise könnte ein Klient wahllos Kacheln löschen. Die resultierende Sektion würde kein Quadrat mehr darstellen. Ob nun ein SectionSquare Objekt ein gültiges Quadrat auf der Karte darstellt, kann ein Klient der Klasse mit dem Aufruf einer Methode feststellen. Erzeugt werden IMap und ISection Objekte durch separate „Erbauerobjekte“. Hier kommt das Entwurfsmuster Erbauer [GAMMA96] zum Einsatz, was zur „Isolierung des Codes von Konstruktion und Repräsentation“ führt und eine „genauere Steuerung des Konstruktionsprozesses“ [GAMMA96] erlaubt. Die Erbauerobjekte selbst werden durch Fabriken erzeugt. Diese werden aber der Einfachheit halber nicht weiter vorgestellt. Abbildung 7-10: ISectionBuilder und ISection Betrachten wir zunächst, wie Sektionen erzeugt werden. Die nachfolgend besprochenen Klassen und Interfaces werden in der Abbildung 7-10 dargestellt. Ein Erbauerobjekt für ISection Objekte implementiert das ISectionBuilder Interface und ist neben dem Erzeugen auch für das Nachladen von Sektionen verantwortlich. Die SectionBuilderSquare Klasse implementiert dieses Interface und erzeugt ausschließlich SectionSquare Objekte. Das SectionBuilderSquare Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 55 Objekt hält keine Referenzen auf die erzeugten bzw. nachgeladenen Sektionen. Umgekehrt kennt aber jedes erzeugte SectionSquare Objekt seinen Erbauer (unter dem ISectionBuilder Interface), da es eventuell nachgeladen werden muss. Die Entscheidung, welche Kacheln das nachgeladene SectionSquare Objekt enthält, delegiert das SectionBuilderSquare Objekt an ein IReloadStrategy Objekt. Die zur Erzeugung notwendigen Daten werden von dem IMapDataProvider oder ITileCache geholt. Der Tile Cache wird im Kapitel genauer 7.5.8 vorgestellt. Ein SectionBuilderSquare Objekt benötigt zum Erzeugen einer Sektion eine PixelCoordinate, die das Zentrum der zukünftigen Sektion darstellt. Von dieser Koordinate ausgehend, werden die Koordinaten der benötigten Kacheln ermittelt. Sektionen werden nachgeladen, in dem die in der Sektion enthaltenen Kacheln ausgetauscht werden, so dass die Sektion einen neuen Kartenausschnitt repräsentiert. Eine konsistente Sektion besitzt nach jedem Nachladevorgang dieselbe Anzahl von Kacheln. Kacheln, die sich nicht mehr in einer Sektion befinden, werden der Garbage Collection überlassen. Abbildung 7-11 illustriert den beschriebenen Nachladeprozess eines ISection Objektes. Zunächst werden die nicht benötigten Kacheln aus der Sektion gelöscht (1). Anschließend wird versucht, die fehlenden Kacheln aus dem Tile Cache zu laden. Im Erfolgsfall liefert der Tile Cache nicht-initialisierte Kacheln zurück (2). Falls einige Kacheln sich nicht im Cache befinden, werden sie vom IMapDataProvider angefordert (3) und gleich in den Cache gesteckt (4). Abschließend werden die Kacheln initialisiert und zu der Sektion hinzugefügt (5). 5. 3. IMapDataProvider 2. SectionSquare 1. SectionSquareBuilder 4. ITileCache Legende: nicht initialisiertes ILazyTile Objekt Garbage Collection initialisiertes ILazyTile Objekt Abbildung 7-11: Nachladen eines SectionSquare Objekts 56 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP Betrachten wir nun den Erzeugungsprozess für IMap Objekte. Abbildung 7-12 stellt die Beziehung von IMapBuilder und IMap vor. Abbildung 7-12: IMapBuilder und IMap Erzeugerobjekte für IMap Objekte implementieren das IMapBuilder Interface und verwalten die erzeugten Objekte. Ein IMapBuilder ist also Kartenliste und Erzeuger für Karten zugleich. Die MapBuilder Klasse implementiert das Interface und holt sich die zur Erzeugung notwendigen Daten über einen IMapCache oder einen IMapDataProvider. Der Map Cache wird später im Kapitel 7.5.8 vorgestellt. Das erzeugte MapCLDC Objekt aggregiert ein ISectionBuilder Objekt, das für diese Karte Sektionen erzeugt. Abbildung 7-13 stellt den Erzeugungsprozess eines MapCLDC Objektes dar. Fordert ein Klient eine Karte an, so wird zunächst im Cache danach gesucht. Der Cache gibt im Erfolgsfall die für die Erzeugung eines MapCLDC Objektes notwendigen Nachrichten zurück (1). Wenn die notwendigen Nachrichten zur Erzeugung der Karte aber sich nicht im Cache befinden, dann werden sie vom IMapDataProvider angefordert (2) und anschließend in den Cache in den Cache gesteckt (3). Abschließend wird das MapCLDC Objekt mit den Informationen aus den Nachrichten erzeugt (4). 2. IMapDataProvider 4. 1. MapCLDC MapBuilder 3. Legende: Nachrichten zur Erzeugung eines MapCLDC Objektes Abbildung 7-13: Erzeugung eines MapCLDC Objektes IMapCache Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 57 Das Sektions-Konzept ist komplex, aber gleichzeitig sehr flexibel. Die eigentlichen Sektion- und Kartenobjekte müssen nicht wissen, wie sie erzeugt worden sind. Das liegt in der Verantwortung der Erzeugerobjekte. Diese kapseln die komplizierte Erzeugung der Objekte und können auf im Cache liegende Instanzen zurückgreifen. Erzeugerobjekte werden mit einem Konfigurationsobjekt (Configuration) initialisiert. So kann die Ausprägung der erzeugten Objekte festgelegt werden. Der Klient eines IMapBuilders ist sich der gekapselten Komplexität nicht bewusst, wie das nächste Unterkapitel zeigt. 7.5.5 Codebeispiel Sektion-Konzept Das nachfolgende Codefragment 7-1 verdeutlicht die im vorherigen Unterkapitel beschriebenen Zusammenhänge. Der Code ist nicht direkt aus MobileJavaMap entnommen, sondern nur für Erklärungszwecke erstellt worden. Nach Instanzierung (1) und (2) der Fabriken für Section- und MapBuilder wird eine IMapBuilder Instanz über die Fabrik erzeugt (3). Vor dem ersten Zugriff muss das IMapBuilder Objekt initialisiert werden (4), dabei werden Karteninformationen aus dem Cache geladen. Die Methode getAvailableMaps (5) liefert ein Array mit IMapIdentifier Objekten zurück, die sich im Cache befinden. Mit diesem Array könnte jetzt weitergearbeitet werden. Um aber alle verfügbaren Karten zu erhalten, muss explizit eine Aktualisierung verlangt werden. Dies geschieht mit dem Aufruf der refreshMapList Methode (6). Der erneute Aufruf von getAvailableMaps liefert nun aktualisierte Informationen (7). Mit der getMap Methode des MapBuilders kann das gewunschte IMap Objekt geholt werden, in unserem Beispiel die erste Karte (8). Als nächsten Schritt soll eine Sektion mit der Kartenmitte als Zentrum erzeugt werden. Die Kartenmitte wird über getWidth und getHeight Methoden des IMap Objektes ermittelt (9). Anschließend wird das zu der Karte dazugehörige ISectionBuilder Objekt geholt (10), mit dem ein ISection Objekt erzeugt werden kann (11). Dabei wird das Zentrum der neuen Sektion mit übergeben. Bevor die Applikation beendet wird, muss der MapBuilder explizit geschlossen werden, damit er eigene Ressourcen schließen kann. (13). 58 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP // Fabriken ISectionBuilderFactory sectionBuilderFactory = new SectionBuilderSquareFactory( // (1) mapDataProvider, configuration); IMapBuilderFactory mapBuilderFactory = new MapBuilderFactory( mapDataProvider, configuration, sectionBuilderFactory); // (2) // MapBuilder IMapBuilder mapBuilder = mapBuilderFactory.getMapBuilder(); (3) try { mapBuilder.initialize(); // Initialisierung des MapBuilders IMapIdentifiers[] mapsFromCache = mapBuilder.getAvailableMaps(); // (4) (5) mapBuilder.refreshMapList(); IMapIdentifiers[] maps // Aktualisierung der Kartenliste = mapBuilder.getAvailableMaps(); (6) (7) IMap map = mapBuilder.getMap(maps[0]); // Zugriff auf die erste Karte (8) PixelCoordinate centerOfMap = new PixelCoordinate( // Kartenmitte map.getMapWidth() / 2, map.getMapHeight() / 2); (9) ISectionBuilder sectionBuilder = map.getSectionBuilder(); // ISection section = sectionBuilder.createSection(centerOfMap); // (10) (11) } catch (Exception e) { // Kann ProviderException, UnkownProjectionException oder // IllegalStateException sein } finally { mapBuilder.close(); // muss explizit geschlossen werden } (12) (13) Codefragment 7-1: MapBuilder und SectionBuilder Innerhalb des try-Blocks können ProviderException, UnkownProjectionException oder IllegalStateException geworfen werden. Der Übersicht halber werden hier alle von einem einzigen catch-Block gefangen (12). Aus diesem Codefragment wird deutlich, dass das Design in der Modellschicht sehr stark Interface-orientiert ist: Die Klassen sprechen andere Klassen nur über ihre Interfaces an. Das erleichtert die Austauschbarkeit von Implementierungen und führt zu einer flexiblen Architektur. Beispielsweise muss der Klient sich nicht darum kümmern, woher die Kartendaten kommen und wie das Caching funktioniert. Kapitel 7: 7.5.6 Mobile Geogrid®-Version mit CLDC/MIDP 59 Nachladestrategie Wenn der sichtbare Bildausschnitt an die Grenzen der Sektion stößt, muss die Sektion nachgeladen werden. Es gibt unterschiedliche Möglichkeiten die Sektion nachzuladen. Für MobileJavaMap wurde eine recht einfache, aber dennoch funktionale Variante implementiert, die in Abbildung 7-14 illustriert wird. Als Beispiel dient eine Sektion mit 6*6 Kacheln, die nachgeladen werden muss, da der sichtbare Bildausschnitt (gestricheltes Rechteck) an das untere Ende der Sektion angestoßen ist. Ein roter Punkt markiert seinen Mittelpunkt. Von ihm ausgehend wird der Mittelpunkt der neuen Sektion ermittelt. Da der Mittelpunkt sich immer in dem Kachelraster befinden muss, wird der Punkt zur nächsten Kachel in Richtung der nächsten Sektionsecke verschoben. In unserem Beispiel ist das die nächste Kachel in Richtung der unteren rechten Ecke. Der grüne Punkt zeigt den neuen Mittelpunkt der neuen Sektion, mit ihm kann berechnet werden, welche Kacheln nachgeladen werden (graue Kacheln) und welche Kacheln aus der Sektion entfernt werden müssen (rote Kacheln). Dieses Verfahren berücksichtigt nicht die Bewegungsrichtung des Bildausschnittes und kommt dennoch auf passable Ergebnisse. Mit sinkender Anzahl der Kacheln verschlechtert sich allerdings die Qualität der Ergebnisse, da das Kachelraster immer größer wird und der Mittelpunkt der neuen Sektion weiter vom Mittelpunkt des Bildausschnitts entfernt liegt. Während des Nachladeprozesses sieht der Anwender einen einfachen Wartebildschirm, der ihm die Möglichkeit zum Abbrechen des Vorgangs anbietet. Wenn stattdessen die Karte angezeigt wird, sinkt die Geschwindigkeit des Nachladens, da Rechenzeit für das Anzeigen der Karte verbraucht wird. 1. Sichtbarer Bildausschnitt stößt an die Grenzen der Sektion 2. Ausgehend vom Mittelpunkt des sichtbaren Bildausschnittes wird der Mittelpunkt der neuen Sektion ermittelt. Abbildung 7-14: Nachladestrategie Durch die Verwendung des Strategie Musters [GAMMA96] kann die Implementierung gegen eine bessere Variante ausgetauscht werden kann. Zum Beispiel könnte die aktuelle Bewegungsrichtung in die Berechnung der neuen Sektionsposition mit einfließen. Ebenso wäre ein konfigurierbarer Nachladealgorithmus vorstellbar. Der Anwender könnte z.B. bestimmen, wie weit voraus geladen werden soll. 60 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 7.5.7 Kommunikation mit dem Kartenserver Die Klasse HTTPMapDataProvider implementiert das bereits im Kapitel 7.5.1 vorgestellte IMapDataProvider Interface und kapselt die Kommunikation mit dem Kartenserver. Die Anfragemethoden erzeugen aus den übergebenen Parametern eine URL und öffnen über die Connector Klasse des Generic Connection Frameworks (welches in Kapitel 4.6 vorgestellt wurde) eine HttpConnection. Nach dem Überprüfen des HTTP-Statuscodes wird ein DataInputStream geöffnet, der den Bytestrom vom Server repräsentiert. Die empfangenen Bytes werden zunächst in einem Bytefeld gepuffert, aus dem später die Nachrichtenobjekte erzeugt werden. Gepuffertes Lesen ist schneller als wenn jedes Byte einzeln gelesen werden muss. Nicht gepuffert wird allerdings der Empfang der Kacheln. Die dort anfallende Datenmenge ist für eine Pufferung zu groß. Hier wird direkt aus dem DataInputStream das Nachrichtenobjekt erzeugt (PackedTilesMessageCLDC). Das Sequenzdiagramm in Abbildung 7-15 zeigt den Ablauf der getPackedTilesMessage Methode, die eine PackedTilesMessageCLDC Instanz zurückgibt. 1. Als Klient tritt ein MapBuilder auf, der die getPackedTilesMessage Methode aufruft. Dabei übergibt er u.a. die absolute Position aller Kacheln. 2. Aus den übergebenen Parametern wird zunächst ein URL-String erzeugt. Zu dieser URL wird über eine statische Methode der (nicht im Sequenzdiagramm dargestellten) Connector Klasse eine HttpConnection geöffnet. 3. Der DataInputStream der HttpConnection wird geholt. 4. Der Konstruktor der PackedTilesMessageCLDC bekommt den DataInputStream übergeben und initialisiert die PackedTilesMessageCLDC Instanz mit den im DataInputStream enthaltenen Daten. 5. Die HttpConnection wird nach dem Erzeugen der Nachricht wieder geschlossen. 6. Der HTTPMapDataProvider gibt die erzeugte Nachricht zurück. : HTTPMapDataProvider : MapBuilder getPackedTilesMessage (…) << create >> :HttpConnection getDataInputStream() dis << create >> ptm:PackedTilesMessageCLDC close() ptm Abbildung 7-15: Erzeugen einer PackedTilesMessageCLDC Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 61 Eine Sitzungsverfolgung ist nicht notwendig, da alle erforderlichen Parameter mit jedem Request übergeben werden. Prototypisch an dieser Implementierung ist der Verzicht auf Username und Passwort, somit kann jeder auf die Kartendaten zugreifen. In einer möglichen kommerziellen Version muss der Zugriff durch eine Authentifizierung abgesichert werden. Damit der Anwender die Kommunikation abbrechen kann, muss sie in einem separaten Thread laufen, ansonsten könnte die Software gar nicht auf Tastatureingaben reagieren. Über das simple Schließen einer geöffneten HttpConnection durch einen anderen Thread wird die Kommunikation bei Bedarf abgebrochen. Die Referenz auf die HttpConnection muss mit dem Java Schlüsselwort volatile gekennzeichnet werden, damit garantiert wird, dass jeder Thread, der auf die Variable zugreift, den aktuellen Wert bekommt. Ohne das Schlüsselwort arbeiten die Threads sonst mit einer Kopie (working copy) der Variablen, die unter Umständen veraltet ist. 7.5.8 Caching der geladenen Karten und Kacheln Verbindungen zum Kartenserver sind mit den jetzigen mobilen Geräten langsam und teuer, von daher ist ein Caching der bereits geladenen Karteninformationen und Kacheln wünschenswert. Aufgrund der Tatsache, dass CLDC/MIDP kein direkten Dateizugriff erlaubt, verwendet MobileJavaMap das RecordStore Management System (kurz RMS, siehe Kapitel 4.4), um die herunter geladenen Daten zu cachen. Das RMS ist eigentlich eher für kleine Datenmengen vorgesehen, aber es konnte dennoch erfolgreich für das Caching eingesetzt werden. MobileJavaMap definiert zwei Caches, die Ihre Daten in vier RecordStores ablegen. Cache RecordStore Interface Map Cache RECORDSTORE_MAP IMapCache Tile Cache RECORDSTORE_TILE_HEADER RECORDSTORE_TILE_IMAGE RECORDSTORE_TILE_CONFIGURATION ITileCache Tabelle 7-3: Caches in MobileJavaMap Tabelle 7-3 listet neben den Namen der verwendeten RecordStores für die beiden Caches auch die Interfaces auf, über die auf die beiden Caches zugegriffen werden kann. Schauen wir uns zunächst den Map Cache an. In diesem Cache sind die Nachrichten gespeichert, die benötigt werden, um eine MapCLDC Instanz zu erzeugen. Quasi als Bauplan für eine Karte können die vom Server empfangenen Nachrichten wieder verwendet werden. Die Nachrichten werden in ein Bytefeld zusammengepackt und im RecordStore MAP abgelegt. Vor den Nachrichten befindet sich zusätzlich ein serialisiertes MapIdentifier Objekt, welches die gecachte Karte identifiziert. Damit der Bytestrom korrekt ausgelesen werden kann, steht vor jedem serialisierten Objekt seine Länge (in der Abbildung 7-16 als graue Rechtecke illustriert). Anhand der SerialVersion der Nachrichten und des MapIdentifiers kann beim Auslesen überprüft werden, ob die gecachten Objekte mit der aktuellen Version der Implementierung deserialisiert werden können. 62 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP MapIdentifier MapInfoMessage MapBoundingMessage ProjectionParameterMessage Abbildung 7-16: Ein Record im RECORDSTORE_MAP Über das Interface IMapCache kann auf den Map Cache zugegriffen werden. Die einzige Implementierung dieses Interfaces ist MapCacheRMS. Nur die MapBuilder Klasse hält eine Referenz auf den Cache. Klienten der MapBuilder Klasse wissen also nicht, ob die Karte, die sie vom MapBuilder bekommen haben, vom Cache kommt oder neu geladen wurde. Prototypisch an dem Map Cache ist, dass er nicht limitiert ist. Allerdings ist ein Record sehr klein, von daher ist es sehr unwahrscheinlich, dass dieser Cache den Speicher eines mobilen Gerätes sprengt. Für die Kacheln existiert ein separater Cache, der Tile Cache, der drei RecordStores verwendet: • TILE_HEADER • TILE_IMAGE • TILE_CONFIGURATION. Die Metainformationen der Kacheln wie Position, MapIdentifier, Zoomfaktor, Bildgröße, usw. werden im RecordStore TILE_HEADER abgelegt. Jeder Eintrag enthält außerdem einen Verweis auf einen Record im TILE_IMAGE. Dort werden die eigentlichen Bilder der Kacheln gespeichert. TILE_CONFIGURATION enthält den Clock-Index, der die ID der „ältesten“ Kachel repräsentiert. Der Clock-Index ist ein essentieller Teil des Second-Chance-Algorithmus, der dafür sorgt, dass bei einem neuen Eintrag in einem vollen Cache nur ältere, seltener verwendete Kacheln gelöscht werden. Auf die genaue Funktionsweise wird später eingegangen. Abbildung 7-17 zeigt einen Cache mit 4 Einträgen. Über den Einträgen steht jeweils die RecordId. Die 4 Einträge im TILE_HEADER RecordStore enthalten Metainformationen über die im TILE_IMAGE RecordStore gespeicherten Bilder. Jeder TILE_HEADER Record verweist auf einen Record im TILE_IMAGE RecordStore. Ein TILE_HEADER Record bildet zusammen mit seinem TILE_IMAGE Record eine Kachel, dabei entspricht die Reihenfolge der Header nicht unbedingt der Reihenfolge der dazugehörigen Bilder. Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 1 2 3 63 4 TILE_HEADER TILE_IMAGE Abbildung 7-17: Tile Cache Grund für die Trennung von Bildern und den Headern ist die schnellere Performance beim Suchen nach den Kacheln. Alle Header können somit beim Start der Applikation in den RAM Speicher geladen werden. Änderungen an den Headern (beispielsweise das Hinzufügen oder Löschen einer Kachel) werden nur im RAM vollzogen, erst beim Beenden von MobileJavaMap werden die Header im TILE_HEADER persistiert. Dagegen werden die gecachten Bilder nicht im RAM gehalten, jede Änderung reflektiert sich sofort im TILE_IMAGE. Das Laden der Header-Einträge in den Speicher bedeutet, dass MobileJavaMap dafür sorgen muss, dass bei jedem Runterfahren die Einträge korrekt synchronisiert werden. Es gibt aber Fälle, wo das nicht garantiert werden kann, zum Beispiel wenn der Akku aus dem mobilen Gerät entnommen wird. Dann sind die Einträge im RMS nicht mehr gültig. Über ein „Gültigkeits-Bit“ in dem KonfigurationsRecordStore (CONFIGURATION) merkt MobileJavaMap, dass es nicht sauber heruntergefahren wurde und löscht den Cache. Der Tile Cache ist auf eine bestimmte Größe limitiert, bei einem vollen Cache muss also eine alte Kachel durch die neue ersetzt werden. Um die zu ersetzende Kachel zu bestimmen, verwendet MobileJavaMap den bereits erwähnten Second-ChanceAlgorithmus. Der Second-Chance-Algorithmus ist ein modifizierter FIFO (First In, First Out)-Algorithmus, der zusätzlich mit einem Second-Chance-Flag arbeitet. Variationen dieses Algorithmus wurden u.a. zur virtuellen Speicherverwaltung in Betriebssystemen eingesetzt (z.B. Unix 4BSD, Unix System V). Die Kacheln werden in einem Ringspeicher abgelegt, ein rotierender Zeiger (der Clock-Index) markiert die aktuelle Einfügeposition für eine neue Kachel. Wenn sich auf dieser Position bereits eine Kachel ohne Second-Chance-Flag befindet, wird sie durch die neue Kachel ersetzt. Hat die Kachel jedoch das Second-Chance-Flag, dann überspringt der Zeiger diese Kachel und „verschont“ sie vor dem Ersetzen. Damit wird aber ihr Second-Chance-Flag wieder entzogen. Eine Kachel bekommt wieder ein Second-Chance-Flag, wenn auf sie zugegriffen wird. Im Gegensatz zum FIFO-Algorithmus werden durch den Second-ChanceAlgorithmus nicht die ältesten Einträge gelöscht, sondern die älteren, auf die lange nicht mehr zugegriffen wurde. Ein Beispiel dargestellt in Abbildung 7-18 zeigt ein Cache mit acht Slots. Ein Slot ist ein Behälter für eine Kachel. Alle acht Slots sind belegt, die Kacheln in den Slots 3, 5 und 6 besitzen ein Second-Chance-Flag (in der Abbildung mit einem grünen Kreis markiert). Eine neue Kachel soll in den Cache eingefügt werden, dafür muss eine bereits vorhandene Kachel ersetzt werden. Der Clock-Index verweist auf Slot 3, da allerdings 64 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP die Kachel in diesem Slot über das Second-Chance-Flag besitzt, springt der ClockIndex auf Slot 4. Diese Kachel besitzt das Second-Chance-Flag nicht und wird somit durch die neue Kachel ersetzt. Nach dem Einsetzen der neuen Kachel springt der ClockIndex auf den nächsten Slot. 1 8 2 7 3 Clock Index: 3 6 4 5 neue Kachel Abbildung 7-18: Second Chance Algorithmus Aber wie funktioniert das Ersetzen von Kacheln in der konkreten Implementierung? Das RMS gibt den Speicher für gelöschte Records erst nach dem zeitaufwändigen Schließen (> 10s auf dem Wireless Toolkit) des RecordStores frei. Dieses Verhalten bleibt übrigens in der MIDP Dokumentation unerwähnt. Die Lösung für das Problem sieht folgendermaßen aus: MobileJavaMap löscht die Records nicht, sondern überschreibt einfach deren Inhalt. Um Fragmentierung zu vermeiden, müssen alle Records die gleiche Größe besitzen. Aufgrund der unterschiedlichen Komprimierungsfaktoren der Bilder geht also mal mehr, mal weniger Speicher verloren. MobileJavaMap trifft eine pessimistische Annahme, und verwendet die unkomprimierte Bytelänge der Bilder als Größe für einen Record. Die festgelegte Größe für einen Eintrag wird in der Implementierung Slotsize genannt. Abbildung 7-19 illustriert den daraus resultierenden Speicherverlust anhand zweier Records. In dem Beispiel gelte eine Kachelgröße von 128 * 128 mit 4 Bit pro Pixel. Daraus ergibt sich die Slotsize von 8192 Bytes (128 * 128 * 4 Bit). Kachel 1 benötigt 3936 Bytes, das führt zu einem Verlust von 4256 Bytes, heftiger fällt der Verlust bei Kachel 2 mit 7783 Bytes aus. 1 Verbrauch: Verlust: 2 3936 Bytes 4256 Bytes Verbrauch: Verlust: 409 Bytes 7783 Bytes Abbildung 7-19: Speicherverlust im TILE_IMAGE Recordstore Um den Verlust zu verringern, kann die Slotsize anhand von Messungen optimiert werden. Ein Messprogramm ermittelt die Bytegrößen aller Kacheln einer Karte. Die verwendete Kachelgröße ist 128 * 128. Tabelle 7-4 listet für fünf Testkarten die Karten- Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 65 größe in Pixel, die Anzahl der Kacheln sowie die durchschnittliche Bytegröße auf. Zusätzlich werden pro Karte die Extremwerte (Minimum und Maximum) dargestellt. 32-5-4 1205 1:4 Mio. 32-5-4 UEK1000 1:1 Mio. 32-5-4 M444 1:500.000 Dornier 1:10000 Dornier 1:1000 8960 * 7680 14080 * 10240 14080 * 18688 2048 * 2816 6144 7680 Anzahl Kacheln 4200 (=70 * 60) 8800 (=110 * 80) 16060 (=110 * 146) 352 (=16 * 22) 2880 (=48 * 60) durchschnittliche Bytegröße einer Kachel 1510,79 1282,37 1892,37 1351,14 1707,57 Minimale ße 251 251 247 125 125 4495 3963 4324 5605 6865 Kartenname Kartengröße Pixel in Bytegrö- Maximale Bytegröße * Tabelle 7-4: Analyse der Kachelgröße in Bytes Die Messungen zeigen, dass sich die durchschnittliche Bytegröße einer Kachel sowie die Extremwerte von Karte zu Karte deutlich unterscheiden. Da MobileJavaMap nur eine Slotsize für alle Kacheln unterstützt, muss eine Mindestgröße für die Slotsize gefunden werden, die für alle verwendeten Karten ausreicht. Ansonsten kann nicht garantiert werden, dass alle Kacheln gecached werden können. In unseren fünf Testkarten ist die größte gemessene Bytegröße 6865 Bytes (Dornier 1:1000). Aber diese Zahl erscheint im Vergleich zur durchschnittlichen Bytegröße sehr groß. Ein Blick auf die absolute Verteilung der Bytegröße in dem Histogramm in der Abbildung 7-20 verschafft Klarheit. Die gemessenen Bytegrößen wurden dafür in 68 gleichgroße Klassen von 200 bis 6900 Bytes eingeteilt, im Anhang befinden sich die genauen Zahlen (Kapitel 12.5.1). Es ist deutlich zu erkennen, dass die kleineren Bytegrößen am häufigsten vorkommen. Das ist auch bei den anderen Karten zu beobachten. Danach sinkt die Häufigkeit auf einen fast gleich bleibenden Pegel. Erst ab der Klasse 6000 tendiert die Häufigkeit gegen 0. Angenommen, die Slotsize sei 6000 Bytes, dann können von dieser Karte 74 Kacheln nicht mehr gecached werden, weil ihre Bytegröße größer als 6000 Bytes ist. Das entspricht einem Prozentsatz von 0,025% (= 74 / 2880 %). Besser als die Beschränkung der Slotsize wäre der Einsatz von mehreren Caches mit jeweils unterschiedlich großer Slotsize. Das ist eine gängige Technik zur Verwaltung von virtuellen Speichern. Für MobileJavaMap wären z.B. drei Caches mit der Slotsize von jeweils 512 Bytes, 4096 Bytes und 8192 Bytes vorstellbar. Das erhöht den Verwaltungsaufwand gegenüber der bereits implementierten Lösung, aber ermöglicht eine wesentlich effizientere Nützung des zur Verfügungen stehenden Cachespeichers. Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP Häufigkeit 66 Klasse Abbildung 7-20: Histogramm der Bytegrößen in der Karte Dornier 1:1000 7.5.9 Positionsbestimmung Die Fähigkeit über eine Bluetooth GPS-Empfänger GPS-Daten zu empfangen und auszuwerten, wertet den Prototypen stark auf. Bei Karten mit sehr großem Maßstab kann man sogar als Fußgänger seine Bewegung auf dem Display nachvollziehen. Vorraussetzung ist ein Bluetooth-GPS-Empfänger, der das standardisierte NMEA Format verwendet und ein mobiles Gerät, das die Bluetooth API unterstützt. Prototypisch an der Implementierung ist, dass die Bluetoothadresse des GPS-Empfängers statisch einprogrammiert ist. Für eine kommerzielle Variante muss noch ein so genannter „Discovery Process“ eingebaut werden, der nach möglichen GPS-Empfängern sucht. Abbildung 7-21: IGPSReceiver Implementiert wird die Verbindung zum GPS-Empfänger in der BluetoothGPSReceiver Klasse, die das IGPSReceiver Interface implementiert. Ein Klient kann den GPS-Empfang mit den Methoden start und stop steuern. Der GPS-Empfänger wird nach dem Starten immer in gleich bleibenden Abständen kontaktiert. Der zeitliche Abstand wird der start Methode in Form von Millisekunden übergeben. Die GPSReceiver Klasse verwendet intern eine private, verschachtelte Klasse namens BluetoothGPSTimerTask, die von java.util.TimerTask ableitet. Sie ist für den eigentlichen Kontakt mit dem GPS-Empfänger verantwortlich. Beim Starten des Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 67 GPS-Empfangs wird eine Instanz dieser Klasse erzeugt und mit einem java.util.Timer Objekt gestartet. Ist ein TimerTask Objekt einmal gestartet, kann es nicht mehr wieder verwendet werden, von daher muss also für jeden Aufruf der start Methode ein eigenes TimerTask Objekt erzeugt werden. Die Verwendung von Timer und TimerTask kapselt die Programmierung mit Threads. Der Klient kann sich als Observer an die BluetoothGPSReceiver Klasse anmelden und wird beim erfolgreichen Empfang einer GPS-Positionsangabe benachrichtigt. Das GPSData Objekt, welches die GPS-Daten kapselt, bekommt der Klient gleich mit der Benachrichtigung mitgeliefert. Codefragment 7-2 zeigt die typische Verwendung des IGPSReceiver Interfaces. Eine BluetoothGPSReceiver Instanz wird mit der Bluetoothadresse des GPS-Empfängers erzeugt (1). Anschließend wird ein zuvor instanziertes IGPSObserver Objekt angemeldet (2). Die BluetoothGPSReceiver Instanz wird mit einer Periode von 5s gestartet (3). Bei Empfang von GPS-Daten wird der Observer benachrichtigt. Nach dem Verwenden muss die BluetoothGPSReceiver Instanz gestoppt werden (4). Eine nicht gestoppte Instanz würde das Beenden des MIDlets blockieren, da CLDC/MIDP keine Daemon-Threads unterstützt (siehe auch Einschränkungen der Virtuellen Maschine in Kapitel 4.1). Normale Threads laufen nach der Beendigung des Main-Threads weiter und verhindern die Terminierung des Programms. IGPSReceiver receiver = new BluetoothGPSReceiver("btspp://008025040FA9:1"); // (1) IGPSObserver obs = new SomeGPSObserver(); receiver.addObserver(obs); // (2) receiver.start(5000); ... receiver.stop(); // (3) // (4) Codefragment 7-2: Verwendung der GPSReceiver Klasse Schwierigkeiten bei der Implementierung machte das Siemens S65: Der InputStream, der den Bytestrom vom GPS-Empfänger repräsentiert, kann nur 600 Bytes puffern. Kommen mehr Bytes vom GPS-Empfänger, dann stürzt die BluetoothImplementierung auf dem S65 ab. Das Gerät muss anschließend neu gestartet werden. Da der GPS Empfänger ununterbrochen Daten schickt, muss also der InputStream direkt nach dem Lesen der ersten Nachricht geschlossen werden. Das ist eine zeitkritische Operation, denn wenn der InputStream zu spät geschlossen wird, dann läuft unterdessen unter Umständen der Puffer über. Das erklärt auch, warum das IGPSReceiver Interface auch nur einen periodischen Zugriff auf den GPS-Empfänger definiert. Eine dauerhafte Verbindung wäre nämlich mit dem S65 nicht möglich. Dieser Fehler vom S65 wurde auch im Siemens Developer Support Forum [@SIEMENS04] diskutiert. Hier zeigt sich abermals, dass das Softwaredesign leider an die Eigenarten der Geräte angepasst werden muss. Da das Wireless Toolkit keine Verbindungen zu realen Bluetooth-Geräten aufbauen kann, musste das Zusammenspiel zwischen GPSEmpfänger und Mobiltelefon direkt mit den realen Geräten getestet werden. 68 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 7.5.10 Noch nicht implementierte Features Laut dem Anforderungskatalog für eine mobile Geogrid®-Version soll das Zoomen von Kartenausschnitten möglich sein. Mit Zoomen ist nicht der Wechsel auf eine Karte mit anderem Maßstab gemeint, sondern die Vergrößerung oder Verkleinerung auf der Pixelebene. MobileJavaMap besitzt noch keine Zoom-Funktionalität, aber die Architektur ist darauf vorbereitet. Es ist vorgesehen, dass der Kartenserver vergrößerte bzw. verkleinerte Kacheln verschickt, da es in CLDC/MIDP keine Möglichkeit zum Verändern der Bildgröße von Image Objekten gibt. Die Alternative dazu wäre RGB-Werte aus den Image Objekten zu extrahieren und dann in einer selbst geschriebenen Zoommethode ein verändertes neues Image Objekt zu erzeugen. Das kostet allerdings zuviel Rechenleistung und Speicherkapazität (siehe Messungen aus Kapitel 8.4.2). Prototypisch ist auch der Verzicht auf die Höhendaten einer Karte. Technisch gesehen sind die Höhendaten nichts anderes wie ein Bild mit den gleichen Dimensionen wie die dazugehörige Karte. Jeder Farbwert repräsentiert eine bestimmte Höhe. Diese Höhendaten können ebenfalls als PNG verschickt werden, zusätzlich wird die Zuordnung von Farbwert und Höhenwert benötigt. Hierfür müsste der Server einen zusätzlichen Request für die Zuordnung implementieren. Aus den erzeugten Image Objekten können die RGB-Werte extrahiert werden (getRGB Methode), die mit Hilfe der Zuordnungstabelle in Höhendaten umrechnet werden. Da für jeden Pixel 32 Bit verbraucht werden, ist dieser Vorgang aber wie bereits besprochen sehr speicher- und rechenintensiv. Ebenfalls noch offen ist, welches Overlayformat unterstützt wird. Zwar ist die Mehrschichtigkeit der Kartendarstellung realisiert und für Overlays vorbereitet, aber das eigentliche Auswerten von Overlaydaten fehlt. Die Anforderungen sehen die Verwendung des ASCII, Binär oder XML Formates vor. Hier sind noch weitere Untersuchungen notwendig, welches der genannten Formate eingesetzt werden kann. Kapitel 7: 7.6 Mobile Geogrid®-Version mit CLDC/MIDP 69 Controllerschicht Nachdem die Modellschicht besprochen wurde, beleuchtet dieses Unterkapitel die zentralen Elemente der Controllerschicht und erläutert den typischen Programmablauf bei Ereignissen. Konsistenzüberlegungen runden dieses Unterkapitel ab. 7.6.1 Die zentrale Controller Klasse Einstiegspunkt in die Applikation ist das MobileJavaMapMIDlet, welches von der abstrakten MIDlet Klasse ableitet. MIDlets wurden im Kapitel 4.2 vorgestellt. Beim Initialisieren holt es sich über eine statische Konstruktormethode eine Instanz der Controller Klasse. Da nur ein Controller Objekt benötigt wird, implementiert die Controller Klasse das Singleton Pattern [GAMMA96]. Im privaten Konstruktor erzeugt das Controller Objekt Model, View und weitere benötigte Controller Objekte. Zusätzlich enthält die Controller Klasse eine nicht-statische, verschachtelte Klasse namens ActionThread, die von Thread abgeleitet ist. ActionThread wird im nächsten Unterkapitel ausführlicher vorgestellt. Abbildung 7-22 illustriert die erwähnten Klassen. Abbildung 7-22: MobileJavaMapMIDlet und Controller Ähnlich wie in Struts können Initialisierungen in separate Plug-in Klassen ausgelagert werden. Jedes Plug-in implementiert das IPlugIn Interface, das Methoden zum Starten und Zerstören des Plug-ins definiert. Beim „Hochfahren“ der Anwendung werden die Plug-ins gestartet und beim Beenden zerstört. Wenn Abhängigkeiten zwischen den Plug-ins bestehen, müssen sie in der richtigen Reihenfolge aufgerufen werden. Die einzige Implementierung im Prototyp ist das ConfigurationPlugIn, das die Konfi- 70 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP guration aus einem RecordStore ausliest und beim Beenden der Applikation die aktuelle Konfiguration wieder in den RecordStore ablegt. Vorteil bei dieser Lösung ist, dass der Controller nicht überfrachtet wird. So benötigt die Controller Klasse nur rund 400 Zeilen Code (ohne Import Statements). Einen größeren Einfluss auf die Größe der Controller Klasse hat aber das Action-Thread Konzept, dass im nächsten Unterkapitel vorgestellt wird. 7.6.2 Action-Thread Konzept Sun bietet auf der Entwicklerwebseite eine J2ME-Beispiel-Applikation an (Java Smart Ticket Sample Application [@SUN_SMARTTICKET03]), die Designvorschläge und Patterns für J2ME Applikationen enthält. Diese Applikation setzt auf eine zentrale Controllerklasse (UIController), die eine nicht-statische, verschachtelte Klasse namens EventHandler besitzt, die von java.lang.Thread ableitet. Soll eine Aktion durchgeführt werden, so muss die handleEvent Methode der Controllerklasse aufgerufen werden, die als Parameter einen Integerwert (die Event-ID) und ein Object Feld erwartet. Die Event-ID gibt an, welche Aktion durchgeführt werden soll und das Object Feld enthält die für die Aktion notwendigen Parameter. Die aufgerufene Methode erzeugt eine neue Instanz der EventHandler Klasse und übergibt im Konstruktor die erhaltene Event-ID und das Object Feld. Anschließend ruft sie die start Methode der EventHandler Klasse auf und erzeugt somit einen neuen Thread. Dieser Thread entscheidet anhand der Event-ID, welcher Code ausgeführt werden soll. Das dazu notwendige switch-case Statement umfasst somit mehr als 700 Zeilen. Das Sequenzdiagramm in Abbildung 7-23 illustriert den beschriebenen Vorgang am Beispiel eines handleEvent Aufrufs durch ein MovieRatingsUI Objekt (auf das nicht näher eingegangen wird). : MoveRatingsUI : UIController handleEvent(eventID, objectArray) << create >> : EventHandler start() Der Thread geht in den Running Zustand über Abbildung 7-23: Ausführen einer Aktion bei der SmartTicket Applikation Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 71 Aus mehreren Gründen halte ich das für eine schlechte Lösung: Zum einen ist die Wartbarkeit durch diese „Monolith“ Methode eingeschränkt, zum anderen wird bei jeder Aktion ein neuer Thread erzeugt. Gefährlich ist auch der Einsatz eines Object Feldes als Parameter, da der Compiler nicht überprüfen kann, ob alle notwendigen Objekte enthalten sind. Also habe ich nach einer weiteren Lösung gesucht. Bei einer Netzrecherche bin ich auf einen Artikel [@KNUDSEN02] gestoßen, der die Threading Problematik für Netzwerkverbindungen bei MIDP beleuchtet. Er schlägt einen SingleWorker-Thread vor, der direkt nach dem Starten in den Wait-For-Notification Zustand übergeht. Soll eine Netzwerkverbindung geöffnet werden, so wird dieser Thread über notify aufgeweckt. Nach dem Erwachen führt der Thread die Kommunikation aus und geht anschließend wieder in den Wait-For-Notfication Zustand zurück. Ich habe die Idee übernommen und so modifiziert, dass der Thread beliebige Aktionen ausführen kann. Dabei werden die Aktionen in Objekte gekapselt, die alle das gleiche Interface implementieren. Bevor der Thread aufgeweckt wird, wird dem Thread Objekt das auszuführende Aktionsobjekt übergeben. Die Idee, Aktionen in Objekte zu kapseln, ist dem Entwurfsmuster „Command“ (Befehl) entnommen (siehe [GAMMA96]). Allerdings kann ein Aktionsobjekt in MobileJavaMap mehrere Empfänger besitzen, im „Command“ Muster ist dagegen nur ein Empfänger vorgesehen. Die notwendigen Referenzen der Empfänger holt sich das Aktionsobjekt über die ihm bekannte Controller Instanz. Abbildung 7-24: ActionThread und IAction Alle Aktionsobjekte implementieren das IAction Interface, das Methoden zum Ausführen und Abbrechen einer Aktion spezifiziert (execute und cancel). Als Übergabeparameter erwarten die beiden Methoden eine Referenz auf das Controller Objekt. Wenn ein IAction Objekt auf Objekte oder primitive Datentypen zugreifen muss, die nicht über die Controller Instanz hergeholt werden können, müssen die benötigten Referenzen bzw. primitiven Datentypen explizit im jeweiligen Konstruktor des IAction Objekts übergeben werden. Erzeugt werden die Aktionsobjekte bei Ereignissen von den Viewklassen. Der Single-Worker-Thread wird durch die Klasse ActionThread repräsentiert, die neben der obligatorischen run Methode die notifyAction und cancelAction Methoden definiert. Das Sequenzdiagramm in Abbildung 7-25 zeigt den typischen Verlauf anhand der Ausführung der LoadMapAction. 72 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP Die als Beispiel dienende Situation ist folgendermaßen: Der Anwender wählt aus einer Liste von Karten die nachzuladende Karte aus. Die MapListUI Klasse implementiert das CommandListener Interface und reagiert auf das Command-Ereignis. 1. Zunächst erzeugt das MapListUI Objekt eine Instanz der der LoadMapAction Klasse und übergibt dabei den MapIdentifier der gewählten Karte. 2. Das erzeugte LoadMapAction Objekt wird der executeAction Methode der Controller Instanz übergeben. 3. Diese wiederum ruft damit die notifyAction Methode ihres ActionThread Objekts auf. 4. Dort wird das übergebene LoadMapAction Objekt als Instanzvariable abgelegt und die notify Methode des eigenen Objektes (ActionThread) aufgerufen. 5. Der Thread, der sich bis jetzt in dem Wait-For-Notification Zustand befand, setzt die Ausführung fort und ruft die execute Methode des LoadMapAction Objekts auf. 6. Nach der Ausführung geht der Thread mit dem wait Befehl wieder in den Wait-For-Notification Zustand zurück und wartet auf die nächste Aktivierung. : MapListUI : Controller : ActionThread << create >> action : LoadMapAction executeAction (action) notifyAction(action) notify() execute(controllerInstance) Der Thread geht in den Running Zustand über wait() Der Thread geht wieder in den Wait-For-Notification Zustand über Abbildung 7-25: Ausführen einer Aktion über den ActionThread Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 73 Diese Lösung führt dazu, dass der Controller-Code aus der Controller Klasse in viele, separate Aktionsklassen ausgelagert wird. Das empfinde ich als übersichtlicher und weniger fehleranfällig. Zudem wird kein Object Feld als Parameterbehälter benötigt. Das sorgt für eine bessere Fehlererkennung beim Kompilieren, da die Konstruktoren der Aktionklassen primitive Typen und/oder Referenzen von bestimmten Typen erwarten. Im Gegensatz zur Lösung von Sun wird bei jeder Aktion immer derselbe Thread wieder verwendet. [@KNUDSON02] weist darauf hin, dass die Erzeugung eines neuen Threads viel Prozessorleistung und Speicher verbraucht. Allerdings ist mit den modernen Mobiltelefonen dank Monty-VM (siehe Kapitel 4.1) eine Thread-Erzeugung nicht mehr so teuer: Auf dem K700i wird ein neuer Thread in ca. 1ms mit einem Speicherverbrauch von 1300 Bytes erzeugt. 7.6.3 Konsistenzüberlegungen Im „Vertrag“ des Interfaces IAction wird die cancel Methode als Wunsch zum Abbrechen definiert. Bei Aktionen, die zur Ausführung wenig Zeit benötigen, kann die Aktionsklasse diesen Abbrechwunsch ignorieren. Aktionsklassen, die eventuell blockierende oder länger dauernde Aktionen wie z.B. das Herunterladen von Kartendaten ausführen, sollten aber einem Abbrechwunsch Folge leisten. Technisch gesehen ruft der Main-Thread die cancel Methode auf, während der ActionThread noch in der execute Methode „steckt“. Beim Abbrechen muss allerdings die Konsistenz der Modelobjekte gewährleistet sein. Wenn z.B. eine Sektion nachgeladen wird, dann löscht die aktuelle Implementierung SquareSectionBuilder die alten, nicht mehr benötigten Kacheln aus der Sektion, bevor er die neuen Kacheln vom IMapDataProvider Objekt holt. Ansonsten wäre für die neuen Kacheln nicht genügend Speicher mehr frei. Wenn jetzt aber die Aktion während dem Runterladen der Kacheln abgebrochen wird, dann ist diese Sektion nicht mehr konsistent, da einige Kacheln bereits gelöscht wurden und einige der neuen Kacheln durch den Abbruch nicht mehr geladen werden konnten. Es bieten sich nun mehrere Möglichkeiten an, eine konsistente Sektion zu erzeugen: Zum einen könnten die fehlenden Kacheln durch einfarbige Flächen ersetzt werden, so dass wieder eine konsistente Sektion entsteht. Eine elegantere Variante wäre, die aus dem Speicher gelöschten Kacheln wieder aus dem Cache zu laden, und damit die ursprüngliche Sektion wieder herzustellen. Die neuen, bereits vom Server geladenen Kacheln, die das IMapDataProvider Objekt zurückgegeben hat, werden in den Cache abgelegt, damit die Downloadzeit und –kosten nicht umsonst gewesen sind. In MobileJavaMap ist noch keine der beiden Varianten implementiert, die Sektion ist beim Abbruch inkonsistent. Hier zeigt sich erneut der prototypische Charakter von MobileJavaMap. 7.7 Viewschicht Im klassischen MVC-Konzept kennt die View-Schicht das Model und leitet Benutzerereignisse an den Controller weiter. In MobileJavaMap kennen jedoch nicht alle Viewklassen die Modellklassen. Genauer gesagt, kennen die High-Level-LCDUI Komponenten ihr Model nicht, sie werden stattdessen von Aktionsklassen mit den notwendi- 74 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP gen Daten vor Ihrer Anzeige gefüllt. Dieses Kapitel betrachtet neben den Interaktionen der Viewklassen mit dem Controller auch die eigentliche Darstellung der Karte. 7.7.1 High-Level-LCDUI Komponenten für die Menüführung Für die Menüführung von MobileJavaMap bietet sich die Verwendung der bereits in Kapitel 4.5.1 vorgestellten High-Level-LCDUI Komponenten an. Je nach Verwendungszweck der Viewklasse leitet sie von javax.microedition.lcdui.List oder javax.microedition.lcdui.Form ab. Die Form Klasse repräsentiert ein Formular, das mit Formularelementen wie z.B. Textfeldern, Datumsfeldern oder Auswahllisten gefüllt werden kann. Dagegen werden List Objekte ausschließlich zur Darstellung von Listen verwendet. Sowohl Form als auch List sind von der abstrakten Screen Klasse abgeleitet, die die Basisklasse für alle High-Level-LCDUI Komponenten bildet. Konkretes Beispiel für ein Formular in MobileJavaMap ist die OptionsUI Klasse, die die das Optionsmenü repräsentiert. Für die Optionseinstellungen wird neben Textfeldern auch eine Auswahlliste benötigt. Das Startmenü von MobileJavaMap gestaltet sich einfacher und bietet nur ein Menü in Listenform an. Von daher leitet die zuständige StartUI Klasse von List ab. Abbildung 7-26 stellt die beiden Klassen dar. Abbildung 7-26: StartUI und OptionsUI Bevor eine Viewklasse angezeigt wird, füllt der Controller sie bei Bedarf mit den anzuzeigenden Werten. Konkret können sich nur in den Viewklassen MapListUI und OptionsUI Werte ändern. (MapListUI stellt die verfügbaren Karten in Listenform dar). Da sich zum Zeitpunkt der Darstellung dieser Viewklassen das zugrunde liegende Modellobjekt nicht ändern kann, muss es auch nicht überwacht werden. Jede Viewklasse erzeugt im Konstruktor die notwendigen Command Objekte und implementiert den eigenen CommandListener. Bei einem Command Ereignis erzeugt die Viewklasse das passende IAction Objekt und übergibt es (wie bereits in Kapitel 7.6.1 erläutert) Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP 75 der Controller Instanz zur Ausführung. Zum besseren Verständnis betrachten wir den Ablauf, wenn aus dem Startmenü das Optionsmenü aufgerufen wird. 1. Die commandAction Methode der StartUI Klasse erzeugt eine neue Instanz der ShowOptionsAction und übergibt sie dem Controller. 2. Der wiederum übergibt das Objekt an den ActionThread. 3. Der ActionThread ruft die execute Methode der ShowOptionsAction auf. 4. execute holt die Werte aus dem Configuration Objekt (welches die Optionseinstellungen kapselt) und füllt das OptionsUI Objekt mit den darzustellenden Werten. 5. Abschließend bringt die execute Methode das OptionsUI Objekt auf den Bildschirm. Die dargestellte Lösung ist sehr einfach und für den Prototyp mehr als ausreichend. Die Idee, dass der Controller die Viewklassen „füllt“, ist ebenfalls in der bereits erwähnten Smart Ticket Sample Application implementiert. Momentan gibt es keinen Grund für die Viewklassen, das jeweilige Objekt zu überwachen. Sollte das später jedoch der Fall sein, so ist das Konzept nach dem MVC-Konzept zu überarbeiten: Die Viewklassen müssten entsprechende Observer Interfaces implementieren und das Modellobjekt im Konstruktor übergeben bekommen. Zudem müssten die jeweiligen Aktionsklassen wie ShowOptionsAction den Zustand der Viewklasse nicht mehr ändern, sondern nur sie nur noch auf dem Bildschirm bringen. 7.7.2 Low-Level-LCDUI Komponenten für die Kartendarstellung Für eine Kartendarstellung eignet sich nur die Verwendung der Low-Level API, denn nur mit ihrer Hilfe können die einzelnen Kacheln zu einem ganzen Kartenausschnitt zusammengefügt und dargestellt werden. Wichtig ist auch die sofortige Ereignisverarbeitung auf Tastendruck, beispielsweise wenn die Karte gescrollt werden muss. Das ist in einer CLDC/MIDP Umgebung ebenfalls nur mit der Low-Level API möglich. Laut dem Anforderungskatalog muss die Darstellung in der Lage sein, einzelne Schichten (Overlays) über die eigentliche Karte zu legen. Ein Beispiel für so ein Overlay wäre die Anzeige aller Hotels als Icons auf der Karte. Nahe liegend wäre der Einsatz des LayerManagers der bereits in Kapitel 4.5.3 vorgestellten Game API. Allerdings erlaubt die abstrakte Layer Klasse wegen des paketprivaten Konstruktors bewusst keine eigenen Implementierungen. Bei erlaubter Ableitung bestünde die Gefahr, dass bei einer nächsten Version der Game API sich die Layer Klasse ändert und damit die eigene Implementierung nicht mehr funktioniert. Auch der in Kapitel 4.5.3 vorgestellte TiledLayer kann nicht eingesetzt werden, da er ein einziges Image Objekt in mehrere „virtuelle“ Kacheln aufteilt, mit denen eine „Spielwelt“ zusammengestellt wird. MobileJavaMap benötigt aber ein Layer, der aus mehreren separaten Image Objekten ein einziges Bild (den Kartenausschnitt) formt. 76 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP Abbildung 7-27: LayerManager und Layer von MobileJavaMap Aus diesen Gründen implementiert MobileJavaMap einen eigenen LayerManager, eine eigene Layer Klasse und eine MapLayer Klasse (siehe Abbildung 7-27). Während die eigene Layer Klasse bis auf den paketprivaten Konstruktor identisch mit dem Original ist, besitzt die eigene LayerManager Klasse gegenüber Ihrem Vorbild zusätzliche Funktionalität: So unterstützt sie die PixelCoordinate Klasse für die Speicherung der Koordinaten und erlaubt eine Überwachung des ViewWindows durch mehrere Observer, die das IViewWindowObserver Interface implementieren. Für das Zeichnen der Kacheln ist die MapLayer Klasse verantwortlich, die im Konstruktor ein ISection Objekt erwartet, das die zu zeichnenden Kacheln enthält. Beim Aufruf der paint Methode zeichnet das MapLayer Objekt die in der Sektion enthaltenen Kacheln auf den Bildschirm. Weitere Unterklassen von Layer sind POILayer („Point of Interest“ Layer) und ReferencePointLayer. POILayer ist nur eine prototypische Demonstrationsklasse für die Darstellung von mehreren „Points Of Interests“. ReferencePointLayer zeichnet dagegen den zuvor gesetzten Referenzpunkt. Abbildung 7-28 illustriert das Übereinanderlegen von drei Layern durch den LayerManager. Dabei ist die Reihenfolge bzw. die Priorität der Layer von entscheidender Bedeutung. In unserem Falle besitzt die MapLayer Instanz die geringste und die ReferencePointLayer die höchste Priorität. Beginnend mit dem Layer mit der geringsten Priorität ruft der LayerManager beim Zeichnen die einzelnen paint Methoden der Layer auf. Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP MapLayer POILayer 77 ReferencePointLayer Abbildung 7-28: Zusammensetzen der Layer Für das Aufrufen der LayerManager Instanz ist die von Canvas abgeleitete Klasse MapUI Klasse verantwortlich (siehe Abbildung 7-29). In ihrer paint Methode ruft sie die paint Methode der LayerManager Instanz auf. Um auf Tastatureingaben reagieren zu können, muß die MapUI Klasse einen eigenen Thread starten, der den Tastaturstatus abfragt und das Display neu zeichnen lässt. Im Gegensatz zu den besprochenen High-Level-LCDUI Komponenten kennt die MapUI Klasse ihr Modellobjekt (das IMap Objekt) und reagiert auch auf Ereignisse. Beispielsweise implementiert die MapUI Klasse das IGPSObserver Interface und observiert somit eine IGPSReceiver Instanz, die periodisch neue GPS-Positionsdaten an Ihre Observer schickt. Bei Empfang eines neuen GPS-Signals zentriert die MapUI Klasse die Karte zur empfangenen Position. Abbildung 7-29: MapUI Klasse 78 7.8 Kapitel 7: Mobile Geogrid®-Version mit CLDC/MIDP Zusammenfassung In diesem Kapitel wurde MobileJavaMap vorgestellt, die mobile Geogrid®-Version für CLDC 1.1/MIDP 2.0 kompatible, mobile Geräte. Nach der Funktionalitätsbeschreibung wurden die einzelnen Architekturschichten der Applikation besprochen. Neben den Problemen und deren Lösungen wurden auch grundlegende Designentscheidungen begründet. Der entstandene Prototyp hat sich als praxistauglich erwiesen und kann als Grundlage für ein kommerzielles Produkt verwendet werden. Allerdings ist aus technischen Gründen keine direkte Speicherung der Karten auf MIDP-fähigen Geräten möglich. Der Prototyp muß also die Kartendaten im PNG-Format von einem Kartenserver beziehen. Die empfangenen Kartendaten werden mit Hilfe des RMS auf dem Gerät persistent gecached. Mangels Unterstützung der Netzbetreiber sowie fehlender integrierter GPS-Empfänger scheitert der Einsatz der Location API. Die Alternative dazu ist die Ansteuerung eines Bluetooth-GPS-Empfängers über die Bluetooth API. Das ActionThread Konzept sorgt für eine Entlastung der zentralen Controller Klasse, in dem es Aktionen in Objekte kapselt und diese durch einen Single-Worker-Thread ausführen lässt. Sämtliche Menüs werden mit High-Level-LDCUI Komponenten realisiert, die Kartendarstellung kann dagegen nur mit Low-Level-LCDUI Komponenten umgesetzt werden. Allerdings konnte die MIDP-eigene Game API nicht verwendet werden, so dass eine eigene Lösung für die Kartendarstellung implementiert werden musste. Da für die Entwicklung von CLDC/MIDP Applikationen besondere Tools notwendig sind, werde ich meine Erfahrungen mit der Entwicklungs- und Testumgebung im nächsten Kapitel vorstellen. Kapitel 8: 8 Erfahrungen mit der Entwicklungsumgebung 79 Erfahrungen mit der Entwicklungsumgebung Dieses Kapitel fasst die Erfahrungen mit der Entwicklungsumgebung zusammen, die bei der Entwicklung von MobileJavaMap entstanden sind. 8.1 Netbeans 4.0 Netbeans 4.0 ist eine kostenlose, quelloffene Entwicklungsumgebung für Java, die von Sun gesponsert wird. Sowohl der Kartenserver als auch MobileJavaMap wurde mit Hilfe dieser IDE entwickelt und getestet. Netbeans unterstützt die J2EE 1.3 (Servlet 2.3 und JSP 1.2) und J2EE 1.4 (Servlet 2.4 und JSP 2.0) Spezifikationen und erleichtert mit einem integrierten Tomcat Server die Entwicklung von Webapplikationen. Allerdings verzichtet Netbeans 4.0 auf die Unterstützung von EJBs (Enterprise JavaBeans). Erst ab der kommenden Version 4.1. ist die EJB-Unterstützung Bestandteil der IDE. Ein separat erhältliches „Mobility-Pack“ integriert das Wireless Toolkit 2.1 und erlaubt komfortables Erstellen und Testen von MIDlets. Dabei wird der bereits in Kapitel 4 erläuterte Pre-Verfication und Obscufation Prozess automatisiert. CDC/Personal Profile wird dagegen nicht unterstützt. Als Antwort auf die Vielzahl der J2ME-Spezifikationen und Geräte bietet Netbeans die Unterteilung eines Projektes in verschiedene Konfigurationen an. Eine Konfiguration in Netbeans hat aber nicht mit einer J2ME-Konfiguration zu tun. Pro Konfiguration können die zu kompilierenden Klassen ausgewählt werden. Darüber hinaus können Zeilen einer oder mehrerer Quelldateien zu einer Konfiguration zugeordnet werden. Ein Präprozessor wertet diese Angaben vor dem Kompilieren aus und entfernt Zeilen, die nicht zu der aktuellen Konfiguration gehören. Das bringt durchaus Vorteile für den Entwickler, allerdings besteht die Gefahr, dass bei übermäßigem Einsatz der Code dadurch unleserlich wird. Zudem bindet man sich mit zunehmender Verwendung der Konfigurationsverwaltung an die Netbeans IDE, da sie von anderen IDEs nicht unterstützt wird. Von daher wird in MobileJavaMap dieses Feature nur an einer einzigen Stelle verwendet: Bei der Instanzierung der IMapDataProvider Instanz. Die DummyDataProvider-Konfiguration instanziert ein DummyMapLocalDataProvider Objekt, während die Standardkonfiguration an dieser Stelle ein HTTPMapDataProvider Objekt erzeugt. Zusätzlich enthält die DummyDataProvider-Konfiguration die notwendigen Kartendaten in der MIDlet-Suite. Ansonsten unterscheiden sich die beiden Konfigurationen nicht. Abbildung 8-1 zeigt, wie einzelne Quellzeilen zu einer Konfiguration zugeordnet werden. Für weitere Unterscheidungen werden die Sprachfeatures von Java ausgenützt, beispielsweise wird die Existenz der Bluetooth API mit der forName Methode der Class Klasse überprüft. 80 Kapitel 8: Erfahrungen mit der Entwicklungsumgebung Abbildung 8-1: Zuordnen von Zeilen zu einer Konfiguration Ebenfalls erwähnenswert ist das auf Apache Ant basierende Buildsystem von Netbeans, das Transparenz in den Buildprozess bringt. Apache Ant ist ein Tool, das den Buildprozess automatisiert. Sämtliche für den Build erforderlichen Aktionen werden in XMLbasierten Ant-Skripten definiert. Jeder Projekttyp in Netbeans basiert auf einem AntSkript, das zusätzlich über Konfigurationsdateien angepasst wird. Dem Entwickler steht es frei, die Ant-Skripte zu erweitern oder komplett neue zu schreiben. Beispielsweise habe ich die JavaDoc Generierung so modifiziert, dass sie das /src Verzeichnis als Ausgangsverzeichnis verwendet. Standardmäßig werden die Quelldateien des /preprocessed Verzeichnisses zur JavaDoc Generation ausgewertet. Die Änderung war notwendig, damit die im /src Verzeichnis befindlichen HTML-Dateien bei der JavaDoc Generierung berücksichtigt werden. Leider bietet Netbeans keine direkte Unterstützung für JavaDoc auf Packageebene (Package Level Javadoc) an, die HTMLDateien muss man von Hand anlegen. Netbeans besitzt eine leistungsfähige Code Completion Funktion, die sogar über den Methoden eines Objektes sogar den passenden JavaDoc Kommentar einblendet (siehe Abbildung 8-2). Das erspart Kontextwechsel zwischen IDE und Internetbrowser. Abbildung 8-2: Code Completion mit Javadoc Kapitel 8: Erfahrungen mit der Entwicklungsumgebung 81 Zu Beginn der Entwicklungsphase von MobileJavaMap war nur die erste, sehr abstürzfreudige Betaversion von Netbeans 4.0 verfügbar. Oftmals musste nach einem Absturz von Netbeans der Netbeans-Cache von Hand gelöscht werden, damit die IDE überhaupt erst wieder gestartet werden konnte. Erst ab dem ersten Release Candidate wurde ein hoher Stabilitätsgrad erreicht und somit ein reibungsloser Einsatz der IDE ermöglicht. Die endgültige Releaseversion läuft sehr stabil und ist mir noch kein einziges Mal abgestürzt. 8.2 J2ME Wireless Toolkit Das Wireless Toolkit wurde im Zusammenhang mit J2ME bereits vorgestellt. Hier geht es nur die Unterschiede vom Emulator zu den richtigen Endgeräten. Während der Entwicklungsphase hat sich herausgestellt, dass zwischen dem Verhalten des Emulators und der tatsächlichen Implementierung auf einem Mobiltelefon einige gravierende Unterschiede bestehen. Neben den bereits in Kapitel 7.5.2 besprochenen Differenzen beim Erzeugen von Image Objekten verhalten sich auch andere Methodenaufrufe von Plattform zu Plattform unterschiedlich. Beispielsweise erlaubt die List Klasse des Emulators das Anmelden eines Select-Command Objektes an eine leere Liste, während die List Klasse auf dem Sony Ericsson K700i bei diesem Versuch eine ArrayIndexOutOfBoundsException wirft. Also musste der Code so umgeschrieben werden, dass nur dann ein Command Objekt angemeldet wird, sobald die Liste einen oder mehr Einträge besitzt. Ein weiteres Beispiel ist das Öffnen einer HTTP-Connection: Wenn das MIDlet nach der Installation auf dem K700i zum ersten Mal gestartet wird, dann wird beim Öffnen einer HTTP-Connection eine IOException geworfen. Beim erneuten Start tritt dieser Fehler nicht mehr auf. Die genaue Ursache konnte ich nicht lokalisieren, auf dem Emulator tritt dieser Fehler nicht auf. Der Fehler könnte auch mit der Simulierung der Internetverbindung zusammenhängen, denn das K700i erlaubt mit dem Sony Ericsson SDK eine virtuelle GPRS Verbindung über Bluetooth. Das Sony Ericsson SDK wird im nächsten Unterkapitel vorgestellt. 8.3 Sony Ericsson SDK Neben einer modifizierten Version des Wireless Toolkit enthält das SDK das ConnectionProxy und DeviceExplorer Tool. Ersteres öffnet über die serielle Schnittstelle eine Verbindung zu einem J2ME-fähigen Sony Ericsson Mobiltelefon. Das Bluetooth Serial Port Profile erlaubt die Simulation einer seriellen Schnittstelle, von daher wird kein spezielles Verbindungskabel benötigt. Ist die Verbindung zwischen PC und Mobiltelefon hergestellt, dann können MIDlets über das DeviceExplorer Tool auf dem Mobiltelefon installiert und verwaltet werden. Beim Ausführen eines MIDlets wird die Standardausgabe des Geräts dargestellt. Ein weiteres sehr praktisches Feature ist die Simulation einer Internetverbindung, dabei agiert der PC als Proxy für das Mobiltelefon. Wäre das nicht möglich, müsste das Gerät über GPRS ins Internet gehen und würde somit hohe Kosten verursachen. Zudem müsste der Kartenserver im Internet erreichbar sein, das ist dank des ConnectionProxy Tools nicht nötig. Abbildung 8-3 zeigt beide Tools im Ein- 82 Kapitel 8: Erfahrungen mit der Entwicklungsumgebung satz. Im Vordergrund befindet sich das ConnectionProxy Tool, das mit dem K700i verbunden ist. Im Hintergrund sieht man die Standardausgabe vom Mobiltelefon. Abbildung 8-3: Debugging mit dem Sony Ericsson SDK Kapitel 9: 9 Fazit 83 Fazit Die J2ME-Welt ist schwer zu überschauen, sie ist ein Sammelsurium von Spezifikationen, die teilweise nur auf Papier existieren. Bestes Beispiel ist die Webservices API, die noch in keinem mobilen Gerät zu finden ist. Auch die unterschiedlichen Versionen und Kombinationen der Konfigurationen und Profile machen dem J2ME-Entwickler das Leben nicht leichter. Neben den Restriktionen in Speicher, Geschwindigkeit und Funktionalität ist vor allem die heterogene Gerätelandschaft ein gravierendes Problem bei der J2ME-Entwicklung. Die Diplomarbeit hat gezeigt, dass die Darstellung von georeferenzierten, rasterbasierten Karten mit mobilen Geräten mit CLDC 1.1/MIDP 2.0 und CDC/Personal Profile dennoch möglich ist. Die vorgestellte mobile Geogrid®-Version MobileJavaMap wurde für eine CLDC 1.1/MIDP 2.0 Umgebung konzipiert und entwickelt. Von daher beziehen sich die nachfolgenden, zusammengefassten Ergebnisse nur auf diese Konfiguration/Profil Kombination. Welche konkreten Einschränkungen bei einer CDC/Personal Profile Implementierung in Kauf genommen werden müssen, muss in einer weiteren Arbeit untersucht werden. Aufgrund der Speicher- und Funktionalitätseinschränkungen von CLDC 1.1/MIDP 2.0 konnte die Softwarearchitektur von JavaMap nicht übernommen werden. Einzig die Kapselung der Projektionen konnte in MobileJavaMap wieder verwendet werden. Um der heterogenen Gerätelandschaft gerecht zu werden, setzt die neukonzipierte Architektur stark auf Interfaces und kommt mit den technischen Einschränkungen zurecht. Um eine möglichst plattformunabhängige Implementierung zu realisieren, wurde auf optionale Pakete verzichtet (Einzige Ausnahme: Bluetooth API). Aber selbst das garantiert nicht die Lauffähigkeit auf allen CLDC 1.1/MIDP 2.0 kompatiblen Geräten, da sich die Herstellerimplementierungen in einigen Fällen unterschiedlich verhalten. Zudem unterscheiden sich die mobilen Geräte auch dramatisch in der Speicher- und Rechenleistung. Um die Lauffähigkeit von MobileJavaMap für ein bestimmtes mobiles Gerät zu garantieren, muss es direkt am Gerät getestet werden. Ein Emulatortest oder das Vertrauen auf Angaben aus einem Whitepaper reichen nicht aus. Insbesondere BluetoothVerbindungen mit anderen Bluetooth-Geräten können nur mit dem Gerät selbst getestet werden, was zusätzlichen Zeitaufwand bei der Entwicklung bedeutet. Da CLDC/MIDP keinen direkten Zugriff auf das Dateisystem vorsieht, muss MobileJavaMap die Kartendaten von einem Server beziehen. Dieser konvertiert das KMRG- ins PNG-Format und schickt den erzeugten Kartenausschnitt, in mehreren Kacheln aufgeteilt, an das mobile Gerät. Das Cachen von heruntergeladenen Informationen wie Kartendaten und Kacheln, ist mit dem RMS machbar, wobei sehr viel Verwaltungsaufwand betrieben werden muss. Trotz Caching ist der jetzige Einsatz des Prototyps für den Endanwender sehr teuer, da durch den Empfang der Kacheln hohe Übertragungskosten entstehen. Zudem sind GPRS Verbindungen recht langsam. Aber mit zunehmender Verbreitung von UMTS-Mobiltelefonen und Flatrateangeboten werden die Kosten- und Geschwindigkeitsprobleme mit hoher Wahrscheinlichkeit in absehbarer Zeit entschärft. 84 10 Kapitel 10: Ausblick Ausblick Die Entwicklungszyklen von mobilen Geräten sind sehr kurz, die Speicher- und Recheneinschränkungen werden in einem Jahr nicht mehr so gravierend sein wie heute. Das Sony Ericsson K700i besitzt beispielsweise nur 512KB RAM, mit so wenig Speicher auf einem Mobiltelefon wird man sich in Zukunft hoffentlich nicht mehr auseinander setzen müssen. Mit steigender Hardwareleistung wird wahrscheinlich auch das CDC/Personal Profile verstärkt unterstützt, was erheblich mehr Funktionalität ermöglicht. Problematisch bleibt aber die Zersplitterung der J2ME Plattform, eine Besserung ist nicht in Sicht. Die Konfigurationen, Profile und optionale Pakete erfordern eine hohe Flexibilität der Software. Um die Anzahl von unterschiedlichen Versionen der Software gering zu halten, muss sich die Software dynamisch zur Laufzeit an die Umgebung anpassen. Ab 2007 muss in Japan jedes Mobiltelefon über einen eingebauten GPS-Empfänger verfügen. Somit wird auch in Europa die Anzahl der Mobiltelefone mit eingebautem GPS-Empfänger steigen, was wiederum viele potentielle Kunden für ortsbezogene Dienste (Location Based Services) bedeutet. Neben dem Herunterladen von Point of Interests könnte aber auch die aktuelle Position eines Mobiltelefons in bestimmten Zeitabständen an einen Server geschickt werden. Zum einen könnte dadurch bei Notfällen eine Person genauer lokalisiert werden, gleichzeitig besteht aber auch die Möglichkeit bzw. Gefahr einer lückenlosen Überwachung. Eines ist aber sicher: Der Markt für mobile Anwendungen und Dienste bleibt spannend. Kapitel 11: 11 Glossar 85 Glossar Abkürzung bzw. Begriff Erläuterung AMS Application Management Software. Systemsoftware zur Verwaltung von Applikationen auf MIDP-fähigen mobilen Geräten. API Application Programming Interface. Programmierschnittstelle für gekapselte Funktionalität. AWT Abstract Window Toolkit. Java GUI-Framework. CDC Connected Device Configuration. J2ME-Konfiguration für PDAs, Set-Top Boxen und leistungsfähigere Mobiltelefone. CLDC Connected Limited Device Configuration. J2ME-Konfiguration für Mobiltelefone und Pager. CORBA Common Object Request Broker Architecture. Sprachunabhängiger, offener Standard zu objektorientierter Kommunikation zwischen vernetzten Computern. DOM Document Object Model. Sprachunabhängige API für XML und HTML Dokumente. EJB Enterprise JavaBeans. Serverseitiges Komponentenframework für Java2 Enterprise Edition zur Modellierung von Geschäftsobjekten. GCF Generic Connection Framework. Java Framework für Netzverbindungen. GPRS General Packet Radio Service. Paketorientierter Standard für den Datenaustausch in GSM Netzen. GPS Global Position System. Satellitengestütztes System zur weltweiten Positionsbestimmung. GSM Global System for Mobile Communications. Mobilfunkstandard der zweiten Generation. HTTP Hypertext Transfer Protocol. Zustandsloses Datentransferprotokoll in der Anwendungsschicht. HTML Hypertext Markup Language. Beschreibungssprache für Dokumente im Netz. IMP Information Module Profile. J2ME-Profile für Geräte ohne oder mit sehr einfachem Display. JAXP Java Apis for XML Processing. APIs zur Erstellung und Bearbeitung von XML Dokumenten mit Java. JDBC Java Database Connectivity. Java-API zum Zugriff auf ein Datenbanksystem J2EE Java2 Enterprise Edition. Java-Plattform für Serversysteme. J2ME Java2 Mobile Edition. Java-Plattform für mobile Geräte. J2SE Java2 Standard Edition. Java-Plattform für Desktoprechner. JavaBeans Komponentenframework für Java2 Standard Edition. JSP Java Server Page. Eine JSP-Seite enthält neben statischen Text auch Codeanweisungen für die Generierung von dynamischen Inhalten. KMRG Komprimierte MilGeo-Rastergrafik. Standardisiertes Rasterkartenformat für militärische Zwecke. KVM Kilo Virtual Machine. Referenzimplementierung für die in der CLDC Spezifikation geforderten Virtuellen Maschine. LCDUI Lowest Common Denominator User Interface. GUI-Framework für MIDP- 86 Kapitel 11: Glossar fähige mobile Geräte. MAPS Map Preparation Software. Verschlüsseltes Kartenformat für zivile Karten. MIDP Mobile Information Device Profile. J2ME-Profil für Mobiltelefone und Pager. PIM Personal Infomation Management. Verwaltung von Kalendereinträgen und Adressen. POI Point of Interest. Ein Punkt auf einer Karte, der für den Betrachter von Interesse sein könnte, beispielsweise ein Hotel oder eine Tankstelle. UML Unified Modelling Language. Standardisierte, grafische Modellierungssprache zur Darstellung von Softwaresystemen. UMTS Universal Mobile Telecommunications System. Mobilfunkstandard der dritten Generation. Nachfolger von GSM. UTM Universal Transversal Mercator. Projektion, die die Basis für ein weltweites Koordinatensystem bildet. RMI Remote Method Invocation. Mechanismus für den Objektaufruf auf entfernten Computern. RMS Record Management kompatible Geräte. SAX Simple API for XML. SAX definiert Richtlinien für XML Parser. SDK Software Development Kit. Eine Sammlung von Programmen, die die Entwicklung von Software ermöglichen bzw. erleichtern. Servlet Ein Servlet ermöglicht serverseitige Applikationen, die über das Frage Antwort (request-response) Modell angesprochen werden können. Swing Komponentenorientiertes, leichtgewichtiges GUI-Framework für Java. WMS Web Map Service. Im Internet stehender Dienst, der georefernziertes Kartenmaterial anbietet. XML Extensible Markup Language. Textbasierte Beschreibungssprache zur Definition von strukturierten Daten. System. Satzbasierte Datenbank für MIDP- Kapitel 12: 12 Anhang 87 Anhang 12.1 Installation von MobileJavaMap auf ein Siemens S65 Da das S65 keine Simulation der Internetverbindung ermöglicht, kann nur die DummyDataProvider-Konfiguration von MobileJavaMap installiert werden. 1. Kompilieren der DummyDataProvider Konfiguration. Abbildung 12-1: Auswahl der DummyDataProvider Konfiguration 2. Bluetooth OBEX Verbindung mit S65 aufbauen. 3. Erstellen eines Unterverzeichnisses namens MobileJavaMap in \Data\Java\jam\Applications. 4. Kopieren von MobileJavaMap.jar und MobileJavaMap.jad von ..\MobileJavaMapCLDC\dist\DummyDataProvider\ ins \Data\Java\jam\Applications\MobileJavaMap\ Verzeichnis. 5. Auf dem S65 kann MobileJavaMap unter Surf & Fun > Anwendungen gestartet werden. 12.2 Installation von MobileJavaMap auf ein SE K700i Für die Simulation der Internetverbindung müssen auf dem K700i folgende Einstellungen gemacht werden: 1. Neues Datenkonto erstellen unter Verbindungen > Datenübertragung > Datenkonten > Neues Konto. 2. Alle Parameter bis auf den Namen freilassen. Der Name kann frei gewählt werden. Datenkonto anschließend abspeichern. 3. Ein neues Internetprofil erstellen unter Verbindungen > InternetEinstellg. > Internet-Profile > Neues Profil. Der Name ist ebenfalls beliebig. Unter Verbinden mit das zuvor erstellte Datenkonto auswählen. Der Internet-Modus ist WAP, die IP-Adresse die Adresse des Computers (bsp. 192.168.0.2). Das Profil anschließend abspeichern. 4. In der Profilübersicht das erstellte Profil als Standardprofil auswählen. 88 Kapitel 12: Anhang Man kann das MIDlet auch direkt über eine OBEX-Verbindung kopieren, hier wird aber das Installieren mit dem Sony Ericsson SDK beschrieben. 1. Kompilieren der DefaultConfiguration Konfiguration (wenn noch nicht vorhanden). 2. Starten des ConnectionProxy Tools. 3. Unter File > Settings den richtigen COM Port und die maximale Übertragungsgeschwindigkeit auswählen. 4. Auf Connect klicken. 5. Starten des DeviceExplorer Tools. 6. Serial Networking aktivieren (File > Serial Networking) 7. Wenn das Tool „hängt“, dann einfach auf dem K700i in das Hauptmenü gehen. Dann wird die Blockade aufgehoben. 8. Unter File > Install... die MobileJavaMap.jar auf das Gerät laden. 9. Nach erfolgreicher Installation taucht das MIDlet in der MIDlet-Liste des DeviceExplorer Tools auf. 10. Von dort kann es gestartet werden. 12.3 MobileJavaMap Bedienungsanleitung Dieses Unterkapitel stellt die Bedienung von MobileJavaMap vor. Zu jedem Menü werden zwei Screenshots vom Sony Ericsson K700i (linke Seite) und dem Siemens S65 (rechte Seite) präsentiert. 12.3.1 Startmenü Nach dem Start begrüßt uns das Hauptmenü mit folgenden Optionen: • Karte anzeigen • Karte auswählen • Optionen • GPS • Beenden Abbildung 12-2: Startmenü Das einzige mögliche Kommando ist Auswählen, mit dem die selektierte Option ausgewählt wird. Zunächst schauen wir uns die Optionseinstellungen an, dazu wählen wir Optionen aus. Kapitel 12: Anhang 89 12.3.2 Optionen Im Optionsmenü können folgende Elemente konfiguriert werden: • Anzahl Kacheln • Kachelgröße • Host • Port • Karte Nachladen • Karte Auf GPS fixieren Abbildung 12-3: Optionen Folgende Kommandos sind verfügbar: • Zurück • Speichern Die Anzahl Kacheln und die Kachelgröße bestimmen zusammen die Größe des angezeigten Kartenausschnitts. Da der Kartenausschnitt und die Kacheln im Prototyp immer quadratisch sind, wird jeweils nur die Kantenlänge angegeben. Angenommen die Anzahl Kacheln ist 4 und die Kachelgröße 128, dann ist der später dargestellte Kartenausschnitt 4*4*128*128 Pixel groß. Host und Port bilden die Grundlage für die URL des Kartenservers. Die Checkbox Karte Nachladen legt fest, ob der Kartenausschnitt beim Überschreiten seiner Grenzen nachgeladen werden soll. Wenn die Checkbox Karte Auf GPS fixieren aktiviert ist, dann wird die Karte auf die letzte empfangene GPS-Position zentriert. Die Änderungen müssen explizit mit dem Kommando Speichern gespeichert werden. Das Kommando Zurück springt lediglich zum Startmenü zurück. Nicht gespeicherte Änderungen gehen dabei verloren. 12.3.3 Kartenauswahl Schauen wir uns nun Karten auswählen an. Die Kartenauswahl zeigt die auf dem mobilen Gerät gecachten Karten an. Folgende Kommandos sind verfügbar: • • • Auswählen Nachladen Zurück. Abbildung 12-4: Kartenauswahl Mit dem Kommando Nachladen werden die gecachten Karten gelöscht und die aktuellen Karten vom Server geladen. Wichtig dabei: Beim Nachladen in der Kartenauswahl werden keine neuen Kacheln geladen oder bereits gecachte gelöscht. Es werden nur die 90 Kapitel 12: Anhang Karteninformationen wie Name, Größe, Projektion, usw. vom Kartenserver heruntergeladen. Eine selektierte Karte kann mit Auswählen in den Speicher geladen werden. Anschließend springt die Applikation in das Hauptmenü zurück. Mit Zurück springt die Applikation in das Hauptmenü zurück, ohne eine Karte zu laden. 12.3.4 GPS Das GPS-Menü ist nur bei Geräten mit Bluetooth API verfügbar. Das K700i unterstützt diese API nicht und MobileJavaMap quittiert den Aufruf des GPS-Menüs mit einem Fehler. Auf dem S65 dagegen zeigt es in einem Abstand von 5s die letzte GPS-Position an. Die Bluetoothadresse des GPS-Empfängers ist im Prototyp statisch einprogrammiert. Das einzige Kommando ist Zurück, was das Zurückspringen zum Hauptmenü bewirkt. Abbildung 12-5: GPS 12.3.5 Karte anzeigen Nachdem die Karte aus der Kartenauswahl geladen worden ist, kann sie mit Karte anzeigen auf das Display gebracht werden. Mit dem Joystick des Mobiltelefons bzw. den Tasten 4,6,2,8 kann die Karte gescrollt werden. Dabei wird die geografische Koordinate des Fadenkreuzes in der linken, oberen Ecke angezeigt. Werden die Grenzen des Kartenausschnitts überquert, so wird der Kartenausschnitt nachgeladen. Beim Druck auf den Joystick bzw. die Taste 5 springt die Applikation wieder in das Startmenü. Darüber hinaus bietet Die Kartenanzeige bietet noch weitere Funktionalität: • • Setzen eines Referenzpunktes Springen zu Koordinate Abbildung 12-6: Kartenansicht Das Setzen des Referenzpunktes erfolgt auf dem K700i mit dem Druck auf die 9, beim S65 dagegen mit dem Druck auf die 3. Das Springen zu einer geografischen Koordinate wird beim K700i mit Druck auf die 7 und beim S65 mit dem Druck auf die 1 ausgelöst. Kapitel 12: Anhang 91 Diese Unterscheide sind plattformabhängig und können vom Entwickler nicht beeinflusst werden. 12.3.6 Springen zu Koordinate Dieses Menü ist nur von der Kartenansicht aufrufbar. Hier kann eine Längen- und Breitengradangabe eingegeben werden, zu der die Kartenanzeige zentrieren soll. Folgende Kommandos sind verfügbar: • • Springen Zurück Abbildung 12-7: Springen zu Koordinate Nach Aktivieren des Springen Kommandos kehrt die Applikation wieder zur Kartenansicht zurück und zentriert die Ansicht auf die gesetzten Koordinaten. Zurück kehrt ohne Sprung wieder zur Kartenansicht zurück. 92 12.4 MapServer Requests [Kapitel aufgrund sensibler Unternehmensdaten entfernt.] Kapitel 12: Anhang Kapitel 12: Anhang 93 12.5 Messungen 12.5.1 Häufigkeit der Bytegrößen von Kacheln Tabelle 12-1 listet die Häufigkeit der Bytegrößen von Kacheln in der Karte Dornier 1:1000. auf. Dabei wurden die Bytegrößen in Klassen von 200 bis 7000 eingeteilt. Klasse Häufigkeit Klasse Häufigkeit 200 60 3800 14 300 413 3900 15 400 347 4000 15 500 260 4100 16 600 152 4200 11 700 95 4300 8 800 98 4400 26 900 87 4500 24 1000 72 4600 25 1100 80 4700 15 1200 57 4800 11 1300 60 4900 12 1400 45 5000 19 1500 53 5100 14 1600 39 5200 17 1700 38 5300 20 1800 19 5400 23 1900 25 5500 20 2000 31 5600 25 2100 22 5700 26 2200 22 5800 14 2300 12 5900 18 2800 35 6000 29 2900 28 6100 15 3000 20 6200 15 3100 21 6300 9 3200 20 6400 9 3300 20 6500 11 3400 21 6700 6 3500 21 6800 7 3600 23 6900 2 3700 16 Tabelle 12-1: Häufigkeit von Bytegrößen von Kacheln in der Karte Dornier 1:1000 94 13 Kapitel 13: Abbildungen Abbildungen Abbildung 2-1: Transversale Mercator-Projektion (nach [@UNI_ROSTOCK_GEOSERVICE04])...............................................................14 Abbildung 2-2: Annäherung an den Geoid mit Ellipsoiden ( 2D-Darstellung) ..............15 Abbildung 2-3: KMRG Karte mit 3x3 Kacheln..............................................................16 Abbildung 2-4: Overlay Beispiel in JavaMap.................................................................16 Abbildung 3-1: J2ME-Plattform .....................................................................................18 Abbildung 4-1: Pre-Verifikation von Class Dateien für die KVM (nach [@SUN00_KVM_WP])..........................................................................................27 Abbildung 4-2: MIDlet-Suite und Applikationsdeskriptor .............................................29 Abbildung 4-3: RecordStore (Beispiel)...........................................................................30 Abbildung 4-4: LCDUI Komponenten ...........................................................................31 Abbildung 4-5: Kartenauswahl auf SE K700i und Siemens S65....................................31 Abbildung 4-6: LayerManager und Layer ......................................................................33 Abbildung 4-7: Layerkonzept der Game-API.................................................................34 Abbildung 4-8: Verwendung des TiledLayer (Bilder entnommen aus [@SUN02_MIDP_20]) ...........................................................................................34 Abbildung 4-9: Wireless Toolkit Integration in Netbeans 4.0 ........................................36 Abbildung 6-1: Kartenserver kommuniziert mit mehreren Applikationen .....................40 Abbildung 6-2: JSP Model-2 Architektur .......................................................................41 Abbildung 7-1: MobileJavaMap auf Siemens S65, Sony Ericsson K700i und Dell Axim PocketPC .................................................................................................................45 Abbildung 7-2: Architekturübersicht MobileJavaMap ...................................................47 Abbildung 7-3: IMapDataProvider und die Implementierungen ....................................48 Abbildung 7-4: Interface IMapDataProvider ..................................................................48 Abbildung 7-5: Kartenausschnitt ....................................................................................50 Abbildung 7-6: Nachladen des Kartenausschnitts ..........................................................51 Abbildung 7-7: ITile, ILazyTile und SquareTile ............................................................52 Abbildung 7-8: Sektion ...................................................................................................53 Abbildung 7-9: IMap und ISection .................................................................................53 Abbildung 7-10: ISectionBuilder und ISection...............................................................54 Abbildung 7-11: Nachladen eines SectionSquare Objekts .............................................55 Abbildung 7-12: IMapBuilder und IMap ........................................................................56 Abbildung 7-13: Erzeugung eines MapCLDC Objektes.................................................56 Abbildung 7-14: Nachladestrategie.................................................................................59 Abbildung 7-15: Erzeugen einer PackedTilesMessageCLDC ........................................60 Abbildung 7-16: Ein Record im RECORDSTORE_MAP .............................................62 Abbildung 7-17: Tile Cache............................................................................................63 Abbildung 7-18: Second Chance Algorithmus ...............................................................64 Abbildung 7-19: Speicherverlust im TILE_IMAGE Recordstore ..................................64 Abbildung 7-20: Histogramm der Bytegrößen in der Karte Dornier 1:1000 ..................66 Abbildung 7-21: IGPSReceiver ......................................................................................66 Abbildung 7-22: MobileJavaMapMIDlet und Controller ...............................................69 Abbildung 7-23: Ausführen einer Aktion bei der SmartTicket Applikation ..................70 Abbildung 7-24: ActionThread und IAction ...................................................................71 Abbildung 7-25: Ausführen einer Aktion über den ActionThread .................................72 Kapitel 14: Tabellen 95 Abbildung 7-26: StartUI und OptionsUI ........................................................................ 74 Abbildung 7-27: LayerManager und Layer von MobileJavaMap .................................. 76 Abbildung 7-28: Zusammensetzen der Layer................................................................. 77 Abbildung 7-29: MapUI Klasse...................................................................................... 77 Abbildung 8-1: Zuordnen von Zeilen zu einer Konfiguration........................................ 80 Abbildung 8-2: Code Completion mit Javadoc .............................................................. 80 Abbildung 8-3: Debugging mit dem Sony Ericsson SDK.............................................. 82 Abbildung 12-1: Auswahl der DummyDataProvider Konfiguration ............................. 87 Abbildung 12-2: Startmenü ............................................................................................ 88 Abbildung 12-3: Optionen .............................................................................................. 89 Abbildung 12-4: Kartenauswahl ..................................................................................... 89 Abbildung 12-5: GPS...................................................................................................... 90 Abbildung 12-6: Kartenansicht....................................................................................... 90 Abbildung 12-7: Springen zu Koordinate....................................................................... 91 14 Tabellen Tabelle 3-1 : J2ME-Konfigurationen.............................................................................. 19 Tabelle 3-2: J2ME-Profile .............................................................................................. 20 Tabelle 3-3: Optionale Pakete......................................................................................... 21 Tabelle 3-4: Anzahl der Endgerättypen für J2ME.......................................................... 23 Tabelle 5-1: Anforderungen............................................................................................ 38 Tabelle 7-1: Vergleich des Speicherbedarfs von drawRGB und drawImage ................. 49 Tabelle 7-2: Vergleich der Geschwindigkeit von drawRGB und drawImage................ 49 Tabelle 7-3: Caches in MobileJavaMap ......................................................................... 61 Tabelle 7-4: Analyse der Kachelgröße in Bytes ............................................................. 65 Tabelle 12-1: Häufigkeit von Bytegrößen von Kacheln in der Karte Dornier 1:1000 ... 93 96 15 Kapitel 15: Codefragmente Codefragmente Codefragment 6-1: ActionMapping Eintrag in der struts-config.xmlFehler! Textmarke nicht definiert. Codefragment 7-1: MapBuilder und SectionBuilder ......................................................58 Codefragment 7-2: Verwendung der GPSReceiver Klasse.............................................67 Kapitel 16: 16 Quellen 97 Quellen Alle nachfolgenden Links waren am Mittwoch, den 23.2.2005 gültig. Sämtliche Spezifikationen mit einer JSR Nummer wurden von [@JCP05] bezogen. [@APACHE04_STRUTS] – Apache Software Foundation: The Struts User’s Guide, 2004, (http://struts.apache.org) [@ALCALA03] – F. Alcala, J. Beel, A. Frenkel, B. Gipp, J. Lülf und H. Höpfner – Ortung von mobilen Geräten für die Realisierung lokationsbasierter Diensten, In: C. Türker (Hrsg): Mobilität und Informationssysteme - Workshop des GI-Arbeitskreises „Mobile Datenbanken und Informationssysteme“ 16./17. Oktober 2003, Zürich, (http://www-dbs.inf.ethz.ch/~tuerker/mdbis/final.pdf) [@BARNES03] – D. Barnes: Fundamentals of Microsoft .NET Compact Framework Development for the Microsoft .NET Framework Developer, 2003, (http://msdn.microsoft.com/smartclient/understanding/netcf/gettingstarted/default.aspx? pull=/library/en-us/dnnetcomp/html/net_vs_netcf.asp) [@BENEFON04] – Benefon: GSM+GPS ESC!, 2004, (http://www.benefon.com/pdf/products/esc/esc_presentation.pdf) [BLOCH02] – Joshua Bloch: Effektiv Java programmieren, Addison-Wesley, München, 2002 [@COMPUTER_RESELLER_NEWS04] – Computer Reseller News: Sun spells out how Java makes money, 2004, (http://www.crn.vnunet.com/news/1156279) [@EADS04] – EADS: Geogrid®, 2004, (http://www.eads.net/frame/lang/de/1024/content/OF00000000400003/9/21/32952219.h tml) [GAMMA96] E. Gamma, R. Helm, R. Johnson, J. Vlissides: Entwurfsmuster, Addison Wesley, München, 1996 [@GIGUERE02] – E. Guiguere: Understanding J2ME Application Models, 2002, (http://developers.sun.com/techtopics/mobility/midp/articles/models/) [GOSLING00] – J. Gosling, B. Joy, G. Steele, G. Bracha: The Java Language Specification Second Edition, Addison Wesley, Boston, 2000 [GOWDIAK04] – A. Gowdiak: Java 2 Mobile Edition security vulnerabilities, HITB Security Conference, Kuala Lumpur, 2004, (http://conference.hackinthebox.org), (http://www.packetstormsecurity.org/hitb04/hitb04-adam-gowdiak.pdf) 98 Kapitel 16: Quellen [@GÜLCÜ02] – C. Gülcü: Think again before adopting the commons-logging API, 2002, (http://www.qos.ch/logging/thinkAgain.jsp) [@HEISE04_51000] – Heise Newsticker: Microsoft einigt sich mit SmartphoneHersteller Sendo, 2004, (http://www.heise.de/newsticker/meldung/51000) [@HEISE04_47573] – Heise Newsticker: GPS-Empfänger in japanischen Handys ab 2007 Pflicht, 2004, (http://www.heise.de/newsticker/meldung/47573) [@J2ME_POLISH05] – J2ME Polish: Device Database, 2005, (http://www.j2mepolish.org/devices-overview.html) [@JCP05] – Java Community Process Program (http://www.jcp.org) [@KNUDSEN02] – J. Knudsen – Networking, User Experience, and Threads, 2002, (http://developers.sun.com/techtopics/mobility/midp/articles/threading/) [KUMAR04] – C. Kumar, P. Kline, T. Thompson: Bluetooth Application Programming with the Java APIs, Morgan Kaufmann, San Francisco, 2004 [LEIBSCHER00] – R. Leibscher: Skript zu Betriebssysteme und Systemsoftware, FH Konstanz, 2000 [@MARGULL04] – U. Margull: Skript zu Betriebssysteme, FH Regensburg, 2004, (http://www.margull.com/bt/index.html) [@MOLITOR04] – S. Molitor: Mobiles unter Beschuss, 2004, (http://www.heise.de/mobil/artikel/50820/0) [@NISSEN03] – F. Nissen, A. Hvas, J. Münster-Swendsen , L. Brodersen: Small Display Cartography, 2003 (http://gimodig.fgi.fi/pub_deliverables/D3_1_1.pdf) [@OZIEXPLORER05] – Des Newman: Des Newman's OziExplorer, 2005, (http://www.oziexplorer.com) [SCHMATZ04] – Klaus-Dieter Schmatz: Java 2 Micro Edition, Entwicklung mobiler Anwendungen mit CLDC und MIDP, dpunkt Verlag, Heidelberg, 2004 [@SESHADRI99] – G. Seshadri: Understanding the JavaServer Pages Model-2 Architecture, 1999, (http://www.javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html) [@SIEMENS04] – Siemens: Siemens Support Forum (http://agathonisi.erlm.siemens.de:8080/jive3/index.jspa?categoryID=1) Kapitel 16: Quellen 99 [@SUN00_KVM_WP] – Sun Microsystems: Kilo Virtual Machine White Paper – (http://java.sun.com/products/cldc/wp/index.html) [@SUN98_PERSONALJAVA] – Sun Microsystems: PersonalJava™ API Specification Version 1.1, 1998, (http://java.sun.com/products/personaljava/spec-1-1/pJavaSpec.html) [@SUN02_PROJECT_MONTY] – Sun Microsystems: The Project Monty Virtual Machine, 2002, (http://java.sun.com/products/cldc/wp/ProjectMontyWhitePaper.pdf) [@SUN02_PERSONAL_PROFILE02] – Sun Microsystems: Personal Profile Specification, 2002, (http://www.jcp.org/en/jsr/detail?id=62) [@SUN03_CDC_WP] – Sun Microsystems: CDC: An Application Framework for Personal Mobile Devices, 2003, (http://java.sun.com/products/cdc/wp/cdc-whitepaper.pdf) [@SUN04_CDC_HI] – Sun Microsystems: CDC HotSpot Implementation, 2004, (http://java.sun.com/j2me/docs/cdc_hotspotds_0804.pdf) [@SUN02_MIDP_20] – Sun Microsystems: MID Profile API Specification, 2002, (http://jcp.org/aboutJava/communityprocess/final/jsr118/index.html) [@SUN_SMARTTICKET03] – Sun Microsystems: Guidelines, Patterns, and code for end-to-end Java applications, 2003, (http://java.sun.com/blueprints/code/index.html#java_smart_ticket_demo) [@SYMBIAN03] – Symbian: Symbian Developer Library, 2003, (http://www.http://www.symbian.com/developer/techlib/sdl.html) [@UNI_ROSTOCK_04] – Uni Rostock: Geoinformatik Service, 2004 (http://www.geoinformatik.uni-rostock.de)