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许可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值