Lezione 1: Introduzione a Java 2 Micro Edition

Introduzione a Java 2 Micro
Edition
Francesca Martelli
[email protected]
http://www.di.unipi.it/~f.martel/
Stanza: 382 DB
Tel: 050 2212 754
Prima qualche domanda logistica
• Per poter andare in laboratorio, dobbiamo cambiare
orario. Slot disponibili:
–
–
–
–
–
Lunedì 14-16 o 16-18
Martedì 14-16
Mercoledì 14-16 o 16-18
Giovedì 14-16 o 16-18
Venerdì mattina o pomeriggio
• Oppure: esercizi a casa con correzioni in aula
• Conoscenza di java?
• Conoscenza di HTML?
Cosa faremo
• Java 2 MicroEdition
– Introduzione alla programmazione J2ME
– J2ME Wireless Toolkit
• Il linguaggio XHTML
Cosa Serve (1)
• Documentazione J2ME
– MIDP 2.0, CLDC 1.1
– http://java.sun.com/javame/reference/apis.jsp
• Qualsiasi tutorial che trovate su internet
• Queste slide che troverete su http://www.di.unipi.it/~f.
martel/didattica.html
• Libri (opzionali):
– James Keogh, J2ME: The Complete Reference, McGraw-Hill
– Roger Riggs, Antero Taivalsaari, Jim Van Peursem, Jyri
Huopaniemi, Mark Patel, Aleksi Uotila, Programming Wireless
Devices with the Java 2 Platform, Micro Edition, Second
Edition, Addison Wesley
L’Architettura Java
• Compilatore Java compiler: trasforma il linguaggio di
programmazione Java in un insieme di bytecode Java
• Java Virtual Machine (JVM): interpreta il bytecodes Java
per eseguire il programma Java
• Vantaggi di Java:
– Portabilità: “write once, run anywhere”
– Sicurezza: scaricando applicazioni da un ambiente
potenzialmente inaffidabile, le chiamate di sistema vengono
controllate dalla Java Native Interface (JNI)
– la possibilità di sfruttare le applicazioni in locale, residenti e
funzionanti anche off-line
– l'interfacciamento con le piattaforme web che lavorano con
JAVA (Servlet o JSP) è immediato
Le versioni di Java
Java 2
• Java 1.2 diventa semplicemente Java 2, sebbene le versioni di JDK
e JRE rimangono 1.2. La piattaforma Java viene divisa in 3
edizioni:
– Java 2 Standard Edition (J2SE): per lo sviluppo di applicazioni
convenzionali da desktop
– Java 2 Enterprise Edition (J2EE): sovrainsieme di J2SE, rivolto alla
programmazione di impresa, con particolare enfasi sullo sviluppo dal lato
server, tramite l’uso di Enterprise JavaBeans (EJBs), applicazioni web
(servlets e JavaServer Pages), CORBA, e Extensible Markup Language
(XML)
– Java 2 Micro Edition (J2ME): sottoinsieme di J2SE, orientato ai dispositivi
portatili che non possono supportare un’implementazione totale di J2SE
• Nonostante la sovrapposizione fra le tre versioni, questa divisione
rende possibile l’evolvere di Java in differenti direzioni per
soddisfare differenti esigenze, mantenendo intatto lo spirito del
linguaggio
Java 2 Micro Edition
• La mancanza di uniformità delle configurazioni hardware fra i vari
piccoli dispositivi ha posto una grossa sfida per la comunità Java
• J2ME è nato proprio per superare questo limite, ed è uno standard
che serve molti dispositivi a capacità limitate, come i telefoni
cellulari, i personal digital assistant (PDA) e i dispositivi plug-in,
che hanno diverse configurazioni hardware non standard
• La Java Community Process ha usato un duplice approccio:
– La definizione di un ambiente Java run-time (una JVM) e di un nucleo di
classi che operano su ogni dispositivo (CONFIGURAZIONE). Ci sono due
configurazioni:
• Una per i dispositivi portatili
• Una per i dispositivi plug-in
– La definizione di un PROFILO per ogni categoria di dispositivo
Configurazioni
• Una configurazione definisce l’ambiente base di esecuzione:
– Limitata JVM
– Nucleo di classi derivate da J2SE
• Il punto chiave è che ogni configurazione è specifica per
una famiglia di dispositivi con capacità simili
• Ad oggi, sono definite due configurazioni, entrambe che
prevedono connettività alla rete, che sia fissa o wireless:
– Connected Device Configuration (CDC): TV set-top boxes, sistemi
di navigazione per auto
– Connected Limited Device Configuration (CLDC): cellulari, PDA
• Non c’è una netta linea di confine fra le due configurazioni
Configurazioni (2)
• Noi ci concentreremo sul CLDC
• Notare che il CDC è un sovrainsieme del CLDC, con in
più alcune classi di J2SE e altre nuove
• CDC ha la virtual machine di J2SE, incluso il debugging
a basso livello e le interfacce native, o meglio, una nuova
virtual machine chiamata Compact VM, sviluppata
appositamente
Profili
• Un profilo estende una configurazione, aggiungendo
classi per specifici usi dei dispositivi, omesse nella
configurazione di base (per esempio, classi per
l’interfaccia utente)
• Il Mobile Information Device Profile (MIDP) è basato sul
CLDC
– Classi per la memorizzazione locale,
– una user interface,
– funzionalità per il networking
Profili (2)
• Altri profili sono:
– Personal Digital Assistant Profile (PDAP): estende CLDC per sfruttare le
maggiori capacità dei PDA rispetto ai semplici dispositivi MIDP, come
migliori display e maggiore memoria
– Foundation Profile: aggiunge classi J2SE al CDC, ma non quelle per
l’interfaccia utente; è la base (foundation) per costruire altri profili
– Personal Profile (con configurazione CDC): ridefinisce PersonalJava come
profilo J2ME; estende il Foundation Profile per implementare una user
interface sofisticata, capace di mostrare finestre multiple
– Personal Basis Profile: simile al Personal Profile (con configurazione CDC
e Foundation Profile), ma implementa user interface più semplice
– Game Profile (con configurazione CDC): contiene le classi specifiche per
sviluppare giochi
– RMI Profile (con configurazione CDC): aggiunge supporto RMI alle classi
del Foundation Profile
– … J2ME è in evoluzione…
• In una stessa configurazione possono coesistere più profili
Connected Limited Device Configuration
• Per capire MIDP bisogna prima conoscere la configurazione
CLDC, definita nel JSR-30 dalla JCP
http://java.sun.com/javame/reference/apis/jsr030/
• Per dispositivi “things that you hold in your hand”, caratterizzati
da connettività wireless, banda ridotta, accesso discontinuo,
batterie limitate e bassa potenza di calcolo e memoria
–
–
–
–
Da 128KB a 512KB di memoria non-volatile (codice)
32KB di memoria volatile (runtime)
Processori a 16-bit (o 32-bit)
Possono non avere interfaccia utente
• I dispositivi CLDC usano la KJava Virtual Machine (KVM),
versione molto ridotta della JVM
CLDC: Requisiti (1)
• No floating point: tipi e costanti floating-point, le classi di J2SE
che trattano con valori floating-point non sono supportati
(computazione pesante); i metodi che ritornano valori floatingpoint sono rimossi; con opportune librerie è possibile utilizzare il
calcolo in virgola mobile
• No object finalization: il metodo finalize è rimosso da
java.lang.Object, per semplificare il compito del garbage collector,
che semplicemente recupera tutti gli oggetti non referenziati (così
si evita il “risorgere” degli oggetti);
• Errori a runtime: eccezioni sottoclassi di java.lang.Error lanciate
dalla virtual machine. Solo 3 classi di errori:
– java.lang.Error, java.lang.OutOfMemoryError,
java.lang.VirtualMachineError
Ogni altra situazione di errore è trattata in modo dipendente
dall’implementazione della VM, tipicamente la terminazione
CLDC: Requisiti (2)
• Interfaccia Nativa Java (JNI) non supportata: non è possibile
chiamare funzioni native del sistema operativo ospitante per
effettuare operazioni
• No reflection: non si possono usare le classi Reflection per
ottenere informazioni sulla JVM in esecuzione
• No object serialization
• No gruppi di thread: la VM non supporta la classe ThreadGroup
quindi non si possono lanciare (o fermare) più Thread in un solo
colpo
• No application-defined class loader: il caricatore di classi subisce
severi controlli e non può essere sostituito, ignorato o modificato.
– La verifica delle classi, computazionalmente pesante, è fatta separatamente
in fase di preverifica su un server e non sul dispositivo.
– Sul dispositivo i file delle classi preverificate subiscono solo una semplice
validazione dei risultati della preverifica.
CLDC: Requisiti (3)
• Le classi “ereditate” da J2SE devono essere un
sottoinsieme delle classi di J2SE 1.3. I metodi possono
essere omessi, ma nessun nuovo metodo public può
essere aggiunto, per ovvie ragioni di compatibilità
• Le classi definite dal CLDC e i suoi profili stanno nel
package o nei sottopackage di javax.microedition,
per identificare facilmente le specifiche classi del CLDC
• Supporto minimo per internazionalizzazioni: il CLDC
fornisce un supporto di base per convertire le codifiche
dei caratteri da/per Unicode. Tuttavia, non ha capacità di
“localizzazione”, per la visualizzazione di data, ora,
valuta, ecc.
Connected Device Configuration
• Per dispositivi “things that you plug into a wall”, cioè
collegati in rete, possibilmente always on, ad alta banda e
con buona potenza di calcolo e memoria
• I dispositivi CDC usano un’architettura a 32-bit,
• Hanno almeno 2MB di memoria disponibile
• Implementano la JVM con tutte le sue funzionalità
• Dispositivi CDC:
–
–
–
–
–
TV set-top boxes digitali
Apparecchi per la domotica
Sistemi di navigazione
Terminali del pagamento fai-da-te
…
Sruttura a livelli dell’Architetturea J2ME
MIDP
OEM
apps
J2ME APIs
Configurazione
OEM
classes
Java Virtual Machine
Sistema operativo
• Livello
Configurazione:
– la JVM interagisce con
il sistema operativo;
– lo strato
configurazione gestisce
le interazioni tra il
profilo e la JVM
Sruttura a livelli dell’Architetturea J2ME
MIDP
OEM
apps
J2ME APIs
Configurazione
OEM
classes
Java Virtual Machine
Sistema operativo
• Livello Profilo:
insieme minimo di
APIs
Sruttura a livelli dell’Architetturea J2ME
MIDP
OEM
apps
J2ME APIs
Configurazione
OEM
classes
Java Virtual Machine
Sistema operativo
• Livello MIDP:
– APIs per le connessioni di
rete, memorizzazione e
interfaccia utente
– Interazione con l’utente
tramite la visualizzazione
di comandi,
sostanzialmente di tre tipi:
• Richiesta di elaborazione
• Richiesta di connessione alla
rete
• Visualizzazione di un’altra
schermata
Sruttura a livelli dell’Architetturea J2ME
MIDP
OEM
apps
J2ME APIs
Configurazione
OEM
classes
Java Virtual Machine
Sistema operativo
• Applicazioni e classi
“original equipment
manufacturer” (OEM):
– Le classi sono usate da
MIDP per usi specifici del
dispositivo
(spedire/ricevere un
messaggio), o accedere a
dati
– Le applicazioni sono
programmi forniti dal
produttore, come un
address book
Le applicazioni per MIDP
• Sono dette MIDlet e devo essere realizzate per funzionare
su qualsiasi dispositivo senza alcuna modifica
• Ciò è particolarmente difficile soprattutto per le interfacce
utente
• I dispositivi hanno schermi di tutte le dimensioni, a toni di
grigio ed a colori
• Inoltre i dispositivi di input sono molteplici: tastiere
numeriche ed alfa-numeriche, soft key, mini joystick ed
anche touch screen
Applicazioni multi-device
• Data la grande varietà di dispositivi ci sono due modi per
creare applicazioni multi-device
– astrazione: specificare una UI astratta, relegando alla MIDP di
crearla in concreto (ad esempio invece di dire “visualizza la
parola 'Avanti' sullo schermo sopra il soft key”, si dice “dammi
il comando 'Avanti' da qualche parte in questa UI”
– scoperta: l'applicazione “scopre” le caratteristiche del
dispositivo a run-time e adatta la UI “al volo” (per esempio si
scoprono le dimensioni dello schermo e si scala l'applicazione)
Applicazioni multi-device (2)
• L'API MIDP supporta entrambi i sistemi
– l'astrazione è il metodo preferito poiché permette di scrivere
meno codice e delega tutto alla MIDP
– in alcuni casi (ad esempio i videogame) è invece necessario un
approccio di tipo “scoperta” per conoscere con certezza le
caratteristiche del dispositivo ed adattare il comportamento in
modo adeguato
• L'API MIDP è progettata in modo tale da permettere
facilmente anche il mix di queste due tecniche nella stessa
applicazione
MIDlet e MIDlet Suite (1)
• Comunemente, MIDlets correlate sono raggruppate in una MIDlet
suite (package), e verranno considerate come un gruppo unico in
fase di installazione/disinstallazione
• Vantaggio: i membri di una MIDlet suite condividono
– Le risorse dell’ambiente ospitante
– Le classi Java istanziate
– La JVM
• Svantaggio: condividere espone ad errori causati da accessi
concorrenti nella lettura/scrittura dei dati
– Rischio ridotto dalle primitive di sincronizzazione per l’accesso ai dati
volatili e persistenti
– Se la MIDlet usa multi-threading, è responsabile per il coordinamento degli
accessi ai dati
MIDlet e MIDlet Suite (2)
• I dati non possono essere condivisi tra MIDlets che non
appartengono alla stessa MIDlet suite, perché il nome della MIDlet
suite è usato per identificare i dati associati alla suite.
Una MIDlet di una diversa MIDlet suite è considerata una sorgente
non attendibile
• Una MIDlet suite è installata, eseguita e rimossa dall’Application
Manager (AM) che gira sul dispositivo, fornito dal produttore.
L’AM è responsabile degli accessi alle classi della JVM e CLDC
da parte delle MIDlets.
• L’AM inoltre mette il file Java archive (JAR) e il file Java
application descriptor (JAD) a disposizione dei membri della
MIDlet suite
JAD & JAR
• Le MIDlet Suite sono distribuite dalla coppia di file JAD
& JAR:
– JAD, Java Application Description: contiene tutte le
informazioni che descrivono le applicazioni, i requisiti per
l'installazione, le propietà e gli eventuali parametri per
l'esecuzione, permessi richiesti sulle API
– JAR, Java ARchive: contiene le classi dell'applicazione, le
eventuali librerie di terze parti, risorse (file di testo, immagini,
suoni, dati binari) necessari all'esecuzione dell'applicazione
• La coppia è generata automaticamente dal tool di sviluppo
JAR File
• Svolge lo stesso ruolo che ha in J2SE, con
alcune differenze:
– deve contenere l'indispensabile per l'esecuzione
dell'applicazione: il dispositivo potrebbe non essere in grado
di salvare l'archivio e il costo di trasferimento potrebbe essere
troppo oneroso
– non è possibile caricare classi e risorse da JAR file diverso da
quello di avvio
• Specificità dei dispositivi:
– i terminali possono avere una limitazione sulla dimensione
massima del JAR (ad esempio: 64K)
– alcuni terminali richiedono esplicitamente che il file JAR sia
compresso
JAR File
• Tutti i file necessari per implementare una MIDlet suite devono
essere contenuti nell’archivio JAR, e sono:
– Classi delle MIDlet
– Immagini grafiche (se richieste)
– Il file Manifesto
• Il Manifest file contiene una lista degli attributi e relative
definizioni usate dall’AMS per installare i file contenuti nel
JAR nel dispositivo
• Gli attributi sono nove, di cui tre opzionali; non includere i sei
obbligatori nel manifest file induce l’application manager a
interrompere l’installazione del JAR file.
• Il manifest file è un semplice documento di testo con estensione
.mf
Attributi del Manifest File
Attributo
Descrizione
MIDlet-Name
Nome della MIDlet suite
MIDlet-Version
Numero di versione della MIDlet
MIDlet-Vendor
Nome del venditore della MIDlet
MIDlet-n
MicroEdition-Profile
MicroEdition-Configuration
MIDlet-Icon
Attributo per la MIDlet. I valori sono: nome della
MIDlet, icona opzionale, e nome della classe MIDlet
Identifica il profilo J2ME necessario per eseguire la
MIDlet
Identifica la configurazione J2ME necessaria per
eseguire la MIDlet
(Opzionale) Icona associata con la MIDlet, deve
essere in formato PNG
MIDlet-Description
(Opzionale) Descrizione della MIDlet
MIDlet-Info-URL
URL per maggiori informazioni sulla MIDlet
Esempio di Manifest File
MIDlet-Name: Mia MIDlet
MIDlet-Version: 2.0
MIDlet-Vendor: MiaSocietà
MIDlet-1: MiaMIDlet, /images/MiaMIDlet.png,
Mia.MiaMIDlet
MicroEdition-Profile: MIDP-1.0
MicroEdition-Configuration: CLDC-1.0
• L’ordine di comparsa degli attributi non è importante
• Ogni coppia deve terminare con un ritorno carrello
JAD File
• Contiene le informazioni sull'applicazione, mostrate all'utente
prima che si proceda con il download e l'installazione del software
• Il JAD file fornisce all’application manager maggiori informazioni
sul contenuto del JAR file, per decidere se la MIDlet suite può
essere implementata sul dispositivo (configurazione, profilo...) e se
il bytecode proviene da un dominio autorizzato ad utilizzare certe
funzionalità
• Può essere un modo per passare parametri a una MIDlet senza
modificare il JAR file (il web service, ad esempio, potrebbe
inserire dinamicamente delle informazioni nel JAD)
• Il JAD file è simile al manifest file come coppie attributo-valore
• Cinque attributi sono obbligatori: MIDlet-Name, MIDlet-Version,
MIDlet-Vendor, MIDlet-n e MIDlet-Jar-URL
Attributi del JAD File
Attributo
MIDlet-Name
MIDlet-Version
MIDlet-Vendor
Descrizione
Nome della MIDlet suite
Numero di versione della MIDlet
Nome del venditore della MIDlet
MIDlet-n
Attributo per la MIDlet. I valori sono: nome della MIDlet,
icona opzionale, e nome della classe MIDlet
MIDlet-Jar-URL
MIDlet-Jar-Size
Locazione del JAR file
(Opzionale) Dimensione del JAR file in bytes
MIDlet-Data-Size
(Opzionale) Dimensione minima (in byte) per la
memorizzazione dei dati persistenti
MIDlet-Description
(Opzionale) Descrizione della MIDlet
(Opzionale) Richiesta di conferma di rimozione della
MIDlet suite
MIDlet-Delete-Confirm
MIDlet-Install-Notify
(Opzionale) Invia lo stato dell’installazione a un dato URL
Esempio file JAD
MIDlet-Version: 1.0.2
MIDlet-Vendor: Francesca Martelli
MIDlet-Jar-URL: http://www.di.unipi.it/~fmartel/labjavame.jar
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: MIDP-2.0
MIDlet-1: Demo1, /image/img1.png ,
it.unipi.di.fmartel.labjavame.HelloWorld
MIDlet-Jar-Size: 10819
MIDlet-Name: HelloWorld
• Attenzione!
– i valori degli attributi MIDlet-Name, MIDlet-Version e MIDlet-Vendor nel JAD file
devono essere identici a quelli nel manifest. Se così non è, il JAR file non viene
installato. Gli altri attributi, se diversi, verranno sovrascritti con i valori del
descrittore
– l'indicazione della dimensione del file JAR deve essere esatta, altrimenti alcuni
dispositivi non caricano l'archivio
• E' consigliabile che l'URL del JAR sia assoluto
Rilascio delle MIDlet suite
• Il rilascio dell'applicazione per l'installazione su
dispositivo può avvenire in tre modalità principali:
– Over-The-Air: l'applicazione è resa disponibile su un server
WAP o WEB pubblico, attraverso il quale il terminale J2ME
può scaricarla e procedere con l'installazione
– PC-based: si procede all'installazione attraverso software
dedicato fornito dal produttore del dispositivo
– OBEX: il terminale J2ME riceve il file jar attraverso
trasferimento OBEX (Push o FTP a seconda delle funzionalità
del terminale e del PC di appoggio) e provvedere
all'installazione in maniera autonoma
Processo di sviluppo di un MIDlet
java sources
compiler
java
bytecode
library
preverifier
JAD
JAR
packaging
tool
Preverified
java bytecode
MIDlet
• Scrivere una MIDlet è simile a creare un’applicazione
J2SE (applet), solo che è meno “robusta”
• Il nome deve essere conforme alla convenzione di
nominazione delle classi Java
• Deve estendere la classe
javax.microedition.midlet.MIDlet
• È un’interfaccia tra i comandi dell’applicazione e
l’ambiente run-time, controllato dall’application
manager.
Struttura del MIDlet
•
L’AM gestisce il ciclo di vita della MIDlet chiamando i metodi
startApp(), pauseApp(), and destroyApp(), dichiarati abstract
nella classe MIDlet:
– startApp(): comandi per l’inizio dell’esecuzione
– pauseApp(): comandi per la sospensione dell’applicazione; per ripartire
si richiama il metodo startApp
– destroyApp(): comandi per la terminazione
•
•
I metodi startApp() e pauseApp() sono public e non hanno né
valore di ritorno, né parametri
Il metodo destroyApp() è pubblico e non ritorna valore, ma ha un
parametro booleano settato a true se la terminazione della MIDlet
è incondizionata, e false se la MIDlet può lanciare una
MIDletStateChangeException, per dire all’AM che non vuole
essere distrutta in quel momento
Ciclo di vita di una MIDlet
destroyApp()
destroyApp()
startApp()
Paused
Active
pauseApp()
caricamento
Destroyed
MIDlet skeleton
import javax.microedition.midlet.*;
public class MyMIDlet extends MIDlet {
//costruttore
public MyMIDlet() { }
//metodi base:
public void startApp() { }
public void pauseApp() { }
public void destroyApp(boolean unconditional) { }
}
Inizializzazione e avvio
• Una MIDlet è un’applicazione event-based.
– Tutte le routine eseguite nella MIDlet sono invocate in risposta a un evento
riportato dall’AM.
– L’evento iniziale occorre quando la MIDlet è lanciata e l’AM invoca il
metodo startApp()
• L'inizializzazione della MIDlet deve avvenire nel costruttore:
– creazione dell'interfaccia grafica (consigliata lazy initialization)
– allocazione delle strutture dati principali
– lettura parametri di piattaforma
• Il metodo startApp() può essere invocato più volte: esso, dunque,
non inizializza alcun oggetto ma si occupa di:
– visualizzare l'interfaccia grafica: tipicamente schermata di dati e invito
all’utente a scegliere fra una o più opzioni
– avviare eventuali Thread
Sospensione
• Il metodo pauseApp() è invocato al sopraggiungere di
una chiamata o altro evento per il quale è richiesto di
sospendere l'applicazione
• Sospendere non significa andare in background!
L'applicazione deve congelare il proprio stato (così da
riprendere l'esecuzione alla successiva invocazione di
startApp()), fermare i thread e chiudere eventuali
connessioni di rete. Per sicurezza meglio salvare qualche
dato sulla flash del dispositivo! :-(
Interazione con l'Application Manager
• L'applicazione notifica all'Application Manager eventuali
variazioni nel suo stato, attraverso i metodi definiti nella
classe MIDlet:
– notifyPaused(): l'applicazione ha rilasciato le risorse ed è
in stand-by
– resumeRequest(): l'applicazione chiede all'Application
Manager di essere riavviata
Chiusura di una applicazione
• Il ciclo di vita di una MIDlet è gestito dall'Application
Manager: per questo motivo, l'applicazione non conclude
la sua esecuzione con il classico
System.exit(EXIT_CODE)
bensì notificando all'Application Manager che tutte le
risorse sono state deallocate e l'applicazione è pronta per
essere terminata:
notifyDestroyed()
J2ME Software Development Kits
• Gratis: J2ME Wireless Toolkit
(http://java.sun.com/javame/downloads/index.jsp)
• Third-party
– Borland JBuilder Mobile Set,
– Sun One Studio 4 (formerly Forte for Java)
– WebGain VisualCafe Enterprise Suite.
• Three software packages need to be downloaded from
java.sun.com:
– Java Development Kit (1.3 or greater) (java.sun.com/j2se/downloads.html),
– Connected Limited Device Configuration (CLDC)
(java.sun.com/products/cldc/)
– Mobile Information Device Profile (MIDP) (java.sun.com/products/midp/)
Creare un MIDlet con J2ME Wireless
Toolkit
• Aprire la Ktoolbar
• Cliccare su New Project e specificare:
– Nome del progetto
– Nome del MIDlet iniziale
• Nella schermata successiva, specificare le metainformazioni sul JAR file:
– Da notare il tab MIDlets per aggiungere ulteriori MIDlet
nello stesso JAR
Creazione del progetto (2)
• Nella cartella apps, apriamo la cartella
HelloWorldProject
–
–
–
–
–
bin: contiene il file JAR e il relativo descrittore
res: cartella generica di risorse, tipo le immagini
src: cartella di lavoro
project.properties è il descrittore
Alla prima compilazione verrà creata la cartella classes
Contenitori
• Il contenitore principale è il Display Manager
implementato nella classe
javax.microedition.lcdui.Display
• Ad un Display è associato un oggetto Displayable
che è un contenitore di oggetti grafici
HelloWorld.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class HelloWorld extends MIDlet{
Display display;
Form form;
public void startApp(){
display = Display.getDisplay(this); //ottengo il display
form = new Form("Hello World Program"); //creo il contenitore
StringItem sItem =
new StringItem(null,"Hello World!"); //creo il componente
form.append(sItem); //aggiungo il componente al contenitore
display.setCurrent(form); //imposto come displayable corrente
}
public void pauseApp(){}
public void destroyApp(boolean unconditional){
notifyDestroyed();
}
}
Lanciamo il nostro primo progetto!
• Torniamo su Ktoolbar e clicchiamo su Build
• Se non ci sono errori, clicchiamo su Run che
caricherà l'applicazione sull'emulatore selezionato
• La prima schermata sull'emulatore, è la lista delle
MIDlet presenti nel progetto
• Selezionando la MIDlet e premendo il tasto Launch
vediamo l'esecuzione vera e propria della MIDlet
HelloWorld
Qualche consiglio pratico
• Sviluppare applicazioni per piccoli dispositivi è una bella
sfida
• Molti metodi tradizionali non sono appropriati per
costruire applicazioni che devono girare su dispositivi
con limitate capacità computazionali
• Questo significa che bisogna “rivedere” l’approccio, con
qualche accorgimento per fronteggiare il problema delle
risorse limitate
Qualche consiglio pratico (2)
• Differenze tra i dispositivi tradizionali e piccoli dispositivi:
– Alimentazione: i primi sono continuamente alimentati, i secondi si affidano
a batterie
– Connessione di rete: i piccoli dispositivi mobili sono connessi via radio o
infrarossi, la cui qualità varia a seconda della distanza col ricevitore e la
potenza del segnale generato dal dispositivo
– Inconsistenza nella connessione di rete, tipicamente richiede all’utente di
sincronizzare dati e applicazioni con un desktop computer o un server
frequentemente.
– Programmi e dati sono memorizzati nella memoria del dispositivo e
vengono perse se cade l’alimentazione. Se persi, devono essere ricaricati nel
dispositivo. Quindi l’applicazione J2ME deve affidarsi a dati memorizzati
offline su un desktop computer o un server, piuttosto che sulla memoria
primaria del dispositivo
Qualche consiglio pratico (3)
• Non aspettatevi di trasmettere/ricevere dati allo stesso
rate di una connessione fissa, perché le tecnologie radio e
infrarossi hanno bande molto limitate
• Molti utenti si aspettano che un’applicazione J2ME abbia
la stessa risposta che avrebbe su un dispositivo
tradizionale. Quindi, bisogna disegnare l’applicazione in
modo da minimizzare/ottimizzare la trasmissione dei dati
con altre sorgenti offline
Best Practices
• Mantenere l’applicazione semplice:
– Pianificare l’applicazione dividendola in oggetti con dati e metodi associati
• Esempio: un form di un ordine è un oggetto che ha un nome, un numero, un
prodotto associato e altri dati; le funzionalità associate sono l’inserzione di un
nuovo ordine, la modifica di uno esistente, la cancellazione
– Pianificare l’applicazione dividendola in piccoli pezzi
• Esempio: piuttosto che un oggetto menu, associare una MIDlet ad ogni opzione
di menu, per ridurre le risorse di processamento
– Limitare l’applicazione alle minime funzionalità richieste, mettendo ogni
componente funzionale in una MIDlet (se possibile), e impacchettare le
varie MIDlet nella stessa MIDlet suite. Questo facilita l’application manager
del dispositivo nel gestire meglio le MIDlets e le risorse che usano
• Mantenere l’applicazione piccola
– La dimensione di un’applicazione J2ME è un punto critico per svilupparla
efficientemente.
– Rimuovere tutte le componenti non necessarie (tipo i suoni)
Best Practices (2)
• Limitare l’uso della memoria
– Gestione globale della memoria: riduce la memoria totale
necessaria all’applicazione.
• Per ridurre il fabbisogno evitare di usare i tipi oggetto; meglio i tipi
scalari. In ogni caso, usare sempre il tipo di dato minimo per
memorizzare un certo dato (per i flag, meglio i boolean che gli int…)
– Gestione della memoria in un picco temporale: minimizza la
quantità di memoria usata negli istanti di maggior uso del
dispositivo. Dipende dal garbage collector, per facilitarlo
• Allocare un oggetto subito prima di usarlo
• Settare tutte le referenze agli oggetti a null quando non servono più
all’applicazione
• Riusare gli oggetti piuttosto che crearne di nuovi
• Ridurre la probabilità di eccezione, rilasciando tutte le risorse subito
dopo il loro uso
Best Practices (3)
• Computazioni pesanti sui Server
– L’applicazione deve fare il minimo calcolo possibile, ma se è
necessaria una computazione pesante l’alternativa è costruire
l’applicazione di tipo
• client-server: il calcolo pesante lo fa il server che poi invia i risultati al
client
• web-services: tre livelli
– Livello client (presentazione): è dove l’utente interagisce facendo la
richiesta
– Livello della logica del servizio: è dove viene chiamato il software
appropriato
– Livello del processamento
– Esempio: corriere insicuro di un indirizzo, interroga il database della sua
azienda
Best Practices (4)
• Gestire l’uso della connessione alla rete
– Fare trasmissioni brevi, trasferendo il minimo indispensabile per completare
un compito
• Esempio: e-mail, invece di scaricare i messaggi, visualizzare prima i campi
“Da”, “Oggetto”, “Data” per poi decidere quale leggere, quale cancellare…
– Considerare l’uso della tecnologia store-forwarding e un server-side agent
che gira su un server che raccoglie la richiesta dal dispositivo mobile, va a
prendere l’informazione da una data sorgente, la tiene memorizzata finché il
dispositivo mobile non ne fa richiesta, e quindi viene forwardata
• Esempio: corriere che non sa la strada per raggiungere un’indirizzo, e vuole
interrogare il sistema di tracking
– Prevedere sempre un meccanismo per ripristinare una connessione caduta
• Per esempio, tenere a disposizione le informazioni chiave sulla richiesta, in
modo da ritrasmetterle automaticamente
Best Practices (5)
• Fare un’interfaccia utente semplice
– Grande varietà di forme e configurazioni hardware fra i piccoli
dispositivi, impossibile fare un’interfaccia standard per tutti.
Nel realizzare la propria user interface seguire i seguenti
consigli:
• Dove possibile, sfruttare l’interfaccia utente fornita dal dispositivo,
piuttosto che disegnarla ex-novo
• Se viene creata, considerare prima i meccanismi di input disponibili
(icone vs testo)
• Controllare le disponibilità dei caratteri della tastiera
• Limitare la quantità di input da parte dell’utente, in modo da
semplificare la selezione dal menu (regola del pollice)
Best Practices (6)
• Usare Variabili locali
– Da sviluppatori, non si può assumere che ci saranno risorse
sufficienti in ogni piccolo dispositivo per eseguire
l’applicazione…quindi questo è un punto critico per ogni
routine di un’applicazione
– Evitare le routine che aumentano l’overhead di processamento
se un’altra routine fa lo stesso compito con minori risorse
– Memorizzazione dei dati: assegnare i dati ai membri di una
classe aderisce perfettamente alla filosofia object-oriented, ma
l’accesso a questi dati è più oneroso in termini di
processamento rispetto all’uso di variabili locali
• Valutare se i benefici dell’uso delle variabili locali rispetto ai benefici
dell’incapsulazione
Best Practices (7)
• Non concatenare le stringhe
Concatenare le stringhe è un processo oneroso
Eliminare o limitare le concatenazioni per quanto è possibile
La concatenazione aumenta anche l’uso della memoria
Un’alternativa è concatenare le stringhe prima che siano
caricate nel dispositivo
– Se è necessario concatenare delle stringhe usare l’oggetto
StringBuffer, che fa un uso efficiente della memoria quando le
stringhe sono appese in un buffer, sebbene ci sia più overhead
–
–
–
–
Best Practices (8)
• Evitare le sincronizzazioni
– È molto comune invocare uno o più thread all’interno di
un’operazione.
• Esempio: routine per l’ordinamento può provocare deadlock o conflitti
se più operazioni usano la stessa routine; questo problema è risolto
sincronizzando le invocazioni dei thread
– Meglio invocare un thread che un metodo
– Limitare le sincronizzazioni, per evitare istruzioni inutili
quando la sincronizzazione è disattivata
– Regola generale: evitare la sincronizzazione a meno che non ci
sia alta probabilità di conflitto fra le operazioni