8.多线程
使用多线程有两种方法:,
一是扩展Thread类:继承Thread类,重载Thread类的run方法,必须Thread类的start方法来启动线程
Thread th=new Thread();
th.start();
另一个方法是实现runnable接口:
实现runnable接口的run方法
Thread th=new Thread(new runnable());
th.strat();
9.记录管理系统(RMS)
9.1MIDP提供了一种特殊的持久化机制-RMS,它本质就是一个小型的数据库管理系统,以一种简单的,类似表格的形式组织信息,并把信息存储起来
Records Stores:记录仓库类似于数据库中的表
Records:记录是系统中最重要的实体,相当于一条记录。存储的是字节数组
RMS的读写操作是线程安全的,但Records Stores是整个Suite共享的,应该进行必要的线程同步
9.2管理RecordStore对象
9.2.1 打开RecordStore:通过一组静态方法openRecordStore来取得实例
openRecordStore(String name, boolean creaeIFNew, int auth, boolean writable)
RecordStore的名称 如不存在是否创建 读权限 写权限
提供两个入口的是name和creaeIFNew只限于本的并且拒绝其他Midlet写
提供三个入口的是nane,发布商,Midlet Suite套件名
9.2.2 关闭RecordStore:closeRecordStore(),在调用后并不会立即关闭。因为它是共享的,只有关闭的次数和打开的次数一样时才真正关闭
9.2.3 删除RecordStore:deleteRecordStore(),一个Midlet Suite只删除它自己的RecordStore。在删除前确保RecordStore是关闭的
9.2.4 获取RecordStore的属性信息
1)getLastModified():返回RecordStore最后更新的时间
2)getName():返回一个已经打开的RecordStore名称
3)getNumRecords():返回当前RecordStore中Record总数
4)getSizeAvailable():返回当前RecordStore中可用的字节数
5)getVersion():返回RecordStore版本号
6)listRecordStores():获取该Midlet套件中所有RecordStore列表
9.3 管理Record对象
9.3.1 增加
addRecord(byte[] data,int offset,int numBytes) 数据/位置/长度
返回的是记录的ID号(自增的),而且该操作是一个原子操作。
9.3.2 获取Recore
byte[] getRecord(int recordID)或int getRecord(int recordID,byte[] buffer,int offset)
例:
byte[] rev=new byte[rs.getRecordSize(id)];
rs.getRecord(id,rev,0);
String revstr=new String(rev);
9.3.3 删除
deleteRecord(int recordID)
9.3.4 修改
setRecord(int recordID,byte[] new, int offset,int numBytes)
9.3.5 其他数据类型与字节数组的转换
要写入数据,先建立一个ByteArrayOutputStream的实例baos,然后把它作为参数传给DataOutputStream构造一个dos实例 ,然后调用I/O方法:writeXXX来把不同的数据到入流中。最后利用baos的toByteArray方法得到一个byte[]数组,将这个数组传给addRecord方法即可。最后关闭
ByteArrayOutputStream baos=new ByteArrayOutputStream();
DataOutputStream dos=new ByteOutputStream(baos);
dos.writeInt(15);
dos.writeUTF("abc");
dos.writeBoolean(false);
byte []data=baos.toByteArray();
dos.close();
baos.close();
rs.addRecord(byte,0,byte.length));
要读入数据,先利用getRecord(id)得到byte数组,然后利用得到数据构造一个ByteArrayInputStream的实例bais,再用DataIntputStream包装它,得到一个实例dis。DataInputStream有一组方便的IO操作用于读DataOutputStrema对应写入的数据。但读入顺序与写入的顺序一样。
byte[] rev=new byte[rs.getRecordSize(id)];
rs.getRecord(id,rev,0);
ByteArrayInputStream bais=new ByteArrayInputStream(byte);
DataInputStream dis=new DataInputStream(bais);
boolean flag=dis.readBoolean();
int value=dis.readInt();
String str=dis.readUTF();
dis.close();
dais.close();
9.4 RecordStore的高级操作:主要体现在4个接口的使用:RecordComparator,RecordEnumeration,RecordFilter和RecordListener
9.4.1 RecordEnumeration遍历接口:MIDP规范中提供的一种安全可靠的遍历方式。RecordEnumeration接口读取数据时,实际上是访问RecordStore中的数据。RecordEnumeration如同一个RecordID的集合
相关主要方法:
1)enumerateRecords(RecordFilter filter,RecordComparator comparator,boolean keepUpdated):通过对RecordStore实例调用些方法可以取得一个RecordEnumeration接口的实例,参数:过滤器/排序策略/是否更新
2)int numRecords():返回当前遍历集合中可用的Record数目。
3)boolean hasNextElement():判断RecordEnumeration接口当前指向的下一个位置是否还有记录
4)boolean hasPreviousElement():判断RecordEnumeration接口当前指向的前一个位置是否还有记录
5)byte[] nextRecord():返回遍历器下一位置的Record拷贝。
6)int nextRecordId():返回当前遍历器下一位置记录的RecordID
9.4.2 RecordFilter过滤接口:过滤不满足条件的记录.
实现boolean matches(byte[] candidate)方法
9.4.3 RecordComparator比较接口:用于比较两条记录是否匹配,
实现int compare(byte[] rec1,byte[] rec2)方法
rec1在次序上领先于rec2时,返回RecordComparator.PRECEDES;反之返回RecordComparator.FOLLOWS
相等返回RecordComparator.EQUIVALENT
9.4.4 RecordListener监听器接口:用于监听RecordStore中记录添加,更改或删除等事件的接口。它作用在RecordStore上。
利用RecordStore的addRecordListener方法来注册一个监听器。必须实现recordAdded,recordChanged,recordDelete方法
这三个方法都要输入两个参数:recordStore和RecordID。监听是在对RecordStore的操作完成后被调用的
10. 无线联网技术
J2ME:CLDC提出通用连接框架(Generic Connection Framework,GCF)来解决不同移动设备的联网问题
有两个特点:1.基于接口设计,2提供创建连接的方法,使用标准的URL简化程序员工作
10.1 GCF架构:最上层的接口是Connection,其他接口都是继承自Connection。在Connection中只定义了一个close方法
在GCF中StreamConnection基于(流连接)TCP的,DatagramConnection基于(数据报)UDP。基于流传输的要操作输入流和输出流
因此StreamConnection扩展了InputConnection和OutputConnection
MIDP对GCF的扩展:ServerSocketConnection,SocketConnection,UDPDatagramConnection,HttpConnection。
其中HttpConnection是MIDP规定设备中必须支持的
GCF的使用:
开发人员就是写出不同的URL,并通过强制类型转换得到需要的连接类型
String url="http://www.163.com";
HttpCOnnection httpcon=(HttpConnection)Connector.open(url) //得到连接并强制转换
10.2 使用HTTP连接Internet
String url="http://www.163.com";
HttpCOnnection httpcon=(HttpConnection)Connector.open(url) //得到连接并强制转换
DataInputStream dis=httpcon.openDataInputStream(); //得到输入流
byte image[]=new byte[httpcon.getLength()];
dis.readFully(image); //把输入流中的数据写到byte数组中
连接类型有file(IO),comm(串行端口),socket(TCP/IP),Datagram(Datagram通信),http(访问web服务器)
10.3 Socket网络连接应用
使用Socket是连接两个设备最简单的方法,是TCP协议的所以也保证了传输的质量,但并不是所有的MIDP设备都支持Socket网络
Socket连接口主要的两个接口是SocketConnection和ServerSocketConnection。与j2se的使用方法相似。开发人员开以用
getLocalAddress()和getLocalPort()两个方法获得本地的绑定IP和端口
Server端:
ServerSocketConnection scn=(ServerSocketConnection)Connector.open("socket://:50009");
SocketConnection sc=(SocketConnection)scn.acceptAndOpen(); //等待客户端的连接
InputStream is=sc.openInputStream(); //得到输入流
OutputStream os=sc.openOutputStream(); //得到输出流
到时可用int i=is.read()得到输入流的数据
用os.write("消息")把数据写到输出流中
Client端
SocketConnection sc=(SocketConnection)Connector.open("socket://localhost:50009");
InputStrema is=sc.openInputStream();
OutputStream os=sc.openOutputStream();
到时可用int i=is.read()得到输入流的数据
用os.write("消息")把数据写到输出流中
10.4 Datagram网络连接应用
是基于UDP通信协议的。传输的单元是UDP数据报。
Server端:
String address;
DatagramConnection dc=(DatagramConnection)Connector.open("datagram://:5555"); //建立UDP服务器端
Datagram dg=dc.newDatagram(100); 创建UDP数据包
//接收
dc.receive(dg); 把接收到的数据放到数据包中
address=dc.getAddress(); 从连接中得到客户端的地址
System.out.println("接收的数据:"+dg.getData()); 得到数据包中的数据
//发送
byte[] bytes=String.getBytes(); 把发送的数据转换成byte[]类型
dg=dc.newDatagram(bytes,bytes.length,address); 根据发送的数据,数据长度,和要目标地址创建一个UDP数据包
dc.send(dg); 向发送这个UDP数据包
Client端
DatagramConnection dc=(DatagramConnection)Connector.open("datagram://localhost:5555"); //根据IP和PORT连接服务器
Datagram dg=dc.newDatagram(100); 创建一个UDP数据包
//接收
dc.receive(dg); 把接收中数据放到数据包中
System.out.println("接收的数据:"+dg.getData()); 得到数据名的数据
//发送
byte[] bytes=String.getBytes(); 把发送的数据转换成byte[]类型
dg=dc.newDatagram(bytes,bytes.length); 根据要发送的数据,数据长度创建一个UDP数据包
dc.send(dg) 给服务器发送这个数据包
11. MIDP安全体系模型
MIDP2.0与1.0采用了完全不同的安全体制
J2ME的安全机制主要由CLDC规范来实现,并没有采用标准JAVA的安全机制。CDLC安全模型有两个级别的安全机制:1)底层安全机制
2)应用层安全机制
11.1 MIDP2.0安全模型
11.1.1 许可:用来保护对敏感API的访问。许可的交互模式有两种:allowed和User许可
11.1.2 保护域:是一组许可及作用在这组许可上的交互模式。四种保护域:制造商域、运营商域、可信任第三方域和非信任域
11.1.3 许可文件的申请
应用中用到了敏感API,许可必须要写到JAD属性文件中Midlet-Permissions(用于程序运行必需的许可申请)和Midlet-permissions-opt
(用于可选的附加许可申请)
11.1.4 工作组
一些许可是相关联的,可以将一些相关联的许可集成到一个功能组中,这样就需要由用户管理Midlet套件所请求的各种许可。
用户可以直接将功能组赋予给某个保护域
MIDP2.0和JTWI规范已经定义了如下功能组
1)Net Access:包含与网络数据连接有关的许可。
2)Messaging:与发送与接收SMS等消息有关的一系列许可
3)Auto Invocation:与自动启动Midlet(例如通过Push Registration)有关的许可
4)Local Connectivity:与通过IrDA或蓝牙等本地端口连接有关的许可
5)Multimedia Recording:允许录制图像、音频、视频等的许可
6)Read User Data:读取电话簿或日历条目等用户数据的一系列许可
7)Write User Data:与写用户数据有关的许可
11.2 MIDP应用的数字签名
如果MIDP应用程序需要经常用敏感的API,最好将开发程序安装到设备的信任保护区域,这样MIDP应用程序首先要进行数字签名
要给Midlet签名,需要一个遵循X.509公钥架构规范的代码签名证书。
任何给Midlet签名的证书均以Midlet-Certificate-<n>-<m>属性形式,包含在JAD文件中
WTK提供了签名的支持,操作见基础篇
12 Push技术概述:
在MIDP1.0中,只能通过应用程序管理器才能启动一个Midlet应用程序,但在MIDP2.0后,可以通过一个网络请求或一修定时器来异步启动一个Midlet程序。这就是Push技术
Push技术属于一种事件触发的异步通信机制。但是Push是2.0的一个可选项,即设备可以支持,不支持,或者部分支持
12.1 Push Registry组件
是应用程序管理器的一个重要组件,它将Push注册事件与特定的Midlet应用程序关联起来
在MIDP2.0中,Push机制可以通过两种方式激活Midlet:接入的网络连接;计时器的警告通知
因此Push Registry组件必须实现对接入的网络连接和计时器的警告通知进行监控,Push Registry包含以下内容
1)接入连接列表
2)计时器的警告列表
3)接入连接Midlet客户列表
4)计时器警告Midlet客户列表
12.1.1 PushRegistry常用方法
1)String getFilter(String connection):取得指定连接的过滤器
2)string getMidlet(String connection):取得指定连接的注册Midlet
3)String[] listConnections(boolean available):返回当前Midlet套件中注册的连接列表
4)long registerAlarm(String midlet,long time):注册一个计时器来启动参数指定的应用程序
5)void registerConnection(String connection,String midlet,String filter):在应用程序管理软件中注册一个动态连接
6)boolane unregisterConnection(String connection):删除一个动态连接注册
12.1.1 Push注册
静态:是在Midlet Suite安装时完成的。要通过在Midlet Suite的JAD文件中指定的Midlet-push字段信息。而且在开发注册中只能使用WTK的Run via OTA功能来测试
Midlet-push-<n>:<ConnectionURL>,<MidletClassName>,<AllowedSender>
<n>:是Push注册的属性名称,一个Midlet套件可以有多个Push注册属性
<ConnectionURL>:是在Connector.open()中使用的连接字符串
<MidletClassName>:是在Push Registry中进行注册的Midlet名称,全路径,包括包名
<AllowedSender>:是用来说明过滤器的,可以对激活Midlet的来源进行限制。可以直接指定IP,也可以使用通配符
动态:是指通过使用Push Registry应用编程接口在运行时进行注册。基于时钟和inbound连接的两种方式都可以用动态
12.1.2 Push事件的处理
在MIDP2.0中,Push的处理是由应用程序管理器来Midlet共同负责的。
Midlet向PushRegistry注册接入连接类型Push事件,应用程序管理器负责监控是否有接入连接;当应用程序管理器发现接入连接时,通过new方法创建一个Midlet的实例并调用Midlet的StartApp()方法来激活Midlet;Midlet调用PushRegistry接口的listConnection()方法来获取接入的所有连接;Midlet调用Connector的open()方法来打开连接并进行相应的数据
12.2 基于接入网络连接的Push应用
12.2.1 静态注册的接入网络连接Push
用WTK新建一个工程,并加入自己的Midlet应用程序。要完成静态注册,要把Push注册信息添加到JAD文件中。[Setting]- [Push Registry]-[Add]。在[Connection-URL]中添加在Connector.open()中使用的连接字符串,如sms://:5001。
在[Class]中添加Midlet的名,要全路径的,如ReceiveSMSMidlet,在[AllowedSender]中添加过滤器,如*表示允许接收任意 地址发送的信息。添加后在JAD中描述为[Midlet-Push-1:sms://:5001,ReceiveSMSMidlet,*]。
测试:
Push只能通过OTA下载安装。安装后[File]-[Untilities]-[Open Console]单击[Send SMS]在对话框中选择Port和仿真器的号码
12.2.2 动态注册的接入网络连接Push
PushRegistry.registerConnection("socket://:6000","ReceiveSMSMidlet","*") 注册
PushRegistry.unregisterConnection("socket://:6000") 删除注册
String[] c.listConnections(true) 判断是否被Push激活
如果被激活处理Push激活事件
(如:建立一个数服务器的连接,并接收服务器发送的信息,一般情情况是建一个线程类,在线程中来实现操作。为了避免系统响应被阻塞)
12.3 动态注册与基于计时器的Push
基于时钟的动态注册要调用PushRegistry.registerAlarm(String Midlet,long time)方法即可。这样指定的时间到达,应用程序管理器就会自动运行指定的Midlet。每个Midlet只有一个基于计时器的注册,重复调用registerAlarm会覆盖上次的结果。
说明:基于计时器的Push注册只能通过动态注册来完成
一般操作是写一个线程类来处理操作。把Midlet名和运行的时间做为入口参数。在线程中调用registerAlarm方法
12.4 Push应用开发注册事项
如果要使用Push技术,需要申请javax.microdition.io.PushRegistry许可
分享到:
相关推荐
【J2ME进阶知识点】 1. 狭义PDA特指手持设备,广义PDA涵盖所有便携式电子设备。 2. PDA通常分为消费型PDA(主要用于个人事务管理)和专业型PDA(如医疗、物流等领域专用设备)。 3. MIDP(Mobile Information ...
**六、J2ME进阶话题** 1. **游戏开发**:J2ME因其跨平台特性在早期移动游戏开发中广泛应用,涉及图形、动画和音频处理。 2. **蓝牙通信**:通过JSR-82(Java Bluetooth API)可以实现设备间的蓝牙通信。 3. **...
教程名称:J2ME手机开发编程菜鸟进阶视频教程课程目录:【】J2ME入门视频教程.05(TextField使用和事件【】J2ME入门视频教程.06(ChoiceGroup使用和获取选项值)【】J2ME入门视频教程.07(为ChoiceGroup添加图标友好...
10. **进阶话题**:除了基础内容,教程可能还会涉及KVM(Java Virtual Machine)的原理、JSR(Java Specification Requests)扩展以及与其他平台的互操作性等更深入的话题。 总的来说,这个J2ME中文教程解密版是一...
- "J2ME游戏开发PDF教程":这个教程很可能是详细的指南,涵盖了从基础到进阶的J2ME游戏开发技术,包括实例和最佳实践。 通过深入学习和实践,开发者可以掌握J2ME游戏开发的技巧,创造出吸引人的移动游戏,尽管现代...
本资源包含了大量的J2ME源代码和实例,这些例子旨在帮助开发者从基础到进阶全面理解J2ME编程。下面将详细阐述J2ME的关键概念、重要技术以及这些源代码可能涵盖的领域。 1. **J2ME架构**:J2ME的架构主要由配置...
描述中提到“对初学者很有帮助,是初学者对精通手机开发垫下了很好的基础”,这暗示了这个代码库可能包含了从简单到复杂的多个示例,逐步引导学习者从基础到进阶,掌握J2ME游戏开发的关键技能。 J2ME游戏开发涉及的...
总之,这份J2ME学习资料打包下载涵盖了从基础到进阶的全方位内容,无论是对J2ME感兴趣的新手还是有经验的开发者,都能从中获益。通过深入学习和实践,可以掌握开发跨平台移动应用的技能,尤其是针对老一代移动设备的...
总的来说,《J2ME网络精灵原理设计》是一份全面的教程,涵盖了从入门到进阶的多个层面,旨在帮助开发者掌握J2ME平台的网络编程和游戏开发能力。通过深入学习和实践,开发者能够创造出富有创新性和趣味性的移动应用和...
**J2ME开发详解** Java 2 Micro Edition(J2ME)是Java平台的一个子集,主要用于嵌入式系统和移动设备,如手机、PDA、智能家电等。...这本书无疑是J2ME初学者的宝贵资源,帮助他们从零开始,逐步进阶。
**J2ME手机开发视频入门教程...这将是你迈向移动开发世界的第一步,为后续的进阶学习和实际项目开发打下坚实基础。记住,实践是检验真理的唯一标准,多动手编写代码,不断尝试和改进,你会在J2ME开发中变得越来越熟练。
进阶学习 随着技能的提升,你可以学习更复杂的J2ME特性,如网络通信、数据存储、多媒体支持等。同时,NetBeans还支持插件扩展,你可以安装额外的插件来增强对特定设备或服务的支持。 总结,使用NetBeans开发J2ME...
总的来说,J2ME教程涵盖了从基础到进阶的各个层面,无论你是想了解J2ME的基本概念,还是深入学习开发技巧,这个教程都将提供有价值的指导。通过学习这些章节,你将能够构建自己的J2ME应用程序,并为在各种嵌入式设备...
**四、进阶配置与优化** 1. **设备兼容性**: 针对不同的设备特性,可能需要进行设备特定的配置,如屏幕尺寸、内存大小等。 2. **代码优化**: 由于J2ME应用运行在资源有限的设备上,优化代码以减少内存占用和提高...
J2ME教程是学习这一技术的基础,尤其对初学者而言,它提供了从入门到进阶的全面指导。 本教程“J2ME慢慢学教程”可能包含以下关键知识点: 1. **J2ME架构**:J2ME由配置(Configurations)和 profiles(配置文件)...
#### J2ME手机开发编程菜鸟进阶视频教程 - **专题地址**:[http://down.51cto.com/zt/114](http://down.51cto.com/zt/114) - **下载量**:650次 - **好评率**:96.00% **知识点概述**: - 该系列教程针对没有或者很...
- **进阶案例**:如开发一个带有基本游戏逻辑的游戏应用,或一个包含多媒体播放功能的应用。 #### 六、J2ME开发常见问题及解决方案 - **内存管理**:由于资源受限,合理管理内存是非常重要的。了解如何优化代码以...
通过《J2ME RPG边学边做》和《J2ME+RPG边学边做》这两份资料,你将逐步学习并实践这些知识点,从基础到进阶,逐步掌握 J2ME 上的 RPG 游戏开发技巧。对于初学者而言,理论学习与实践相结合是最好的学习方式,不断...
《程序天下-J2ME手机游戏开发详解》是一本专注于J2ME(Java 2 Micro Edition)平台上的手机游戏开发的专业书籍。J2ME是Java技术的一个...这本书的源码实例涵盖了这些核心概念,是学习和进阶J2ME游戏开发的宝贵资源。
总的来说,这个教程集合为你提供了一个全面的学习路径,从理论到实践,从基础到进阶,帮助你理解和掌握J2ME平台上的手机游戏开发。通过系统学习和动手实践,你将具备开发自己独特手机游戏的能力。