580 likes | 810 Views
第三章 MIDP 入门. 2008-03. 内容概述. MIDP 相关名词解释 JAD 文件和 Manifest 文件详解 MIDlet 基本知识介绍 MIDlet 编程基础. MIDP 名词. MIDlet 一个可以执行的应用程序基本单位。除了继承自 javax.microedition.midlet.MIDlet 之外还包括让此类可以顺利执行的所有其他类何资源文件。 MIDlet Suite 许多 MIDlet 所构成的集合,一般又叫做 MIDlet 应用程序套件。 JAR 文件( JAR File, .jar 文件)
E N D
第三章 MIDP入门 2008-03
内容概述 • MIDP相关名词解释 • JAD文件和Manifest文件详解 • MIDlet基本知识介绍 • MIDlet编程基础
MIDP名词 • MIDlet • 一个可以执行的应用程序基本单位。除了继承自javax.microedition.midlet.MIDlet之外还包括让此类可以顺利执行的所有其他类何资源文件。 • MIDlet Suite • 许多MIDlet所构成的集合,一般又叫做MIDlet应用程序套件。 • JAR文件(JAR File, .jar文件) • 包裹住MIDlet Suite的文件,属于ZIP压缩格式。
MIDP名词 • 描述文件(Descriptor File, .jad文件) • 用来描述MIDlet Suite基本信息的文本文件,包括MIDlet Suite所包含之MIDlet相关信息(类名称、图标、程序名)或是MIDlet Suite之整体信息(文件大小,安全权限,证书等),它独立于JAR文件之外。 • 应用程序管理器(Java Application Manager) • 负责将MIDlet Suite安装到机器上执行以管理MIDlet生命周期的机制(或软件)总称。
应用程序管理器 • 什么是应用程序管理器? • 应用程序管理器(Java Application Manager, JAM)在规范中也称作Application Management Software(AMS)。这是一个用来执行J2ME应用程序的原生程序,应用程序管理器负责管理设备上所有的J2ME应用程序。
应用程序管理器 • 后台工作 • 用户不知道应用程序管理器的存在
应用程序管理器 • 单一进入点 • 用户必须先进入应用程序管理器,然后才能启动个别的Java程序
JAD与JAR • MIDP应用程序构成 • 一个完整的MIDP应用程序是由一个JAD文件(纯文本文件)与JAR(ZIP压缩文件)所组成 描述文件(.jad) MIDlet-Jar-Url:xxx.jar 执行文件(xxx.jar)
JAD文件的必要性 • 这样设计的原因 • 减少网络传输费用。用户先查看描述文件,再决定要下载的内容。 • 安全性。在描述文件中加入证书,证书中内含程序制作单位的公钥。 • 在MIDP1.0时,是否有JAD文件无关痛痒.但是在MIDP2.0之中,是否有JAD文件将涉及安全议题。
JAD与JAR的内容 • JAD的内容 • 纯文本文件,内部是一些属性和属性值 • JAR的内容 • MIDlet • 相关的Class文件 • 资源文件 • MIDlet 执行时所需要的文件,如图片、文本文件等 • 清单文件(Manifest File, Manifest.mf) • 用来描述一个MIDP应用程序的基本信息 • 存在于JAR文件内部
MIDP执行环境 • MIDP执行环境泛指MIDP应用程序在执行时期所能获得的资源: • CLDC中所定义的类库 • MIDP中所定义的类库 • 工具类:自定义类、标准Optional Package类、厂商专属程序库,其他程序库。 • 资源:MIDlet只能存取来自同一个JAR文件之中的所有非class文件。 • 权限确认与连接外部资源。 • 描述文件与清单文件的内容。 • 平台的特性。
功能与资源 • JAR文件里的资源文件读取 • java.lang.Class.getResourceAsStream() • 描述文件或清单文件读取 • javax.microedition.midlet.MIDlet.getAppProperty() • 平台特性读取 • java.lang.System.getProperty()
权限确认与连接外部资源 • 权限确认 • javax.microedition.midlet.MIDlet类提供checkPermission()方法用于权限确认 • 连接外部资源 • javax.microedition.midlet.MIDlet类提供platformRequest()方法用于连接外部资源
JAD与manifest内含的属性 • MIDP标准里预先定义的属性 • MIDlet-Name • MIDlet Suite的名称 • MIDlet-Version • MIDlet Suite的版本号 • MIDlet-Vendor • 提供此MIDlet Suite的厂商名称 • MIDlet-Icon • 此MIDlet的图标文件的文件名
JAD与manifest内含的属性 • MIDlet-Description • 描述此MIDlet的相关信息 • MIDlet-Info-URL • 描述此MIDlet更多相关信息的URL地址 • MIDlet<n> • 描述MIDlet Suite之中MIDlet的信息 • MIDlet-Jar-URL • 应用程序要下载代表MIDlet Suite的JAR文件时应该去的URL地址
JAD与manifest内含的属性 • MIDlet-Jar-Size • 此MIDlet Suite的JAR文件的大小 • MIDlet-Data-Size • MIDlet所需要的永久资料存储区 • MicroEdition-Profile • 执行此MIDlet Suite所需要的profile名称及版本 • MicroEdition-Configuration • 执行此MIDlet Suite所需的Configuration名称及版本 • MIDlet-Delete-Confirm • 删除此MIDlet Suite之前,应用程序管理器必须显示给用户的确认文字
JAD与manifest内含的属性 • 与系统相关的属性 • MIDlet-Jar-RSA-SHA1 • JAR文件的数字签名 • MIDlet-Certificate-<n>-<m> • 验证JAR文件用的安全证明 • MIDlet-Permissions • 执行此MIDlet Suite必要的权限 • MIDlet-Permissions-Opt • 执行此MIDlet Suite次要的权限
JAD与manifest内含的属性 • 与OTA相关的属性 • MIDlet-Install-Notify • 应用程序管理器安装此MIDlet Suite之后,用来报告安装结果的URL • MIDlet-Delete-Notify • 应用程序管理器删除此MIDlet Suite之后,用来报告删除结果的URL
JAD与manifest内含的属性 • 与Push机制相关的属性 • MIDlet-Push-<n> • 与javax.microedition.io.PushRegistry类有关 • 以上的属性,MIDlet都可以在执行时期通过javax.microedition.midlet.MIDlet.getAppProperty()取得。
Manifest文件必要属性 • Manifest文件里所指定的属性至少要有下列几项: • MIDlet-Name • MIDlet-Version • MIDlet-Vendor • MIDlet-<n> • MicroEdition-Profile • MicroEdition-Configuration
Manifest文件可选属性 • MIDlet-Description • MIDlet-Icon • MIDlet-Info-URL • MIDlet-Data-Size • MIDlet-Permissions • MIDlet-Permissions-Opt • MIDlet-Push-<n> • MIDlet-Install-Notify • MIDlet-Delete-Notify • MIDlet-Delete-Confirm • 其他不以”MIDlet-”或”MicroEdition-”开头的属性
JAD文件必要属性 • JAD文件里所指定的属性至少要下列几项: • MIDlet-Name • MIDlet-Version • IDlet-Vendor • MIDlet-Jar-URL • MIDlet-Jar-Size • 其他的为可选属性
JAD文件必要属性 • JAD与manifest相同的必要属性: • MIDlet-Name • MIDlet-Version • MIDlet-Vendor • 如果清单文件中这三个参数和描述文件中的这三个参数值不同,那么应用程序管理器将不会下载并安装该JAR文件
JAD与manifest属性 • 执行时期提取JAD与manifest属性: • 不受信任的MIDP Suite :先传回清单文件的属性值,然后才是描述文件内的属性值。以描述文件的属性值为主 • 受信任的MIDP Suite :先传回清单文件的属性值,然后才是描述文件内的属性值。如果有他们有相同的属性,其值一定要一样。取得的属性值以清单文件中所指定的为主
MIDlet资源共享 • 同一个MIDlet Suite里的MIDlet可以彼此共享资源和Class文件,但不同的MIDlet Suite里不行
MIDP基本程序结构 • MIDlet必须继承自javax.microedition.midlet.MIDlet类 Java.microedition.midlet.MIDlet MIDlet应用程序
MIDlet程序的基本外观 • MIDlet程序的基本外观 • startApp() 转至运作状态 • pauseApp() 转至停止状态 • destroyApp() 转至消灭状态 Import javax.microedition.midlet.MIDlet; public class TestMidlet extends MIDlet { public TestMidlet() { super(); } protected void statApp() { } protected void pauseApp() { } protected void destroyApp(bollean arg0) { } }
MIDlet起始行为 设定显示在屏幕上的画面 MIDlet进入运行状态(Active) display.setCurrent(Displayable类的子类) Application Manager调用startApp() 取得代表屏幕的Display对象 Display.getDisplay(this)
程序的关键部分 • 在构造函数中获得display • display = Display.getDisplay(this); • 在startApp()中显示Form • Form f = new Form(“Hello World”); • display.setCurrent(f);
执行结果 • 结果显示 注意:我们不能在程序里new出其他的MIDlet,并调用其生命周期的相关函数,这样做会引发SecurityException.
输出结果 打开程序 • 输出结果 设备暂停(例如电话有来电) 关闭设备 startApp()很可能不光被调用一次而已,每次从停止状态重新回到运行状态的时候都会被应用程序管理器调用,所以只需要执行一次的初始化动作不宜放在startApp()中,请改用构造函数做初始化动作
MIDlet类&应用程序管理器 • MIDlet类中定义了如下三个抽象方法,因此我们撰写的MIDlet必须实现它们: • startApp() 转至运作状态 • pauseApp() 转至停止状态 • destroyApp() 转至消灭状 • 应用程序管理器通过这三个抽象方法来控制MIDlet的生命周期。
状态变迁 • 状态改变 • 状态的改变是由应用程序管理器来执行的 • 如果MIDlet自己调用这些函数,不会造成状态的转换,只能当成一个单纯的函数调用而已 • 代码示例
MIDlet自我管理 • MIDlet可以软性改变自己状态 • 改变方法:调用相应状态改变函数 • 改变的决定权在于应用管理器,不保证一定可行
两种状态改变方式比较 • 应用程序管理器主动要求停止 • pauseApp()会被调用 • MIDlet自身调用notifyPaused() • pauseApp()不会被调用 • 但两者都会让MIDlet进入停止状态 • notifyDestroyed()与destroyApp()同理
随机数 • Java.util.Random类可用于产生随机数(只能是int或long类型) • 关键代码 • Random rdm = new Random(seedvalue); 或: Random rdm = new Random();(系统时间做为随机数种子) Int iRdm = rdm.nextInt();范围是int数据类型(32bit)
随机数 Int iRdm = rdm.nextInt();范围是[0,n) Long lRdm = rdm.nextLong();范围是long型数值范围(64bit) Double dRdm = nextDouble():范围是[0.0d, 1.0d) Float dRdm = nextFloat():范围是[0.0f, 1.0f)
随机数 • 如想设定随机数的范围是-160——160: Int res = rdm.nextInt() % 160; • 如果想设定随机数的范围是0 —— 160: Int res = (rdm.nextInt() >>> 1) % 160 • 如果想设定随机数的范围是-160 —— 0: Int res = (rdm.nextInt() | 0x80000000) % 160;
执行时间的测量 • 时间测量工具函数 • System.currentTimeMillis() • 返回值:long • 作用 • 取得目前时间与1970年1月1日零时UTC时间(协调世界时)的差距 • 平常的使用方法 • 程序开始和结束时调用此函数得到的返回值之差就是程序执行的时间
日期处理 • TimeZone • TimeZone defaulttz = TimeZone.getDefault() • 不能用new来产生 • defaulttz.getID() • 取得所使用的时区 • defaulttz.useDaylightTime() • 是否使用日光节约时间
日期处理 • defaulttz.getRawOffset() • TimeZone使用的时区和GMT相差值 • TimeZone.getAvaliableIDs() • 静态方法,取得系统所支持的时区
日期处理 • Date • Date类负责记录与1970年1月1日零时UTC时间(协调世界时)的差距 • Date date = new Date(time) • time :与1970年1月1日零时UTC时间的差距 • 可以这样产生date: Date date = new Date() 相当于 :Date date = new Date(System.currentTimeMillis()); • 注意:Date类本身仅存放时间差,如果要解析年月日以及时间那么必须要和Calendar类合用
日期处理 • Calendar • Calendar Cal = Calendar.getInstance() • 不能用new产生 Date now = new Date(); Cal.setTime(now); System.out.println(cal);
日期处理 • 可以使用get方法获得时间的某部分信息 • Cal.get(Calendar.HOUR); • Cal.get(Calendar.MINUTE); • Cal.get(Calendar.MILLISECOND); • Cal.get(YEAR); • Cal.get(MONTH);
Thread • Thread的两种建立方式 • 继承Thread类,并实现run()方法 • 实现Runnable接口,并实现run()方法 • 启动线程 • 调用Start()方法
Timer & TimerTask • Timer • 产生周期信号 • TimerTask • 与Timer连用以处理周期信号到达时所作的动作。
Timer & TimerTask • 示例 继承TimerTask类 实现run()方法 通过Timer的schedule()方法来设定特定时间或特定周期,并将它与某个TimerTask联系