JavaTM MicroEdition -Conceptos BásicosPontificia Universidad Javeriana Computación Móvil 2008/01 Historia • Enero 15, 1991: “Green Project”: ¿Qué hacer a cerca de tanta variedad de dispositivos electrónicos? • 1999: Java se subdivide en: – Java 2 Enterprise Edition. (J2EE) – Java 2 Standard Edition. (J2SE) – Java 2 Micro Edition (J2ME) • 2001: Primeros teléfonos móviles con soporte J2ME. – Cerca de 1 Millón de descargas de Java EE. 1 Historia • 2002: 78% de las ejecuciones de J2EE son más efectivas para el desarrollo y despliegue de WS. – Segunda versión de Mobile Information Device Profile (MIDP). • 2005: 4.5 millones de desarrolladores usan Java – 2.5 billones de dispositivos con Java. – 700 millones de teléfonos móviles con soporte Java • 2006: Las tecnologías Java SE y ME son relanzadas como Open Source. Acerca de la Plataforma JME • Plataforma creada para manejar las restricciones asociadas con la construcción de aplicaciones en dispositivos pequeños. • Existe un proceso de estandarización de los componentes, especificados en JSR (Java Specification Request). • JME se basa en stack = configuración + profile(s) + APIs opcionales. 2 Acerca de la Plataforma JME – Una configuración provee el más básico conjuntos de librerías y las capacidades de la máquina virtual para un amplio rango de dispositivos. – Un profile es un conjunto de APIs (UI, Almacenamiento permanente) que soportan un restringido rango de dispositivos. – Paquetes opcionales con un conjunto de APIs(Bluetooth,Multimedia, Mobile 3D) de tecnología específica. Acerca de la Plataforma JME 3 Acerca de la Plataforma JME • La plataforma se ha dividido en dos configuraciones básicas: – Configuración para dispositivos pequeños llamado Connected Limited Device Profile (CLDC). – Configuración para dispositivos de mayor capacidad llamado Connected Device Profile (CDC). CLDC • Especificación CLDC 1.1 (JSR 30/139). • Requisitos: – Al menos 160-192 KB de memoria total disponible para la plataforma Java. – Un procesador de 16/32 bits. – Entre 8 a 32 MHz. – Bajo consumo de energía. – Conectividad de red: Inalámbrica, conexiones intermitentes y limitado ancho de banda. 4 CLDC • Es necesario disponer de una máquina virtual especial: KVM (Kilo Virtual Machine). • Es suficiente una cantidad de memoria total para las aplicaciones JAVA entre 160 KB y 512 KB. (RAM + Flash) • Hasta 2MB incluyendo el perfil y paquetes opcionales. • Velocidad de red de 9600(normalmente) o menos. CLDC 1.1 • Los paquetes y algunas de las clases que se soportan en CLDC 1.1 son: – java.lang.Thread – java.lang.String – java.lang.Boolean – java.lang.Byte – java.lang.Short – java.lang.Integer 5 CLDC 1.1 – java.lang.Long – java.lang.Float – java.lang.Double – java.lang.Character – java.util.Vector – java.util.Hashtable CLDC 1.1 • • • • • • java.io.InputStream java.io.OutputStream java.io.DataInputStream java.io.DataOutputStream java.io.Reader java.io.Writer 6 Profiles(Perfiles) • El Perfil para Dispositivos de Información Móvil(MIDP) define las clases para las aplicaciones que se ejecutan en teléfonos personales y Pocket PC de poca capacidad. • Incorpora clases para ciertas acciones extendiendo las capacidades de una configuración, para completar su funcionalidad y el uso de los elementos que proporciona un dispositivo. Profiles(Perfiles) • Los perfiles tienen sus pros y sus contras. – Pros? – Contras? • • • • El principal perfil y el más utilizado es MIDP. MIDP se basa en CLDC. MIDP no permite acceder al S.O., x ? Aplicaciones elaboradas basándose en el perfil MIDP se conocen como MIDlets. • MIPD provee: – – – – Entorno de Ejecución MIDlet Interfaz de usuario Entorno de Red Almacenamiento Persistente (+-) 7 MIDP 2.0 • Requisitos: – Memoria: Mínimo 128KB de RAM – 8 KB en memoria no volátil donde los MIDlets pueden colocar información. – Pantallas de 94*54 pixels. – Capacidad de ingreso de datos (variada) y de conexión de red. – Ventajas: • WORA: Write Once, Read Anywhere. • Security: Sandbox KVM. MIDP 2.0 8 MIDP 2.0 (Midlets) • Cada MIDlet debe extender de javax.microedition.midlet.MIDlet. – La constructora no tiene argumentos. – Conceptualmente los MIDlets son similares a los applets. • Pueden ser descargados. • Ejecutan en el entorno del dispositivo. – Se deben tener una implementación por los métodos que controlan el ciclo de vida de la aplicación. MIDP 2.0 (Midlets) • Ciclo de vida: – Un MIDlet durante su ciclo de vida (crea/destruye) puede atravesar por diferentes estados. – Los estados son: • DETENIDO: Mantiene los recursos mínimos y admite notificación asincrónica, se encuentra “en espera”. – MIDlet creado pero todavía no se ha ejecutado por primera vez el método startApp(). – Provocado por llamadas a los métodos pauseApp() o notifyPaused(). 9 MIDP 2.0 (Midlets) • ACTIVO: Estado de ejecución que se entra después de la ejecución inicial del método startApp(). – Se puede estar en este estado por la recuperación mediante la llamada al método resumeRequest() al estar en una pausa. • DESTRUIDO: Estado provocado por la invocación de los métodos destroyApp() o notifyDestroyed(). – Al estar en este estado no podrá realizar ninguna transacción a otro estado, finaliza el MIDlet. MIDP 2.0 (Midlets) 10 MIDP 2.0 (Midlets) • Ciclo de Construcción: – Editar código fuente – Compilar – Distribución: (Aplicación) • MIDlets+Clases+Recursos+Manifiesto: JAR • Manifiesto: Describe el contenido del archivo (versión de CLDC y MIDP, nombre, versión y vendedor). • Descriptor de la aplicación(*.jad): información similar como la del manifiesto (+MIDlet-Jar-Size, MIDlet-Jar-URL), archivo externo. – Algunas veces usado para la instalación. MIDP 2.0 (Midlets) 11 MIDP 2.0 (Midlets) • Interfaz de usuario: – Obj: Escribir una vez y correr en cualquier lugar. – WORA es falso: • Diferentes tamaños de pantalla. • Colores diferentes. • Diferentes capacidades de entrada. MIDP 2.0 (Midlets) • Abstracción (Método preferido) – Especifica una interfaz de usuario en términos abstractos. • Descubrir (Juegos) – Aplicación aprende acerca del dispositivo. – Tamaño de la pantalla (escalable). 12 MIDP 2.0 (Midlets) • UI: Vista desde arriba. • La clase de la UI es javax.microedition.lcdui • La pantalla del dispositivo se representa por un Display(getDisplay()). • Display(Base) • Canvas: (Descubrir/Juegos) • Screen: (Abstracción) MIDP 2.0 (Midlets) • Cambiar el contenido del display: setCurrent(). • Secuencia típica: – Mostrar una pantalla. – Esperar una entrada. – Decidir cual es la siguiente pantalla. – Repetir. 13 Herramientas / Kits de desarrollo • Sun’s MIDP reference Implementation • Sun J2ME Wireless Toolkit • IDE: – Netbeans + Mobility Pack – IBM WebSphere Sun Java Wireless Toolkit 14 Sun Java Wireless Toolkit • MSA: Mobile Service Architecture “Base del código” import javax.microedition.lcdui.*; // Paquete para el manejo de la UI en un MIDlet import javax.microedition.midlet.MIDlet; // Paquete para usar el perfil MIDlet public final class clasepersonal extends MIDlet implements CommandListener { /** * Crea la forma donde se despliega la calculadora */ protected void startApp() { } /** * Mètodo de destrucción de la aplicación */ protected void destroyApp(boolean unconditional) { } /** * Método de pausa de la aplicación */ protected void pauseApp() { } public void commandAction(Command c, Displayable d) { } /** * Extraer el número en el tipo primitivo adecuado de una caja de texto * * @param t la caja de texto donde se va a sacar el número * @param type la cadena de caracteres con el argumento numérico * @throws NumberFormatException */ private double getNumber(TextField t, String type) throws NumberFormatException { } } // final de la clase 15 “Base del código” /** El num max de caracteres. */ private static final int NUM_SIZE = 5; /** Botón de salir */ private final Command exitCmd = new Command("Salir", Command.EXIT, 2); /** Botón de Operar */ private final Command calcCmd = new Command("Operar", Command.SCREEN, 1); /** Caja de texto donde se recibe el primer argumento */ private final TextField t1 = new TextField(null, "", NUM_SIZE, TextField.DECIMAL); /** Caja de texto donde se recibe el segundo argumento */ private final TextField t2 = new TextField(null, "", NUM_SIZE, TextField.DECIMAL); /** Caja de texto donde se despliega el resultado */ private final TextField tr = new TextField("Resultado", "", NUM_SIZE, TextField.UNEDITABLE); /** Un grupo de selección con las opciones funcionales de la calculadora*/ private final ChoiceGroup cg = new ChoiceGroup("", ChoiceGroup.POPUP, new String[] { "sumar", "restar", "multiplicar", "dividir" }, null); /** Ventana de alerta para el despliegue de errores */ private final Alert alert = new Alert("Error", "", null, AlertType.ERROR); /** Indica si la aplicación esta inicializada */ private boolean isInitialized = false; “Base del código” protected void startApp() { if (isInitialized) { return; } Form f = new Form("Ejemplo de una calculadora"); f.append(t1); f.append(cg); f.append(t2); f.append(tr); f.addCommand(exitCmd); f.addCommand(calcCmd); f.setCommandListener(this); Display.getDisplay(this).setCurrent(f); alert.addCommand(new Command("Back", Command.SCREEN, 1)); isInitialized = true; } 16 “Base del código” /** * Acciones asociados a los eventos de los botones. * @param c nombre del objeto * @param d forma de despliegue que contiene el objeto donde se desarrolla la acción. */ public void commandAction(Command c, Displayable d) { if (c == exitCmd) { destroyApp(false); notifyDestroyed(); return; } double res = 0.0; try { double n1 = getNumber(t1, "uno"); double n2 = getNumber(t2, "dos"); switch (cg.getSelectedIndex()) { case 0: res = n1 + n2; break; case 1: res = n1 - n2; break; case 2: res = n1 * n2; break; “Base del código” case 3: res = n1 / n2; break; default: } } catch (NumberFormatException e) { return; } catch (ArithmeticException e) { alert.setString("División por cero"); Display.getDisplay(this).setCurrent(alert); return; } /* * El resultado */ String res_str = Double.toString(res); if (res_str.length() > tr.getMaxSize()) { tr.setMaxSize(res_str.length()); } tr.setString(res_str); } 17 “Base del código” private double getNumber(TextField t, String type) throws NumberFormatException { String s = t.getString(); if (s.length() == 0) { alert.setString("No " + type + " Argument"); Display.getDisplay(this).setCurrent(alert); throw new NumberFormatException(); } double n; try { n = Double.parseDouble(s); } catch (NumberFormatException e) { alert.setString(type + " argument fuera del rango."); Display.getDisplay(this).setCurrent(alert); throw e; } return n; } Bibliografía • http://www.java.com/en/javahistory/timelin e.jsp • http://www.java.com/en/javahistory/video.j sp • http://ils.unc.edu/blaze/java/javahist.html 18