Mobileszközök programozása Java nyelven

A Java a mobileszközök világában: J2ME

Miért (ne) használjuk a Javat?

A Java nyelv a Bevezetőben tárgyalt platformfüggetlenséget mindmáig nem tudta teljesen elérni a mobiltelefonok világában. Ennek oka elsősorban az, hogy a gyártók vagy nem minden Java-szolgáltatást építettek be készülékeikbe vagy a beépített szolgáltatások hibásak. Ezen felül pedig erőforrás- használatkor felmerülhetnek hozzáférési problémák is a jogosultsági rendszer miatt.
Ahogyan a későbbiekben bemutatásra kerül, a Java egy magja viszonylag stabil, amennyiben az adott mobil telefon engedélyezi külső forrásból származó Java alkalmazás telepítését és futtatását. Ezen mag erejét és az elérhető programkönyvtárakat a későbbiekben részletezzük, de elöljáróban annyi elmondható, hogy inkább kisebb programok, játékok, egyszerű hálózatos alkalmazások fejlesztését teszi lehetővé. Például igazán komoly multimédiás vagy grafikus felülettel rendelkező alkalmazás nem fejleszthető, mert az ezekhez szükséges JSR csomagok nem érhetőek el stabilan minden platformon. Ezért fontos, hogy a programozó tudja, mivel feszegeti a Java nyújtotta lehetőségek határait.
Amiért tehát érdemes Java-ban mobiltelefon-alkalmazást készíteni, mert egy szűk eszközkészletet tekintve ténylegesen platformfüggetlen és maximálisan kielégíti az ehhez kapcsolódó igényeket. Egy kevés rendszerszintű operációt alkalmazó program, nem kifejezetten komplex felhasználói kommunikációval elkészíthető úgy, hogy a legtöbb készüléken üzemeljen.
Ami azonban elkeserítő, hogy például egy a beépített kamera szolgáltatásait használó alkalmazás működésére nincs garancia Java-ban, mert ahhoz a Java magon kívül a JSR-234 csomagra is szükség van. Ez azonban nincs minden napjainkban is működő telefonon (jelen pillanatban az új Nokia készülékeken Java-ból nem hozzáférhető a kamera), de volt már precedens olyanra is, hogy a JSR-234 csomag nem teljesen volt megvalósítva. A 4-5 éves Nokia N70 készüléken például a kamera elérhető, de a JSR-234 egyéb szolgáltatásainak (zoom, fehéregyensúly, stb.) biztonságos hívásai is teljesen lefagyasztották a készüléket.

Fejlesztő környezetek, emulátorok

A J2ME fejlesztésére Windows vonalon kiválóan alkalmas a NetBeans, Linux alatt inkább az Eclipse használatos. A Java-s fejlesztőkörnyezetek kényelmesek, számos a programozó dolgot könnyítő funkcióval bírnak (text-highlighting, intelliSense-szerűség, stb.), használatuk éppen ezért javasolt. Emellett képesek a kód automatikus tördelésére, sőt, NetBeansben van automatikus Javadoc generálás.
Mindkét fejlesztőkörnyezet mellett telepíthetők különböző emulátor programok, amelyek a számítógépen történő teszteléshez elengedhetetlenek. Ezen programok általában lehetőséget nyújtanak számos készülék emulálására (pl. a Sony Ericsson Wireless Toolkit többszáz féle mobilt tud emulálni). A professzionális emulátorok általában képesek a memória használat és a hálózati terhelés monitorozására a készül hardveres és szoftveres képességeinek figyelembe vételével, ám általában ezek a funkciók is fenntartással kezelendők. Például az előbb nevesített emulátor Memorymeter eszköze csak becsüli az operációs rendszer memóriafoglalását, ezért előfordulhat, hogy egyes futtatások OutOfMemoryBoundExceptiont eredményeznek ugyanazon input mellett, míg mások gond nélkül lefutnak.

Futtatás és teszt

A fejlesztés során készített Java forráskódot fordíthatjuk az emulátor számára értelmezhető .jad formátumra, illetve ezzel párhuzamosan a telefonos interpreter számára értelmezhető .jar formátumú állományra. Ezt wap, bluetooth vagy USB-kábel segítségével eljuttathatjuk a telefonra. Amennyiben a telefon alkalmas az előállított tárgykód értelmezésére, telepítést követően futtathatjuk is.
Az átviteli- és telepítési procedúra azonban meglehetősen lassú, ezért célszerű a programot az emulátor segítségével emulált környezetben tesztelni és az esetleges hibákat javítani. Bár az emulálás, kiváltképp a "Debug mode"-ban történő futtatás lényegesen lassabb, mint a számítógépes alkalmazások esetében, még mindig praktikusabb a telefonon történő tesztelésnél.
Az emuláláskor a Debug mode mellett a fejlesztő rendelkezésére áll még a szöveges Console. Ez különösen hasznos lehet a hiba lokalizálásakor, hiszen rendszer szintű, ezért a kód minden részéből elérhető a megfelelő hívással.

