MokaByte 61 - Marzo 2002 
Il mondo java embedded
III parte: introduzione al MIDP (Mobile Information Device Profile
)
di
Marco Tom
Negli ultimi due numeri di MokaByte abbiamo visto il ruolo svolto da configurazioni e profili nell'architettura J2ME: le configurazioni si "preoccupano di aspetti generali" (non legati ad una particolare famiglia di dispositivi) i profili di problematiche più strettamente connesse all'apparecchiatura host. Abbiamo poi analizzato nel dettaglio la configurazione CLDC, a questo punto saliamo di un gradino (nella "scala" J2ME) e iniziamo ad occuparci di un profilo: il MIDP.

MIDP (Mobile Information Device Profile)
Il Mobile Information Device Profile è un profilo Java 2 Micro Edition che si basa sulla configurazione CLDC (Connected Limited Device Configuration) ed è diretto allo sviluppo di applicazioni Java per dispositivi wireless (telefoni cellulari, smartphone, two-way-pagers, palmari). La CLDC, seguendo la "filosofia J2ME" lascia irrisolti alcuni aspetti fondamentali per la realizzazione di applicazioni reali; le librerie MIDP come vedremo si integrano ed "estendono" quelle della configurazione permettendo la realizzazione, la gestione e l'esecuzione degli applicativi java. In particolare il MIDP si occupa di:

  • gestire il ciclo di vita delle applicazioni (caricamento - esecuzione - distruzione delle applicazioni)
  • gestire l'interfaccia utente (dispositivi di input/output)
  • salvataggio persistente dei dati
  • networking (implementazione dei protocolli)

Questi quattro punti sono implementati in altrettanti packages, rispettivamente:

  • javax.microedition.midlet
  • javax.microedition.lcdui
  • javax.microedition.rms
  • javax.microedition.io

In questo e nei prossimi articoli analizzeremo nel dettaglio ciascuno di questi package.


Figura 1 - Architettura MIDP


In figura 1 è mostrata la struttura dell'architettura MIDP: alla base dell'architettura troviamo, ovviamente, l'hardware del dispositivo host e il software nativo, cioè il sistema operativo e le librerie native. Al di sopra di questi due livelli si posa tutta l'architettura J2ME. La KVM (Kilobyte Virtual Machine) fornisce l'ambiente runtime per l'esecuzione delle applicazioni Java, mentre CLDC e MIDP forniscono il set completo di API Java di cui il programmatore potrà disporre.

Come è possibile osservare oltre alle librerie Java "standard" (CLDC-MIDP) possono essere disponibili librerie proprietarie specifiche per un dato dispositivo che se da un lato possono aumentare potenzialità e prestazioni dall'altro pregiudicano la portabilità del codice (device-specific applications). Per fare un esempio esistono librerie Siemens utilizzabili sul modello Siemens SL45i che permettono l'invio di messaggi SMS:

import com.siemens.mp.io.sms.*;
...
...
...
SMS sms = new SMS();
sms.send(number, text);
...
...
...

un applicativo che fa uso di questa porzione di codice potrebbe essere relegato a funzionare esclusivamente su questo o altri modelli Siemens (ad esempio non funziona su Nokia e Motorola).

 

Gestione del ciclo di vita delle applicazioni : javax.microedition.midlet
Un'applicazione per dispositivi MIDP è chiamata MIDlet ed è qualcosa di simile ad un'Applet java. Un MIDlet non possiede un metodo main, ma deve estendere la classe
javax.microedition.midlet.MIDlet ed implementare i suoi metodi astratti relativi allo stato in cui il MIDlet stesso può trovarsi:

protected abstract void startApp()
segnala al MIDlet che è stato posto nello stato di attività

protected abstract void pauseApp()
segnala al MIDlet il suo inserimento nello stato di pausa

protected abstract void destroyApp (boolean unconditional)
impone al MIDlet di terminare le proprie attività ed entrare nello stato destroyed.

