770 likes | 980 Views
Programming in Java. J2ME 汪益賢 蔡文能 交通大學資訊工程學系. http://www.csie.nctu.edu.tw/~tsaiwn /java/. Outline. Java ME Java ME Architecture Java ME Specification Learning J2ME CLDC 1.0 / MIDP 2.0 APIs User Interface (lcdui) Input/Output (RMS) Networking 練習: Calculator or Monty Hall ( 手機版 ).
E N D
Programming in Java J2ME 汪益賢 蔡文能 交通大學資訊工程學系 http://www.csie.nctu.edu.tw/~tsaiwn/java/
Outline • Java ME • Java ME Architecture • Java ME Specification • Learning J2ME • CLDC 1.0 / MIDP 2.0 • APIs • User Interface (lcdui) • Input/Output (RMS) • Networking • 練習:Calculator or Monty Hall (手機版)
Java ME (formerly J2ME) • Java Platform, Micro Edition • Provides a robust, flexible environment for applications running on a broad range of other embedded devices • Mobile phones • PDAs • TV set-top boxes • Printers • Applications based on Java ME specifications are written once for a wide range of devices, yet exploit each device’s native capabilities. • Java Mobile Games
Java ME Games • The most popular application • Java-enabled devices grow rapidly. • Java mobile games almost become the name of Java mobile applications. Nokia Snake ThinkNewIdea MJ16 JoyPark-Rich
Pac-Manhattan • http://www.pacmanhattan.com/
Java ME Architecture • VMs • Configurations • Profiles • Optional Packages
J2ME Architecture • Source: http://www.j2mer.idv.tw 多層次的架構 (一堆很容易搞混的名詞) 基本上,把 Profile, Configuration 都當作是 Package 來思考
VMs for Java ME • KVM (K Virtual Machine) for CLDC • 16-bit or 32-bit processor with a clock speed of 16MHz or higher • At least 160KB memory (128KB for VM and the CLDC library + 32KB for runtime heap space) • Low power consumption (battery) • Wireless with limited bandwidth • JVM (Java Virtual Machine) for CDC • 32-bit processor • More than 512KB memory + 128KB runtime heap space • Unlimited power supply • Fast network • Target devices: smartphones, TV set-top boxes, and so on.
Configurations • Specifies the Java programming language features supported. • Specifies the Java virtual machine features supported. • Specifies the basic Java libraries and APIs supported. • Two configurations are defined: • CLDC (Connected, Limited Device Configuration) • CDC (Connected Device Configuration)
Profiles • Provide specific APIs for a certain device type. • CLDC • MID Profile (Mobile Information Device Profile) • Screen resolution: 96x54. Memory: 256KB for MIDP components, 128KB runtime space, 8KB persistent space. • PDA Profile • Screen resolution: 160x160. • CDC • Foundation Profile • No GUI • Personal Basis Profile • Lightweight component • Personal Profile • Full AWT and Applet (No Swing and Java 2D)
Optional Packages • A set of technology-specific APIs that extends the functionality of a Java application environment. • Ex: • Wireless Messaging API (WMA) • For CLDC 1.0 / MIDP 2.0 • Provides access to wireless communication resources like Short Message Service (SMS). • Mobile Media API (MMAPI) • For CLDC 1.0 / MIDP 1.0 • Provides audio, video and other time-based multimedia support. • JDBC • For CDC / FP 1.0
Focused Specifications in This Course • The CLDC Specification • Currently version 1.1 (JSR 139) • No Floating point in version 1.0 (CLDC 1.0 不支援實數) • The MIDP Specification • Currently version 2.0 (JSR 118) • Note that JSR (Java Specification Request) is the actual description of proposed and final specifications for a new Java API that is submitted to the JCP (Java Community Process). (註: JSR 類似 RFC)
Relationship between CDC/CLDC and J2SE J2SE CLDC CDC
The CLDC Specification • Java language and VM features • Security • Classfile verification • Reduced APIs • Core Java libraries (java.lang.*, java.util.*) • IO • Networking
Constraints on Java Language Specification • No floating point (float and double) • But CLDC 1.1 support floating point • No finalization (Object.finalize()) • Limited error handling
Constraints on KVM • No JNI • No user-defined class loader • No reflection • No thread groups and daemon threads • No weak references • java.lang.ref.WeakReference
Sun Java Wireless Toolkit for CLDC Buffer Overflow Vulnerabilities • http://www.vupen.com/english/advisories/2008/3439 • Two vulnerabilities have been identified in Sun Java Wireless Toolkit (WTK) for CLDC (Connected Limited Device Configuration), which could be exploited by local attackers to gain elevated privileges. These issues are caused by unspecified buffer overflow errors which may allow a malicious program downloaded and executed in the WTK to execute arbitrary code with the privileges of the WTK process. • Affected: Sun Java Wireless Toolkit for CLDC version 2.5.2 and prior. • Solution: Upgrade to Sun Java Wireless Toolkit for CLDC version 2.5.2_01 :http://java.sun.com/products/sjwtoolkit/
The MIDP Specification • Application Life-cycle Management • User Interface • Event Handling • Record Management System (RMS)
MID Profile • MIDP 1.0 Packages: • javax.microedition.lcdui.* • javax.microedition.rms.* • javax.microedition.midlet.* • javax.microedition.io.* • MIDP 2.0 Added Packages: • java.microedition.lcdui.game.* • javax.microedition.media.* • javax.microedition.media.control.* • javax.microedition.pki.* • MIDP 2.0 supportssocket connection that is not available in 1.0.
Constraints on Libraries • Only majority of the class libraries are included. • ex: • No java.io.BufferedReader/Writer,java.io.FileReader/Writer/ InputStream/OutputStream • No java.awt.* • …
Hardware Consideration • The screen size is small. • Different mobile devices have different constraints. • Different screen size. • Different Input Method • No mouse • ITU keyboard (0~9, *, #, 上下左右, …) • Touch pad • Different available memory
Learning Java ME (CLDC 1.0 / MIDP 2.0) • Development Environment • Sun Java Wireless Toolkit (currently WTK 2.5.2) • http://java.sun.com/products/sjwtoolkit/ • The Wireless Toolkit has been integrated into Java ME SDK 3.0. • Deployment • Your First MIDP Program • class HelloMidlet extends MIDlet
Sun Java Wireless Toolkit • A toolbox for developing wireless applications that are based on CLDC and MIDP. • Cell phones • Mainstream personal digital assistants • Other small mobile devices • The toolkit includes the • Emulation environments • Performance optimization and tuning features • Documentation • Examples
Deployment • There are two ways to deploy a MIDlet suite. • Direct uses some direct connection between the device and the development platform • commonly cable, infrared, or Bluetooth link • Over-The-Air provisioning (OTA) uses the device’s built-in browser to install a MIDlet suite from a remote server
JAD and JAR Files • The basic components of any MIDlet suite you will deliver • Java Application Descriptor (JAD) file • the location and size of the JAR file • the configuration and profile requirements • attributes • Java Archive (JAR) file • 在 product deployment 主題中討論
Your First MIDP Program: Hello MIDP import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class HelloMidlet extends MIDlet implements CommandListener { private Form mainForm; public HelloMidlet()//no-argument constructor { mainForm = new Form("HelloMIDlet"); mainForm.append(new StringItem(null, "Hello, MIDP!")); mainForm.addCommand(new Command("Exit", Command.EXIT, 0)); mainForm.setCommandListener(this); } protected void startApp() { Display.getDisplay(this).setCurrent(mainForm); } protected void pauseApp(){} protected void destroyApp(boolean b) {} public void commandAction(Command c, Displayable s) { notifyDestroyed();//destroy the MIDlet } }
The Life Cycle of A MIDlet • When a MIDlet begins execution, the application management software (AMS) first calls the zero-argument constructor to create a new instance of the MIDlet. Then, the AMS places the MIDlet in the Paused state. • startApp() • shift the MIDlet to the Active state • allocate resources, such as record stores, network connections, and UI components. • pauseApp() • The MIDlet is not being terminated, but it should release some resources. • destroyApp(boolean b) • The MIDlet is terminated. Release any resources acquired.
Controlling the MIDlet State • notifyPaused() – enter the Paused state. • notifyDestroyed() – inform the AMS that the MIDlet can now be considered Destroyed. • destroyApp(boolean b) • If this boolean is true, the MIDlet will be in the Destroyed state when destroyApp() returns. • If this boolean is false, the MIDlet can request not to enter the Destroyed state by throwing a MIDletStateChangeException.
Essential APIs • User Interface (lcdui) • javax.microedition.lcdui • High-Level API: Form, Alert/List/TextBox • Low-Level API: Canvas/GameCanvas, Font/Graphics/Image • Sound • Input/Output (RMS) • Networking • HttpConnection • StreamConnection • SocketConnection
Essential APIs1. User Interface • The GUI classes included in the MIDP are not based on AWT/Swing. • The AWT is designed for desktop computers and optimized for these devices, such as window management. • The AWT assumes certain user interaction models, such as mouse. • The MIDP UI consists of two APIs. • High-Level API • Portability • Gives you little control over its look and feel • Implemented by subclasses of the Screen class • Low-Level API • Control of graphic elements and input events • Implemented by the Canvas and Graphics classes • All the UI classes are placed in the javax.microedition.lcduipackage.
The MIDP GUI Programming Model • The Display class is the display manager • Instantiated for each active MIDlet • Provides information about the device’s display capabilities. • Only one screen can be visible at a time, and the user can traverse only through the items on that screen. • A screen is made visible by calling the Display.setCurrent() method. • There are three types of screens: • Screens that encapsulate a complex user interface component • Alert, List, or TextBox (High-level API) • Generic screens • Form (High-level API) • Screens used within the context of the low-level API • Canvas (Low-level API)
Example of High-Level API • GuiTest.java • Screens that encapsulate a complex user interface component • TextBox • List • Alert • Generic screens • Form
GuiTests: Main Menu (List) import javax.microedition.lcdui.*; import javax.microedition.midlet.*; public class GuiTests extends MIDlet implements CommandListener { private List mainMenu; private static final Command exitCommand = new Command("Exit", Command.STOP, 2);//priority:2 public GuiTests() { mainMenu = new List("Test Components", Choice.IMPLICIT); mainMenu.append("Test TextBox", null); mainMenu.append("Test List", null); mainMenu.append("Test Alert", null); mainMenu.append("Test Form", null); mainMenu.addCommand(exitCommand); mainMenu.setCommandListener(this); //見下一頁 mainMenu.setTicker(new Ticker(“Test GUI Components”)); //跑馬燈 showMainMenu(); } public void startApp() {} public void pauseApp() {} /*略*/ private void showMainMenu() { Display.getDisplay(this).setCurrent(mainMenu); currentMenu = "Main"; } }
GuiTests: TextBox public class GuiTests extends MIDlet implements CommandListener { private TextBox textBoxf = new TextBox("Enter Some Text:", "", 10, TextField.ANY); private static final Command backCommand = new Command("Back", Command.BACK, 0); //priority:0 private String currentMenu; public GuiTests() { textBox.addCommand(backCommand); textBox.setCommandListener(this); textBox.setTicker(new Ticker("Testing TextBox")); //跑馬燈 } private void showTextBox() { textBox.setString(""); Display.getDisplay(this).setCurrent(textBox); currentMenu = "input"; } public void commandAction(Command c, Displayable d) { List down = (List)Display.getDisplay(this).getCurrent(); switch(down.getSelectedIndex()) { case 0: showTextBox(); break; case 1: showList(); break; case 2: showAlert(); break; case 3: showForm(); break; } } }
GuiTests: List public class GuiTests extends MIDlet implements CommandListener { private List list = new List("Choose Items", Choice.MULTIPLE); private static final Command backCommand = new Command("Back", Command.BACK, 0); //priority:0 public GuiTests() { list.addCommand(backCommand); list.setCommandListener(this); list.setTicker(new Ticker("Testing List")); list.append("Item 1", null); list.append("Item 2", null); list.append("Item 3", null); } private void showList() { Display.getDisplay(this).setCurrent(list); currentMenu = "list"; } public void commandAction(Command c, Displayable d) { List down = (List)Display.getDisplay(this).getCurrent(); switch(down.getSelectedIndex()) { case 0: showTextBox(); break; case 1: showList(); break; case 2: showAlert(); break; case 3: showForm(); break; } } }
GuiTests: Alert public class GuiTests extends MIDlet implements CommandListener { private Alert soundAlert = new Alert("sound Alert"); private void showAlert() { soundAlert.setType(AlertType.ERROR); soundAlert.setString("** ERROR **"); Display.getDisplay(this).setCurrent(soundAlert); //Play Sound } }
GuiTests: Form (1/2) public class GuiTests extends MIDlet implements CommandListener { private Form form = new Form("Form for Stuff"); private Gauge gauge = new Gauge("Progress Bar", false, 20, 9); private DateField date = new DateField("Today's date: ", DateField.DATE); private TextField textfield = new TextField("TextField Label", "abc", 12, 0); private ChoiceGroup choice = new ChoiceGroup("choice", Choice.EXCLUSIVE, new String[]{"choice 1", "choice 2"}, null); private static final Command backCommand = new Command("Back", Command.BACK, 0); //priority:0 private static final Command mainMenuCommand = new Command("Main", Command.SCREEN, 1); private static final Command exitCommand = new Command("Exit", Command.STOP, 2); //priority:2 private String currentMenu; public GuiTests() { form.append(new Spacer(2, 2)); form.append(new StringItem("label", "text")); form.append(choice); form.append(gauge); form.append(textfield); form.append(date); form.addCommand(backCommand); form.addCommand(mainMenuCommand); form.addCommand(exitCommand); form.setCommandListener(this); } //接下頁
GuiTests: Form (2/2) //接上頁 private void showForm() { Display.getDisplay(this).setCurrent(form); java.util.Date now = new java.util.Date(); date.setDate(now); currentMenu = "form"; } public void commandAction(Command c, Displayable d) { String label = c.getLabel(); if(label.equals("Exit")) { try { destroyApp(true); } catch(Exception e) {} } else if(label.equals("Back")) { if(currentMenu.equals("form")) { int index = choice.getSelectedIndex(); mainMenu.setTitle("Form choice: " + index + " text:" + textfield.getString()); } showMainMenu(); } else if(label.equals("Main")) { showMainMenu(); } else {/*略*/} } }
Low-level APIs • Canvas • Not component and container architecture • It is really a canvas. • GameCanvas • Add double buffering support. • MIDP 2.0 • Graphics • Font • Image
Using Graphics • The Graphics object is obtained in the paint()method of the Canvas class. • The Graphics class is similar to that of AWT, but with limited capabilities. • Two basic kinds of drawing • Primitive graphics (shapes and text) • PNG Images (opaque, transparent, and translucent) • Provides a drawing context • The current drawing area • The current drawing color • The Coordinate System • The Two Forms of the Canvas’s repaint() Method public void repaint() public void repaint(int x, int y, int width, int height)
Painting Shapes and Text • The Graphics class can draw the following kinds of shapes: • Lines: drawLine() • Triangle: fillTriangle() MIDP 2.0 • Rectangles: drawRect(), fillRect() • Round-edged rectangles:drawRoundRect(), fillRoundRect() • Arcs: drawArc(), fillArc() • Text: drawChar(), drawChars(), drawString(), drawSubstring()
Using Fonts • static Font getFont(int face, int style, int size); • Face: FACE_SYSTEM, FACE_MONOSPACE, or FACE_PROPORTIONAL • Style: STYLE_PLAIN or a combination of STYLE_BOLD, STYLE_ITALIC, and STYLE_UNDERLINED • Size: SIZE_SMALL, SIZE_MEDIUM, or SIZE_LARGE • Get font information: Font font1 = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_ITALIC | Font.STYLE_BOLD, Font.SIZE_LARGE); Font font2 = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_UNDERLINED, Font.SIZE_SMALL); Font font3 = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM); protected void paint(Graphics g){ g.setFont(font1); g.drawString("Proportional", 10, 10, anchor); g.setFont(font2); g.drawString("Monospace", 10, 35, anchor); g.setFont(font3); g.drawString("Default Font", 10, 60, anchor); }
Anchor • The drawing of text and images is based on “anchor points.” Anchor points are used to minimize the amount of computation required when placing text. void drawString(String text, int x, int y, int anchor); boolean drawImage(Image img, int x, int y, int anchor); • Anchor value (bit mask) • Horizontal: LEFT, HCENTER, RIGHT • Vertical: TOP, VCENTER, BASELINE, BOTTOM • EX: Graphics.LEFT | Graphics.TOP
Using Images • Loading Images • Displaying Images • Performing Animation • Double Buffering
Loading Images • Using the Image.createImage() static methods • It is easy to get an Image object if image data is in PNG format. • Image Types: • Immutable images: cannot obtain Graphics object from them createImage(String pngFileName) createImage(Image source, int x, int y, int w, int h, int transform) createImage(InputStream stream) createImage(Image source) createImage(byte[] data, int imageOffset, int imageLength) createRGBImage(int[] rgb, int w, int h, boolean processAlpha) • Mutable images: can obtain Graphics object from them createImage(int w, int h)