Kétféle mobileszköz, két külön irányvonal

A Java nyelv tervezői a mobil eszközök támogatására alkalmas Java-t kétféle megközelítés alapján képzelték el. Az egyik felfogás szerint a már létező Java SE-t kell úgy átalakítani, hogy az a korlátozott erőforrások figyelembe vételével készítsen futtatható állományt az SE szolgáltatásai mellett. Ennek eredményeképpen született meg Connected Device Configuration - azaz a CDC.
A másik elképzelés szerint újra kell tervezni az alapkönyvtárakat és hatékonyan, a mobileszközök korlátozott erőforrásainak figyelembe vételével Új Javat kell írni. Ennek eredményeképpen született meg a CLDC - azaz Connected Limited Device Configuration.
A fejlesztések során mindkét megoldás realizálhatónak látszott: a CDC gyorsan készült, hiszen "csak" át kellett írni egy meglévő Java verziót; ám ez nem bizonyult elég hatékonynak ahhoz, hogy mobiltelefonos fejlesztésekhez is használható legyen. Így fordulhatott elő, hogy mindkét fejlesztési irány mindmáig tart.

CDC - avagy a PalmTopok, GPS-ek, PDA-k és a Java

Mint ahogy az előbb megvilágítottuk, a CDC alapvetően azon gondolat szüleménye, hogy a meglévő Java SE-t kell így átalakítani, hogy mobileszközös fejlesztésekre is alkalmas legyen. Az optimalizáció egyik alappillére a futtatható állomány tömörítése, a másik az osztálykönyvtárak optimalizálása. A JAR fájl tömörítése és optimalizálása (az ún. obfuszkálás) lehetővé teszi a tárolást és a telefonos interpreter dolgát is megkönnyíti. Az osztálykönyvtárak optimalizálása pedig a kisebb számítási igényt és a gazdaságosabb memóriahasználatot biztosítja.
Az átalakítással kapott CDC nem hozta azt az eredményt, amely kielégítené a mobilfejlesztés igényeit, hiszen ezek az alkalmazások még mindig több MB memóriát igényelnek. Bár a tömörítés és az optimalizálás eredményes, mégsem tud igazodni a mobiltelefonok nyújtotta gyenge hardveres teljesítményhez. Ennek megfelelően a CDC az intelligensebbnek mondható mobileszközökön, pl. PalmTopok, GPS-készülékek és PDA-k esetében használható. Ezen eszközökön a CDC nagyjából homogén interfészt szolgáltat, ennek megfelelően készíthetők "komoly" alkalmazások.
Mivel az ilyen eszközök nagy támogatottságot élveznek elsősorban a Microsoft termékek körében, ezért nem igazán jellemzők a Javas fejlesztések. Amennyiben azonban mégis a Javara hagyatkozunk a fejlesztéskor, az SE-ben használatos kényelmes GUI-készítés, adatbázis-kezelés, hálózat-kezelés mellett számos egyéb, az SE-ből már jól ismert eszköz áll rendelkezésünkre.
A CDC fejlesztések egyedülállósága és talán egyben legfontosabb jellemzője, hogy kompatibilis a Java SE-vel. Ezzel a képernyőméret különbségek figyelembevételével és az obfuszkálással egyidejűleg fejleszthetünk számítógépre és CDC-t támogató mobileszközre is.

CLDC - avagy a mobiltelefonok és a Java

A mobiltelefonok számára "emészthető" Java verzió a CLDC, amely a fentebb részletezett folyamatban említett újítás eredményeképpen született. Ez azt jelenti, hogy ez a Java verzió ízig-vérig mobiltelefonokra született, ezáltal megteremti a platform-független mobilprogramozás lehetőségét.
Jelenleg a CLDC két verziója létezik: 1.0 és 1.1. Előbbi a napjainkban működőképes készülékeken (6-8 évre visszamenőleg) is működik, míg az 1.1-es változat inkább a 2-3 éves verziókon biztosított stabilan. Az 1.0-ás verzió csak az alap típusokat és a legalapvetőbb aritmetikai műveleteket szolgáltatja, nevezetesen négy alapműveletet, az abszolút értéket és a modulus képzést. Ezzel szemben az 1.1-es verzió már támogatja a lebegőpontos aritmetikát is.
A CLDC-k esetében nincs különösen nagy hangsúlya a verzióknak, mert szerencsére az újabb verziók kompatibilisek a régebbi verziókkal, így a régebbi alkalmazások futása az új készülékeken biztosított.

