J2ME中文教程 9 MIDP 2 Push技术

来源:J2ME开发网 作者:mingjava 2007-11-23 出处:pcdog.com

.net  j2me  java  安全  网络连接  

              第9章            MIDP 2.0 Push 技术

9.1    Push技术概述

9.1.1     Push技术的分类

9.1.2     PushRegistry应用编程接口

9.2    静态注册与基于inbound网络连接的Push

9.2.1     注册

9.2.2     监听与启动

9.2.3     处理数据

9.3    动态注册与基于计时器的Push

9.4    使用Push应注意的问题

9.4.1     安全性问题

9.4.2     Push程序需注意的问题

 


 

9.1    Push技术概述

Push技术是一种通过异步方式将信息传送给设备并自动启动MIDlet程序的机制。通常我们进行网络连接的时候,是客户端主动去连接服务器,服务器处理请求并返回给客户端响应,这是同步处理机制。而Push技术不同,它不需要应用程序通过“拉”的方式通过网络取得数据,应用程序需要的数据会被主动“推”向设备。当设备接收到信息的时候,相关的MIDlet会被激活并开始运行,处理发送过来的数据。一般来说用户是不需要参与这个过程的。Push技术使得MIDlet同设备更加紧密地集成了起来,使得MIDlet程序在设备上的启动更加的平滑自然。这显然让MIDlet应用更具竞争力。

 

值得注意的是,Push是MIDP2.0的一个可选项。换句话说设备可以支持、不支持、或者部分的支持Push技术。

9.1.1   Push技术的分类

我们知道Application Management Software(AMS)是负责MIDlet的生命周期管理的,包括运行、暂停和销毁等。Push Registry是AMS的一个重要的组件,是AMS的一部分,它提供了Push的应用编程接口并跟踪push注册事件。在MIDP2.0中,Push机制可以通过如下两种方式激活MIDlet:

 

1)通过inbound网络连接(就是基于接入的连接的通知)

2)通过基于计时器的时钟(又称基于警告的通知)

 

下图是说明了MIDlet激活与生命周期的联系,供读者参考:

J2ME中文教程 9 MIDP 2 Push技术(图一)

图一:MIDlet激活方式与生命周期关系图

9.1.2   PushRegistry应用编程接口

首先我们介绍一下PushRegistry应用编程接口,PushRegistry是通用连接框架(Generic Connection Framework)中的一个类,它提供了所有和push相关的方法。我们这里只是简单列出了主要的方法,读者可以参考MIDP 2.0 的API文档得到更多信息。

 

方法总结

static String

getFilter(String connection)
       取得指定连接的过滤器

static String

getMIDlet(String connection)
       取得指定连接的注册MIDlet

static String[]

listConnections(boolean available)
       返回当前MIDlet套件中注册的连接列表

static long

registerAlarm(String midlet, long time)
       注册一个计时器来启动参数指定的应用程序

static void

registerConnection(String connection, String midlet, String filter)
       在应用程序管理软件中注册一个动态连接

static boolean

unregisterConnection(String connection)
       删除一个动态连接注册

      

通过使用PushRegistry我们可以把一个MIDlet注册到Push事件中并可以取得push相关的信息。

在MIDP2.0中,Push的处理是由AMS和MIDlet共同负责的,这样有利于简化AMS的实现,同时也可以避免把信息push到设备的方式和格式限制的过于严格。下面我们了解一下Push处理的过程,首先假设一个MIDlet已经被注册到push事件中:

1)首先,当MIDlet没有被激活的时候,AMS负责监视某个MIDlet的注册事件,一旦注册事件发生的时候,AMS会激活相关的MIDlet来进行下一步的处理。

2)当MIDlet正在运行的时候,MIDlet自己要负责所有的push事件的处理。主要是inbound网络连接和时钟事件。

9.2    静态注册与基于inbound网络连接的Push

下面我们将采用讲解和实例结合的方式来说明如何使用Push机制开发J2ME应用程序,

 

我们将使用SUN提供的Wireless Toolkit(WTK)做为运行环境。

 

在Push注册中有两种方式:静态注册和动态注册,静态注册是在MIDlet套件安装的时候完成的。你需要通过在MIDlet套件的jad文件中指定MIDlet-push字段的信息。并且当我们想测试应用程序的时候,不能只是简单的选择RUN,而必须要使用WTK提供的RUN via OTA功能把MIDlet套件通过AMS安装好,然后测试Push功能。

 

