J2ME 进阶

来源:互联网 发布:手机淘宝假货怎么投诉 编辑:程序博客网 时间:2024/06/03 22:50
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许可
 
原创粉丝点击