MIDP JRE-szolgáltatás

A CDC/CLDC mellett a JRE (Java Runtime Environment) másik szolgáltatáscsomagja az MIDP (Mobile Information Device Profile). Ez biztosít interfészt az alkalmazás futtatásához, a felhasználói felület programozásához, valamint az alapvető fájlkezeléshez.
Az MIDP a felhasználóval történő kapcsolattartásra két különböző megközelítésű megoldást kínál: a Canvas-t és a Form-ot. A Canvas a korábbi konzolos programok "grafikai képességeit" idézi: állítható az ecset színe, illetve pixeles címzéssel elhelyezhetők síkidomok vagy például kép objektumok. A példányosított Canvas objektum képes a képernyőméretek lekérdezésére, illetve a dimenziók szerinti pozícionálásra is. Ezzel szemben a számítógépes körökben megszokott módon objektumok elhelyezésére biztosít lehetőséget. A Form és társosztályai (Button, Label, ...) hivatottak átültetni a Java SE-ben vagy EE-ben megszokott GUI-t a mobilos Java-világba.
Jelen pillanatban az általánosan elterjedt MIDP verzió a 2.0, amit közvetlenül az 1.0 előzött meg sok-sok évvel ezelőtt. A következő változat, a 3.0 már fejlesztés alatt áll. Ahogyan a CLDC-k esetében is, a különböző MIDP-verziók is kompatibilisek lesznek egymással, így legalább a korábbi MIDP-változatban készített alkalmazásokat nem kell frissíteni, ha elkészül az MIDP 3.0.

MIDlet alkalmazások

A MIDlet a J2ME mobil-eszközön futtatható alkalmazása. Mivel a mai mobiltelefonok jelentős része nem rendelkezik saját operációs rendszerrel, csak az alkalmazások kezeléséért felelős programmal, az ún. AMS-sel (Application Management System); fontos, hogy az alkalmazás-fejlesztő a programozás során segítse az AMS munkáját. Az AMS lényegében a számítógépes környezetekben megszokott, az operációs rendszer által végzett a processz kezeléssel feladatokat látja el. Ilyen módon gondoskodik az alkalmazások futtatásáról, a memóriaterület felosztásáról és felszabadításáról, szükség esetén pedig az alkalmazást futtató processz megszüntetéséről vagy megállításáról. Ne felejtsük el, hogy mobiltelefonról lévén szó, a számítógépnél megszokottnál sokkal több nem-maszkolható megszakítási kérelem érkezhet (hívás, SMS/MMS, jelzések, akkumulátor, stb.). Hiszen a mobiltelefon elsődleges feladata a kommunikáció, következésképpen egy Java alkalmazás csak alacsony prioritást kaphat.
Ezen okokból kifolyólag minden J2ME alkalmazás legfelsőbb rétege a MIDlet osztályból kell, hogy származzon, különben a telefon egyszerűen nem fogja futtatni az alkalmazást. Ezáltal a programozó rá van kényszerítve, hogy a MIDlet osztály startApp(), pauseApp() és destroyApp() absztrakt metódusainak megvalósításával az AMS-nek megfelelő alkalmazást fejlesszen. Ezen metódusok a nevüknek megfelelően az alkalmazás indításakor, felfüggesztésekor, illetve bezárásakor hívódnak meg.
A következő ábra mutatja a MIDlet-ek lehetésges állapotait:

A MIDlet állapotai

A MIDlet konstruktorának hívásakor (new()) az AMS létrehozza a MIDlet egy példányát, majd aktiválja azt, vagyis meghívódik a startApp() metódus. A Java SE alkalmazások esetén a program futása a statikus main metódus meghívásával kezdődik, ez a program belépési pontja. Ha nincs main, a program futási idejű hibával leáll. Java ME-ben a main-nek a startApp() függvény felel meg. Ez indítja el a Java ME alkalmazást.
Az alkalmazás bezárásakor a destroyApp() hajtódik végre. Ha ez paraméterként egy igaz értékű logikai változót kap, akkor felszabadítja a lefoglalt erőforrásokat. Ha valamilyen okból kifolyólag (például telefonhívás esetén) az alkalmazást fel kell függeszteni, az AMS meghívja a MIDlet pauseApp() függvényét, majd (a telefonhívás befejeztével) a startApp()-ot.

Ez alapján egy MIDlet alkalmazás váza:

import javax.microedition.midlet.MIDlet;

public class FOO extends MIDlet {
public void startApp() {
//főprogram lehetőség szerint külön szálban futtatva
}

public void pauseApp() {
this.notifyPaused();
}

public void destroyApp(boolean unconditional) {
this.notifyDestroyed();
}
}

Biztonsági okokból célszerű továbbá a programot eleve egy önálló szálban (Thread) futtatni!