Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 European Master on Critical Networked Systems Modulo su Mobile Systems Parte III: Sviluppo di applicazioni J2ME Lezione 2: Ciclo di sviluppo J2ME Realizzazione di applicazioni MIDP Docente: Ing. Salvatore Orlando Dipartimento di Informatica e Sistemistica Via Claudio 21, 80125 Napoli www.mobilab.unina.it [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Contenuti della lezione Application models per configurazioni CDC e CLDC Ciclo di sviluppo di un applicazione MIDP Sviluppo di applicazioni MIDP: Elementi Base LCD UI Event Handling Record Management System (RMS) www.mobilab.unina.it [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Application Models Unmanaged Managed www.mobilab.unina.it Main Class FP, PP, PBP Applet PP XLet PP, PBP MidLet MIDP [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Application Models: Main Class • Entry point: public static void main(String[] args) • La JVM carica la classe principale ed avvia il metodo main • L’applicazione termina: • 1) Invocando il metodo • 2) Quanto tutti i suoi threads (eccetto i daemon threads) terminano • 3) Mediante un segnale del S.O. System.exit() Modalità UNMANAGED: Se l’applicazione viene terminata brutalmente dal sistema operativo, potrebbe non aver rilasciato tutte le risorse di sistema acquisite www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Application Models: Applet • Supportata sin dalla prima release di Java nel 1995 public class BasicApplet extends java.applet.Applet { public BasicApplet() { // constructor - don't do much here } public // // // } • Gira sotto il controllo di un browser Web • Strettamente connessa alla pagina web in cui si trova void init() { applet context is ready, perform all one-time initialization here public void start() { // the applet is being displayed } • Applicazione managed: il ciclo di vita di una applet è sotto il controllo del browser web public void stop() { // the applet is being hidden } public void destroy() { // free up all resources } www.mobilab.unina.it } [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Application Models: Applet Ciclo di Vita Stato iniziale (Dopo l’invocazione del costruttore) L’applet non è stata ancora inizializzata I metodi start e stop consentono di avviare/fermare la applet L’invocazione del metodo init rende la applet pronta per l’attivazione (init può essere invocato una sola volta nell’intero ciclo di vita) Nello stato STOPPED la applet rilascia le risorse utilizzate www.mobilab.unina.it [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Application Models: Applet Contesto Operativo • Ottenere parametri della applet (specificati nella pagina web): getParameter • Interagire mediante l’Applet Context: • Ridimensionare la applet • Avviare una clip audio • Visualizzare un messaggio nella barra di stato del browser • Aprire una nuova finestra • Rimpiazzare la URL corrente • Interagire con i Web Forms via DOM e Javascript www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Application Models: XLet Managed Applications: vengono gestite da un software special purpose insito nella Java Virtual Machine www.mobilab.unina.it import javax.microedition.xlet.*; public class BasicXlet implements Xlet { private XletContext context; public BasicXlet() { // constructor - don't do much here } public void initXlet(XletContext context) throws XletStateChangeException { // called by the system to //initialize the Xlet this.context = context; } public void destroyXlet(boolean unconditional) throws XletStateChangeException { // the system destroys the Xlet } public void pauseXlet() { // the system pauses the Xlet } public void startXlet() throws XletStateChangeException { // the system activates the Xlet } } [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Application Models: XLet Ciclo di Vita La XLet può essere distrutta in qualsiasi istante Stato iniziale (Dopo l’invocazione del costruttore) la XLet non è stata ancora inizializzata L’invocazione del metodo initXLet rende la XLet pronta per l’attivazione (viene fornito alla XLet un riferimento al contesto col quale interagire) www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Application Models: XLet Contesto Operativo • L’interazione è regolata dall’interfaccia javax.microedition.xlet.XletContext • getContainer restituisce l’oggetto di interfaccia utente principale dell’applicazione • getXletProperty restituisce le proprietà di inizializzazione della XLet • notifyDestroyed porta lo stato della XLet a Destroyed • notifyPaused porta lo stato della XLet a paused • resumeRequest richiede all’Application Management System (AMS) di riattivare la XLet www.mobilab.unina.it [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Application Models: MidLet import javax.microedition.midlet.*; • Managed Application: viene gestita un software special purpose (AMS – Application Management System) public class BasicMIDlet extends MIDlet { public BasicMIDlet() { // constructor - don't do much here } protected void destroyApp(boolean unconditional) throws MIDletStateChangeException { // the system destroys the MIDlet } • L’AMS deve essere incorporato nel dispositivo (cellulari, smartphones o pagers): le midlet potrebbero essere interrotte da eventi esterni (come una telefonata) protected void pauseApp() { // the system pauses the MIDlet } protected void startApp() throws MIDletStateChangeException { // the system activates the MIDlet } } www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Application Models: MidLet Ciclo di Vita La MidLet è stata costruita ed è attualmente inattiva (si noti l’assenza dello stato loaded) startApp provoca l’attivazione della Midlet. Se questa non può avvenire, si solleva un eccezione e la MidLet viene distrutta La MidLet è terminata è pronta per essere “riciclata” dal Garbage Collector La MidLet può essere distrutta anche nello stato ACTIVE www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Application Models: MidLet Contesto Operativo • Ottenere proprieta’ di inizializzazione: getProperty Le proprietà di inizializzazione sono contenute in un apposito descrittore chiamato Java Application Descriptor • Richiedere la riattivazione della MidLet: resumeRequest La richiesta viene inoltrata all’AMS, che in seguitò decidera se e quando riattivare la MidLet (re)invocando il metodo startApp • Mettere in pausa la MidLet: notifyPaused • Distruggere la MidLet: notifyDestroyed www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Ciclo di sviluppo di una MidLet Il ciclo di sviluppo di una Applet o di una XLET è identico a quello di una tradizionale applicazione Java 1. Compilazione – bisogna fornire il classpath delle librerie J2ME a javac 2. Pre-Verifica – altera il classfile al fine di allegerire il meccanismo di verification a runtime (come richiesto dalla configurazione CLDC) 3. Packaging – produce la MidLet suite, costituita da un jar includente tutti i class file e da un application descriptor, il JAD 4. www.mobilab.unina.it Testing – collaudo della MidLet su di un emulatore (generico o specifico per una determinata classe di dispositivi) [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Java Application Descriptor (JAD) •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 (un 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 MIDlet-Jar-URL www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Java Application Descriptor (JAD) MIDlet-Version: 1.0.2 MIDlet-Vendor: Totore Consulting MIDlet-Jar-URL: http://www.mobilab.unina.it/hello.jar MicroEdition-Configuration: CLDC-1.1 MicroEdition-Profile: MIDP-2.0 MIDlet-1: Demo1, /image/img1.png , org.mobilab.midlets.HelloWorld MIDlet-Jar-Size: 10819 MIDlet-Name: HelloWorld www.mobilab.unina.it [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: Elementi Base • Ogni MidLet deve ereditare dalla classe javax.microedition.midlet.MIDLet • I metodi di tale classe consentono all’AMS di creare, avviare, mettere in pausa e distruggere una MidLet. • Una MidLet deve pertanto implementare almeno i seguenti metodi: • void startApp() • void pauseApp() • void destroyApp(boolean unconditional) www.mobilab.unina.it [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: LCD UI (1/5) • API per la creazione di interfacce grafiche per dispositivi con display LCD • Contenute nel package javax.microedition.lcdui • Divise in due gruppi logici: • Alto livello – Classi molto astratte (il rendering dipende dal particolare dispositivo). Consentono la realizzazione di interfacce piuttosto evolute. • Basso livello – Consentono controllo preciso sul rendering dei controlli. Sono meno portabili. In questa lezione non ci concentremo su queste API www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: LCD UI (2/5) Displayable e Display • Al fine di essere visualizzato sullo schermo di un dispositivo, un elemento deve implementare l’interfaccia Displayable • Le classi che implementano Displayable possono avere un titolo, un ticker ed una serie di comandi • La classe Display rappresenta un astrazione dello schermo di un dispositivo. • Fornisce metodo per acquisire informazioni sullo schermo • Visualizza un Displayable o cambia il Displayable correntemente visualizzato mediante il metodo setCurrent(Displayable element) www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: LCD UI (3/5) Screens Classi che implementano l’interfaccia Displayable • Alert Utilizzata per visualizzare informazioni o messaggi di errore. Il titolo viene settato esclusivamente nel costruttore, mentre il messaggio visualizzato può essere cambiato con il metodo setString. I comandi agiscono analogamente ai pulsanti nelle message box. • Textbox Consente di immettere testo in una casella. Consente di impostare alcuni parametri, come il massimo numero di caratteri. La effettiva validità dei parametri impostati dipende però anche dalle caratteristiche dei dispositivi. • List Realizza una selezione tra più elementi. La selezione può essere multipla (Checkboxes), esclusiva (RadioButtons) o implicita (Semplice Elenco) • Form E’ il displayable più completo (e complesso). E’ una collection di instanze di elementi di tipo Item. Provvede delle versioni “itemizzate” anche degli elementi TextBox e List www.mobilab.unina.it [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: LCD UI (4/5) Forms • Insieme di istanze di oggetti che implementano l’interfaccia javax.microedition.lcdui.Item • Gli elementi vengono aggiunti al form mediante il metodo append(Item item) 1° elemento – indice 0, 2° elemento – indice 1, … • Per aggiungere gli elementi in una posizione specifica si può usare il metodo insert(int index, Item item) • Per rimpiazzare un elemento si può usare il metodo set(int index, Item item) Elementi Forms • StringItem – etichetta non modificabile • DateField – Campo per inserire una data od un ora • TextField – Casella di testo (analoga alla TextBox) • ChoiceGroup – Gruppo a selezione singola/multipla (analoga alla List) www.mobilab.unina.it • Spacer – elemento invisibile che aggiunge spazio tra i controlli • Gauge – Controllo “Barra di progresso” • ImageItem – per inserire un immagine nel form • CustomItem – Classe astratta. Consente la creazione di controlli “personalizzati” [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: LCD UI (5/5) Commands • L’interazione tra la MidLet e l’utente avviene attraverso i comandi • Un Comando equivale ad un pulsante o ad una voce di menu in un’applicazione “standard” • Ad ogni Displayable possono essere agganciati dei comandi utilizzando il metodo addCommand(Command command) • Un Command è composto da: • Una “short label” (obbligatoria) ed una “long label” (opzionale) • Un tipo di comando (Es.: Command.EXIT, Command.OK) - utilizzato per il mapping con i tasti del dispositivo • Una priorità - utilizzata per indicare al dispositivo una priorità nella visualizzazione dei comandi • La MidLet può gestire l’azione connessa all’esecuzione di un comando implementando l’interfaccia javax.microedition.lcdui.CommandLister • bisogna implementare il metodo CommandAction(Command c, Displayable d) c indica il comando invocato, d indica su quale elemento è stato invocato www.mobilab.unina.it [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: Event Handling (1/3) • L’interazione avviene tramite Callbacks • Tipi di UI Callbacks in MIDP: 1. Comandi astratti (facendi parti della UI di alto livello) 2. Eventi di basso livello (pressioni e rilascio di tasti) 3. Invocazioni del metodo paint della classe Canvas 4. • Invocazioni del metodo run di oggetti Runnable richieste attraverso una chiamata la metodo callSerially della classe Display In questa lezione ci occuperemo esclusivamente della gestione degli eventi di alto livello, impiegati per: • Navigazione attraverso Screens (diverse istanze di Displayable) • Automatizzazione Forms (gestione eventi legati a singoli Items dei forms) www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: Event Handling (2/3) Gestione eventi per Displayables Realizzata implementando l’interfaccia CommandListener 1. Creazione del Displayable 2. Aggiunta dei comandi al Displayable 3. Impostazione del command listener per il Displayable NB: Diversi Displayable possono condividere lo stesso CommandListener menu = new List("Menu Items", Choice.IMPLICIT); menu.append("Item1", null); menu.append("Item2", null); menu.append("Item3", null); menu.append("Item4", null); menu.addCommand(exitCommand); menu.setCommandListener(this); www.mobilab.unina.it La classe in cui viene definito il displayable è anche un Command Listener. (NB: Le istanze della classe CommandListener devono implementare il metodo CommandAction) [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: Event Handling (3/3) Gestione eventi per Forms Realizzata implementando l’interfaccia ItemStateListener • Gestisce eventi relativi a cambiamenti nello stato interno dei controlli dei forms Variazione valore gauge bar, immissione testo in un Text field, immissione date in Date field, selezione valore in Choice Group • Il listener deve implementare il metodo itemStateChanged(Item item) • All’atto della creazione deve essere registrato il suo listener • E’ compito del listener distinguere a quale degli items del form l’evento faccia riferimento ed effettuare il casting opportuno www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: RMS (1/6) • La memorizzazione persistente dei dati è una caratteristica desiderabile in tutti i dispositivi • In J2SE il problema viene risolto mediante JDBC, che prevede l’esistenza di drivers (Java, parzialmente nativi, o totalmente nativi) per connettersi ad un DBMS • In sistemi caratterizzati da risorse notevolmente limitate tutto ciò non è possibile • J2ME per la configurazione CLDC prevede una semplice API, il Record Management System (RMS) • RMS non è assolutamente un DBMS. Fornisce un semplice meccanismo per gestire un insieme di records resi univoci mediante un ID intero incrementale • RMS fornisce metodi per gestire “record stores” ed inserire, aggiornare ed eliminare records www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: RMS (2/6) • Le API sono contenute nel package javax.microedition.rms • Una record store è una collezione di record unicamente identificati da un ID intero incrementale. • Le record stores non sono assolutamente paragonabili ai database relazionali • La rappresentazione delle record stores (files binari) è dipendente dalla piattaforma • I nomi delle record stores sono case sensitive e non posso superare i 32 caratteri di lunghezza • Due record stores nella stessa Midlet suite non possono avere lo stesso nome • Le record stores vengono memorizzate in una sottocartella dell’applicazione chiamata NOJAM www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: RMS (3/6) Gestione di Record Stores Apre (e se del caso crea) una record store. Se la stessa record store è già aperta da un’altra MidLet nella stessa suite restituisce un riferimento alla record store già aperta. public static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary) throws RecordStoreException, RecordStoreFullException, RecordStoreNotFoundException Elimina una record store. In caso di problemi di diritti d’accesso solleva un eccezione. public static void deleteRecordStore(String recordStoreName) throws RecordStoreException, RecordStoreNotFoundException Restituisce l’elenco dei nomi delle record stores gestite dalla MidLet suite corrente public static String[] listRecordStores() Restituisce il numero di records contenuti nella record store public int getNumRecords() throws RecordStoreNotOpenException www.mobilab.unina.it [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: RMS (4/6) Lettura di records •Il metodo getRecord restituisce un array di bytes contenente uno specifico record ID •La dimensione del record può essere ottenuta mediante il metodo getRecordSize •NB: I record non sono strutturati per campi, il parsing dell’array di byte recuperato è lasciato all’utente for (int i = 1; i <= recStore.getNumRecords(); i++) { // Allocate more storage if necessary if (recStore.getRecordSize(i) > recData.length) recData = new byte[recStore.getRecordSize(i)]; len = recStore.getRecord(i, recData, 0); System.out.println("Record ID#" + i + ": " + new String(recData, 0, len)); } www.mobilab.unina.it [email protected] Mobile Systems S. Russo European Master on Critical Networked Systems Mobilab Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: RMS (5/6) Aggiunta/Modifica Records 1. Trasformare i dati da scrivere in array di bytes 2. Utilizzare il metodo addRecord • Il primo parametro è l’array di bytes da scrivere • Il secondo parametro è l’offset al quale iniziare la scrittura • Il terzo parametro è il numero di bytes da scrivere byte[] rec = str.getBytes(); try { recStore.addRecord(rec, 0, rec.length); System.out.println("Writing record: " + str); } catch (Exception e) { System.err.println(e.toString()); } Per modificare records si può utilizzare il metodo setRecord NB: E’ necessario conoscere l’ID del record da modificare www.mobilab.unina.it [email protected] Mobile Systems S. Russo Mobilab European Master on Critical Networked Systems Napoli, Maggio-Giugno 07 ::. Sviluppo MIDP: RMS (6/6) Eliminazione Records L’eliminazione è possibile attraverso il metodo deleteRecord NB: Anche in questo caso è necessario conoscere l’ID del record da eliminare La classe RecordStore non fornisce alcun metodo per ottenere l’ID del record WorkAround: 1. Ogni volta che un record viene creato aggiungere l’ID del record ad un opportuna struttura dati 2. Per individuare il record da aggiornare/eliminare bisogna iterare su tale vettore www.mobilab.unina.it Vector recordIDs = new Vector(); int lastID = 1; //Add a record....parameters are missing here db.addRecord(); // Now add the ID to the vector recordIDs.addElement(new Integer(++lastID)); Enumeration IDs = recordIDs.elements(); while(IDs.hasMoreElements()) { int id = ((Integer) IDs.nextElement()).intValue(); //Compare to see if this is your record //Then call db.deleteRecord(id); } [email protected] Mobile Systems S. Russo