Il cambiamento di stato di un MIDlet è controllato dall'AMS Application Management Software (talvolta chiamato anche MIDlet Management Software o Java Application Manager) questo altro non è che un'applicazione software che fa parte dell'implementazione del MIDP stesso e svolge le funzioni di "gestore dei MIDlet" essendo responsabile della loro installazione, esecuzione e rimozione. Più precisamente l'AMS:

  • garantisce la possibilità di installare e disinstallare MIDlet nel/dal dispositivo
  • prepara l'ambiente di esecuzione per il MIDlet (KVM, librerie CLDC-MIDP, librerie di terzi, file JAD, risorse esterne, ecc)
  • cattura gli errori che si possono verificare sia in fase di installazione del MIDlet che durante la sua esecuzione

In figura 2 è riportato il diagramma dei possibili stati di un MIDlet. Nel momento in cui esso è pronto per essere eseguito l'AMS ne crea un'istanza e pone il MIDlet nello stato di pausa. A questo punto con la chiamata del metodo startApp () il MIDlet passa allo stato attivo e riceve tutte le risorse di cui necessita per il funzionamento. A questo punto si possono verificare due condizioni: il MIDlet può essere distrutto oppure può entrare nello stato di pausa. In questo caso rilascia temporaneamente le risorse di cui disponeva e diventa inattivo. Una nuova chiamata al metodo startApp () può riportare il MIDlet dallo stato di pausa a quello di attività. Il MIDlet può comunque decidere "della propria sorte", attraverso i metodi:

notifyPaused() - il MIDlet informa l'AMS che è entrato nello stato di pausa
resumeRequest() - il MIDlet richiede all'AMS la possibilità di rientrare in attività
notifyDestroyed() - il MIDlet informa l'AMS che verrà distrutto

esso può decidere il proprio cambiamento di stato.


Figura 2 - Ciclo di vita di un MIDlet

Il flag presente nella firma del metodo destroyApp(boolean uncoditional) permette al MIDlet di "opporsi" al passaggio allo stato distroyed. Talvolta, infatti, può accadere che un MIDlet stia eseguendo un processo particolarmente importante e delicato (ad esempio operazioni con il database) da non poter essere interrotto, in questo caso può rilanciare una MIDletStateChangeException e richiedere all'AMS di rimanere nello stato di attività. Tale richiesta non è automaticamente esaudita dall'Application Manager, ma se il flag unconditional è true essa è sicuramente ignorata. Nel caso contrario (unconditional = false) può essere accettata e l'AMS provvederà a richiamare il metodo destroyApp() in un secondo momento.

 

Riportiamo qui sotto il codice di un semplice esempio di MIDlet:

package midletexample;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class MIDletExample extends MIDlet implements CommandListener {

private Form form;
private Command exit;

/** Costruttore */
public MIDletExample () {
}

/** pone il MIDlet in attività */
public void startApp() {
form = new Form("My MIDlet");
exit = new Command("Exit", Command.EXIT, 1);
form.addCommand(exit);
form.setCommandListener(this);
Display.getDisplay(this).setCurrent(form);
}

/** pone il MIDlet in pausa */
public void pauseApp() {
}

/** distrugge il MIDlet */
public void destroyApp(boolean unconditional) {
}

/** gestisce gli eventi generati dai comandi */
public void commandAction(Command command, Displayable displayable){
System.out.println(exit.getLabel());
if (command = = exit) {
destroyApp(false);
notifyDestroyed();
}
}
}


che genera questo output sull'emulatore (figura 3)



Figura 3 - MIDlet in esecuzione

 