静态注册需要我们在jad文件或者manifest文件中提供MIDlet-push字段的内容,每个push注册实体需要提供如下的内容:

MIDlet-Push-<n>: <ConnectionURL>, <MIDletClassName>, <AllowedSender>

 

l         MIDlet-Push-<n>是push注册的属性名称,一个MIDlet套件可以有多个Push注册属性。

l         ConnectionURL是在Connector.open()中使用的连接字符串

l         MIDletClassName是在Push Registry中进行注册的MIDlet名称,一定要包括包名,例如com.j2medev.push.PushMIDlet。MIDletClassName一定要是在jad文件中记录的。

l         AllowedSender是用来说明过滤器的,可以对激活MIDlet的来源进行限制。我们可以直接指定ip地址,如192.16.8.0.12。也可以使用通配符“*”和“?”,其中“*”表示任意地址都可以访问,而“?”代表一个单独的字符串。如192.168.0.?

 

下面给出一个静态注册的基于inbound连接的Push实例。我们编写一个简单的MIDlet应用程序,并在安装过程中完成静态注册。然后我们起一个socket连接来激活这个MIDlet。整个过程分为注册、监听、运行、处理数据四部分。

9.2.1   注册

使用WTK新建项目命名为push,并指定MIDlet为com.j2medev.push.PushMIDlet。

J2ME中文教程 9 MIDP 2 Push技术(图二)

 

读者可以使用喜欢的文本编辑器编写一个简单的MIDlet,这里给出的参考代码如下:

package com.j2medev.push;

 

import javax.microedition.midlet.MIDlet;

import javax.microedition.midlet.MIDletStateChangeException;

import javax.microedition.lcdui.*;

 

public class PushMIDlet extends MIDlet {

 

   private Display display;

 

   protected void startApp() throws MIDletStateChangeException {

      

       display = Display.getDisplay(this);

       display.setCurrent(new Form("Push"));

   }

 

   protected void pauseApp() {

   }

 

   protected void destroyApp(boolean arg0) throws MIDletStateChangeException {

   }

}

 

通过WTK提供的设置功能编辑Jad文件,把注册信息写入MIDlet-Push字段。J2ME中文教程 9 MIDP 2 Push技术(图三)

 

这里提供的Connection URL = socket://:5001,Class=com.j2medev.push.PushMIDlet,Allowed Sender = *。编辑后的jad文件如下:

MIDlet-1: push, push.png, com.j2medev.push.PushMIDlet

MIDlet-Jar-Size: 1329

MIDlet-Jar-URL: push.jar

MIDlet-Name: push

MIDlet-Permissions: javax.microedition.io.PushRegistry

MIDlet-Push-1: socket://:5001, com.j2medev.push.PushMIDlet, *

MIDlet-Vendor: Unknown

MIDlet-Version: 1.0

MicroEdition-Configuration: CLDC-1.0

MicroEdition-Profile: MIDP-2.0

 

编译项目,正确无误后使用WTK提供的打包功能生成jar文件。这一步我们最重要的是使用wtk提供的RUN via OTA功能把MIDlet安装,这样才可以在安装的时候注册静态连接。从Ktoolbar选择Project->Run via OTA。

 

J2ME中文教程 9 MIDP 2 Push技术(图四) J2ME中文教程 9 MIDP 2 Push技术(图五)

 

这里我们不会详细介绍安装的步骤,当安装结束后WTK会弹出对话框询问push可能会接收网络连接的数据,这是收费操作。读者选择确定就可以了。

9.2.2   监听与启动

现在我们已经完成了静态注册的准备,下面我编写一个简单的Sender程序,目的是向设备建立socket连接,来产生inbound连接。代码如下:

package com.j2medev.socket;

 

import java.net.Socket;

 

public class Sender {

 

   public static void main(String[] args) throws Exception {

       new Socket("127.0.0.1",5001);

   }

}

 

编译并运行Sender程序,我们将可以看到PushMIDlet被激活的时候弹出的对话框,选择ok,AMS将会激活PushMIDlet。

J2ME中文教程 9 MIDP 2 Push技术(图六) J2ME中文教程 9 MIDP 2 Push技术(图七)

 

在MIDP2.0规范中并没有规定设备必须要支持什么协议,inbound连接的协议是具体设备实现相关的。即使设备支持一种连接协议,也不一定支持将他用于Push启动,请读者参考各个厂商的API取得相关信息。一般可以使用如下几种形式:1)基于消息的短消息服务 2)基于流的TCP sockets 3)基于包的数据报。

