`
mmdev
  • 浏览: 12955012 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

J2ME进阶

 
阅读更多

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手机开发编程菜鸟进阶视频教程

    教程名称:J2ME手机开发编程菜鸟进阶视频教程课程目录:【】J2ME入门视频教程.05(TextField使用和事件【】J2ME入门视频教程.06(ChoiceGroup使用和获取选项值)【】J2ME入门视频教程.07(为ChoiceGroup添加图标友好...

    坦克J2ME游戏khk'

    本书分为4篇:起步篇、基础篇、进阶篇和实战篇,循序渐进地讲解了如何使用J2ME开发无线应用。. 本书详细讲解了J2ME的图形用户界面、游戏线程、记录存储、通用联网架构等基础知识,还在以往MIDP1.0的基础上增补了2.0...

    《J2ME手机游戏开发技术详解》随书光盘

    本书分为4篇:起步篇、基础篇、进阶篇和实战篇,此资源为该书中的实例源码光盘

    手机游戏,五子棋,J2ME

    手机游戏、五子棋、J2ME编程,程序短小,是学习、进阶人好代码,算法和结构都不难让人理解、、、

    《j2me手机游戏开发技术详解》源代码

    本书分为4篇:起步篇、基础篇、进阶篇和实战篇,循序渐进地讲解了如何使用J2ME开发无线应用。

    基于JAVA的J2ME的手机游戏开发(论文+源代码).zip

    项目资源】:基于JAVA的J2ME的手机游戏开发(论文+源代码) 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。

    JAVA基于J2ME的手机游戏开发(论文+源代码).rar

    【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或...

    基于java的基于java的J2ME的手机游戏开发(论文+源代码).rar

    【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或...

    java手机PDA程序设计入门

    第01章 J2ME概论 第02章 J2ME程序的撰写 第03章 Personal Java概论 第04章 MIDP程序设计基础 第05章 MIDP程序设计进阶 第10章 LCDUI——简介 目录未完,详情请下载文档。

    Google Android SDK开发范例大全 源码

    余志龙,来自于手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及J2EE、JSP、Servlet、JavaBeans、PHP、C#等程序语言,熟悉面向对象技术与Eclipse...

    Java虚拟机规范

    java进阶必读刊物,虚拟机详解,程序优化和处理。

    老罗android开发视频教程全集百度网盘下载

    Android以Java为编程语言,使接口到功能,都有层出不穷的变化,其中Activity等同于J2ME的MIDlet,一个 Activity 类(class)负责创建视窗(window),一个活动中的Activity就是在 foreground(前景)模式,背景运行...

    Google Android SDK开发范例大全(第3版) 1/5

    余志龙、陈昱勋、郑名杰、陈小风,分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言...

    Google Android SDK开发范例大全(第3版) 4/5

    余志龙、陈昱勋、郑名杰、陈小风,分别来自手机制造业、电视媒体业、网络、电信产业、软件开发等领域,擅长嵌入式系统软件设计、J2ME游戏开发、Android开发,以及12EE、JSP、Servlet、Java Bean、PHP、C#等程序语言...

Global site tag (gtag.js) - Google Analytics