MIDlet e MIDlet Suite: installazione ed esecuzione
A questo punto, occorre affrontare il problema del passaggio dalla realizzazione del MIDlet alla sua installazione - esecuzione su di un dispositivo MIDP (o un suo emulatore). La situazione è abbastanza differente rispetto alle applicazioni Java Standard Edition. Si è già visto, a proposito della configurazione CLDC, che nella fase di verifica dei file class è stato introdotto uno step intermedio: la pre-verifica. Una volta superata tale fase l'applicativo è, in teoria, pronto per essere eseguito. In realtà, il processo di pre-verifica genera come output file class, resta quindi da vedere come questi debbano essere installati sul dispositivo in modo tale da permettere l'esecuzione del MIDlet.
Tutti i file class del MIDlet devono essere inseriti in un file JAR, questo può contenere una o più applicazioni MIDlet il cui insieme prende il nome di MIDlet Suite. A questo punto il file JAR può essere caricato sul dispositivo in modi diversi a seconda dell'implementazione MIDP e del tipo di dispositivo (ad esempio via cavo seriale, via rete, via porta infrarossi, salvataggio su MMC MultiMediaCard, ecc.). Il file JAR come detto può contenere più MIDlet, al suo interno troveremo tutti i file class ad essi relativi, file di risorsa (ed esempio file di testo, immagini - il MIDP supporta immagini in formato png Portable Network Graphics -,ecc), eventuali librerie di terze parti ed infine un file MANIFEST. All'interno di una MIDlet Suite i singoli MIDlet possono (o meglio dovrebbero) condividere file class e risorse (file di testo, immagini), questo, infatti, permette di ridurre le dimensioni totali del file JAR cosa estremamente importante in caso di download dell'applicativo da reti con larghezza di banda modesta.
Il file MANIFEST presente all'interno del JAR descrive il contenuto del file JAR stesso e fornisce inoltre informazioni circa la MIDlet Suite. Riportiamo qui sotto un esempio di MANIFEST file relativo ad una MIDlet Suite costituita da tre MIDlet: MIDlet1, MIDlet2, MIDlet3.

File MANIFEST:

Manifest-Version: 1.0
MIDlet-Version: 1.0
MIDlet-Vendor: My Vendor
MIDlet-3: MIDlet3, , midletsuiteexample.MIDlet3
MIDlet-2: MIDlet2, , midletsuiteexample.MIDlet2
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0
MIDlet-1: MIDlet1, , midletsuiteexample.MIDlet1
MIDlet-Name: My MIDlet Suite

In realtà oltre al file Jar una applicazione MIDP è costituita anche da un file con estensione JAD (Java Application Descriptor). A titolo di esempio riportiamo qui sotto il file JAD relativo alla MIDlet Suite di cui abbiamo appena visto il file MANIFEST:

File JAD:

MIDlet-Name: My MIDlet Suite
MIDlet-Version: 1.0
MIDlet-Vendor: My Vendor
MIDlet-1: MIDlet1, , midletsuiteexample.MIDlet1
MIDlet-2: MIDlet2, , midletsuiteexample.MIDlet2
MIDlet-3: MIDlet3, , midletsuiteexample.MIDlet3
MIDlet-Jar-URL: MIDletSuiteExample.jar
MIDlet-Jar-Size: 309
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-1.0

Quelli riportati sono gli attributi predefiniti obbligatori di un file JAD, altri attributi predefiniti sono opzionali:

MIDlet-Description
MIDlet-Icon
MIDlet-Info-URL
MIDlet-Data-Size

Come si può notare i due file sono molto simili ma svolgono ruoli differenti. Il file JAD gioca un ruolo molto importante, soprattutto, nel caso di downloading delle applicazioni da reti wireless (OTA deployment - Over-The-Air deployment) tipicamente con larghezza di banda limitata.
Il suo scopo è, infatti, quello di informare l'Application Manager Software delle caratteristiche richieste per l'installazione e l'esecuzione della MIDlet Suite prima ancora dell'effettivo download del file JAR. Sulla base degli attributi contenuti nel file JAD, l'AMS è in grado di valutare la possibilità o meno di procedere all'installazione dell'applicativo. Ad esempio l'AMS verifica se esiste spazio di memoria sufficiente per il file JAR, valuta la corrispondenza delle versioni di configurazione e profilo, si assicura che nel dispositivo non sia presente la stessa versione dell'applicativo che si intende installare. I concetti appena esposti sono rappresentati in figura 4 dove è possibile osservare com'è strutturata una tipica applicazione MIDP.



Figura 4 - Applicazione MIDP