9.2.3   处理数据

你可能意识到了,我们的程序并没有处理那个激活MIDlet的连接。在一个真正的应用中,被唤醒的MIDlet应该在启动过程中判断自己是被用户打开的还是被利用push技术唤醒的。如果是被唤醒的,应用程序应该紧接着打开这个连接,处理数据。下面的代码示范了如何判断是否被唤醒:

 

String connections[]=PushRegistry.listConnections(true);//传入true表示仅仅取得接入的连接

for(int i=0; i< connections.length;i++) {

   //利用这个连接字符串打开连接处理

}

9.3    动态注册与基于计时器的Push

动态注册是指通过使用PushRegistry应用编程接口在运行时进行注册。基于时钟和基于inbound连接的两种方式都可以使用动态注册,读者应该知道使用基于时钟的push方式只能通过动态注册。

 

基于时钟的动态注册比较简单,我们只是简单的调用PushRegistry的静态方法registerAlarm(String MIDlet,long time),这样当指定的时间到达的时候,AMS就会唤醒参数中指定的MIDlet。每个MIDlet只有一个基于计时器的注册,重复调用registerAlarm会覆盖上次的结果。下面我们给出一种基于时钟的Push动态注册的实例,我们的MIDlet会在程序结束后的10秒钟后自动启动。

 

依然使用前面我们新建的push项目,我们只是需要添加另外一个MIDlet命名为PushMIDlet2。代码如下:

package com.j2medev.push;

 

import java.util.Date;

 

import javax.microedition.midlet.MIDlet;

import javax.microedition.midlet.MIDletStateChangeException;

import javax.microedition.lcdui.*;

import javax.microedition.io.*;

 

public class PushMIDlet2 extends MIDlet {

 

   private Display display;

 

   protected void startApp() throws MIDletStateChangeException {

       display = Display.getDisplay(this);

       Form form = new Form("Push");

       form.append("This is a push example");

       display.setCurrent(form);

 

   }

  

   protected void pauseApp() {

      

   }

 

   protected void destroyApp(boolean arg0) throws MIDletStateChangeException {

      

       scheduleMIDlet(10000);

       display = null;

 

   }

  

   private void scheduleMIDlet(long delt)

   {

       try

       {

           Date now = new Date();

           PushRegistry.registerAlarm(this.getClass().getName(),now.getTime()+delt);

       }

       catch(Exception e)

       {

           e.printStackTrace();   

       }

   }

}

 

jad文件内容如下:

MIDlet-1: push, push.png, com.j2medev.push.PushMIDlet

MIDlet-2: push2, , com.j2medev.push.PushMIDlet2

MIDlet-Jar-Size: 2222

MIDlet-Jar-URL: push.jar

MIDlet-Name: push

MIDlet-Permissions: javax.microedition.io.PushRegistry

MIDlet-Push-1: socket://:5001, com.j2medev.push.PushMIDlet, *

MIDlet-Vendor: Unknown

MIDlet-Version: 1.0

MicroEdition-Configuration: CLDC-1.0

MicroEdition-Profile: MIDP-2.0

重新编译项目、打包并通过RUN via OTA安装新的MIDlet套件。运行push2,这是一个很简单的应用程序。关闭它后系统会提示你是不是允许MIDlet接受自动信息,选择确定即可。10秒后push2会自动启动,表明我们完成了基于时钟方式的动态注册。

 

9.4    使用Push应注意的问题

9.4.1   安全性问题

使用Push增加了用户对安全性的担心。所以对Push的应用是在MIDP2.0的安全框架之下进行的。如果要使用Push需要申请javax.microedition.io.PushRegistry许可。

9.4.2   Push程序需注意的问题

l         利用Push启动的程序应该明确的和用户交互。一个被Push唤醒并运行在后台的程序会让用户产生很多疑惑。

l         如果处理inbound连接,应该在一个独立现程中进行。

l         正确使用Push技术,不要利用基于计时器的Push反复启动程序来检测网络更新,应该使用基于inbound连接的Push

由于篇幅有限,MIDP 2.0 Push讲解就介绍到这里,动态inbound的注册比较复杂,请参考www.j2medev.com的文章。

 

 


更多内容请看PCdog.com--Fireworks教程  j2me教程  PPT教程专题
上一篇:J2ME中文教程 7 开发无线网络应用程序
下一篇:J2ME中文教程 10 MIDlet的开发流程与部署