Una volta installato sul dispositivo un MIDlet (o una MIDlet Suite se l'applicativo è composto da più MIDlet) può essere lanciato ed eseguito. Ecco come appare la MIDlet suite di esempio (di cui abbiamo riportato i file MANIFEST e JAD) sull'emulatore Sun.


Figura 5
- Una MIDlet Suite

Oltre agli attributi predefiniti presenti nei file MANIFEST e JAD è possibile inserirne di propri nel formato nome-valore. La possibilità di definire attributi addizionali può essere importante in alcuni (forse molti) contesti. In fase di runtime è, infatti, possibile leggere il valore di tali attributi utilizzando il metodo String getAppProperty(String key) della classe MIDlet che ritorna il valore dell'attributo passato come parametro (key). Ad esempio è possibile indicare tra gli attributi le dimensioni del display facendo in modo che leggendo il loro valore a runtime l'applicativo riadatti la propria grafica in base alle dimensioni del display stesso. Un altro possibile impiego potrebbe essere quello di inserire un attributo "language" in modo da far apparire sullo schermo messaggi nella lingua desiderata. Tenedo conto che anche i file di risorsa (file di testo, immagini, ecc) sono accessibili mediante il metodo della classe Class getResourceAsStream (String file) è evidente come i MIDlet possano essere dotati di "poteri di auto-configurazione" in fase di runtime.

 

I Tools di sviluppo
Concludiamo questo primo articolo sul profilo MIDP con una breve panoramica sui tools di sviluppo disponibili. Benché sia comunque possibile operare da riga di comando, la complessità delle operazioni potrebbe scoraggiare anche i migliori intenzionati (compilazione - preverifica - packaging - installazione, creazione del file JAD). Fortunatamente sono disponibili tools di sviluppo dedicati, o plug-in per ambienti di sviluppo Java completi che rendono automatiche ed estremamente semplici tutte le fasi di creazione - sviluppo - e testing dei MIDlets.
Non vogliamo qui entrare nel merito di quale sia il migliore prodotto attualmente disponibile o fare comparazioni tra l'uno o l'altro ambiente, ci limiteremo ad elencare le possibili alternative lasciando al lettore il compito di verificare personalmente le caratteristiche dei vari prodotti.
J2ME Wireless Toolkit - di Sun Microsystem disponibile per piattaforme Sun Solaris e Windows. E' utilizzabile sia come tool standalone sia come plug-in di Forte For Java (durante la fase di installazione l'utente ha la possibilità di scegliere tra queste due modalità). E' possibile effettuare il download del prodotto all'indirizzo http://java.sun.com/products/j2mewtoolkit

CodeWarrior for Java, Professional Edition Version 6.0 - ambiente di sviluppo di Metrowerks permette l'esecuzione, l'emulazione e il debugging per applicazioni MIDP, contiene un emulatore Motorola. La versione trial (30 gg) è disponibile all'indirizzo http://www.metrowerks.com/desktop/java/download

Nokia Developer's Suite Beta 0.2 for the Java - può essere utilizzato sia in modo standalone sia come plug-in di Forte For Java e JBuilder5 / JBuilder6 (con Mobile Set installato). Dispone di emulatore Nokia. Per il download http://www.forum.nokia.com/main.html.

JBuilder Mobile Set 2.0 - di Borland è il plug-in per JBuilder 6.0. Oltre alle funzioni di esecuzione, emulazione, debugging e packaging possiede un tool visuale per disegnare interfacce grafiche MIDP. JBuilder Mobile Set 2.0 è disponibile all'indirizzo http://www.borland.com/jbuilder/offers.

Siemens SW Development Tools - Tool di sviluppo per apparati Siemens SL45i / i6688 (versione dell' SL45i per il mercato asiatico) http://www.siemens-mobile.de

 

Bibliografia e Riferimenti
- "Il mondo java embedded I parte" - MokaByte 59 Gennaio 2002 http://www.mokabyte.it/2002/01/j2me_1.htm
- "Il mondo java embedded II parte: la configurazione CLDC" - MokaByte 60 Febbraio 2002 http://www.mokabyte.it/2002/02/j2me_2.htm
- http://developer.java.sun.com/developer/technicalArticles/wireless
- Developing Wireless Applications using J2ME[tm] Technology - Bill Day
-
http://wireless.java.sun.com/getstart/articles/wirelessdev/wirelessdev.pdf
- http://java.sun.com/products/midp/

MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it