Embedded 版 (精华区)

发信人: snows (花自飘零水自流), 信区: Embedded
标  题: Wince编程经验14(ZZ)
发信站: 哈工大紫丁香 (2004年03月14日09:33:22 星期天), 站内信件

Java 平台相关代码接口 (Java Native Interface) 是一个标准编程接口,用于编写 J
ava 本地方法和将 Java 虚拟机嵌入本地应用程序中。其主要目标是要使本地方法库在
给定平台上的所有 Java 虚拟机实现中具有二进制兼容性。
JDK(Java Development Kit,Java 开发工具包)1.2 扩展了 Java 平台相关代码接口
 (JNI),将新功能融入 Java 平台中。这是根据获得许可方和用户的意见和建议进行更
改的。
JDK 1.2 仍然支持旧的本地方法接口 (NMI),旧的 NMI(Native Method Interface,本
地方法接口)原先是在 JDK 1.0 中实现的。旧的 NMI 并不包括在 Java 平台标准中,
即将出台的 Java HotSpotTM 虚拟机也不支持它。我们建议程序员将他们现有的 NMI 代
码移植到 JNI 上。
posted by Jiang 7/1/2003 10:39:58 下午
8.19.2003
Java on Windows CE 环境设定 - Sun PersonalAE篇(上)出处:pdaordie.com by Sog
Personal Java仿真器及环境设定
请注意本篇文章只适用「没有Jeode Runtime执行环境」的使用者。
环境设定
本章节会为各位介绍环境的相关设定与安装。首先各位看手中需要有一台WinCE 2.0以上
的操作系统的PDA(笔者在这要先跟各为说明一下,目前笔者手中的PDA为Compaq iPaq 
6360及HP Jornada 548,操作系统都是WinCE 3.0且CPU为Intel StrongARM及Hitachi的
SH3,所以并不能保证在其它环境上面执行,不过根据网页上面的说法应该是可以正常的
其它平台上面执行才是,目前已经确认新的HP的Jornada 720系列没有办法执行,需要作
细部的修改及设定,请参考Java On WinCE板上的文章)。
安装开发环境JDK1.1.8及PersonalJava
1-1 下载及安装JDK1.1.8
请先连接至http://java.sun.com,点选左边的Products & APIs进入新的页面,点选中
间的点选JavaTM 2 SDK, Standard Edition, 1.1.x JDK版本,其执行环境为Microsoft
 Windows(注意!!不要点选1.3及1.4Beta版本喔!!)及Download Documentation,下载
完成后,会出现jdk-1_1_8_008-win.exe及 jdk-1_1_8_003-doc.zip,请先执行jdk-1_1
_8_008-win.exe使用默认值,完成后就会在C磁盘多出一个jdk1.1.8的目录了,接着再将
jdk-1_1_8_003-doc.zip解压缩到jdk1.1.8的目录则会多出一个doc的目录,此目录为Ja
va的API手册,接下来我们要继续下载PersonalJava 发展环境。
1-2 下载PersonalJava 发展环境
1-2-1 下载PersonalJava Runtime Environment for Windows CE
完成了jdk的安装之后接下来我们就要开始安装PersonalJava的开发环境了,同安装jdk
1.3一样,请先连接至http://java.sun.com,点选左边的Products & APIs进入新的页面
如下图,再点选下面的Early Access Releases,然后用您的帐号登入,若没有帐号可以
**注册一个的,然后点选PersonalJavaTM Runtime Environment for Windows CE,接着
就点选您的PDA为哪一种CPU(若无法得知请询问厂商,不然后面就无法继续动作了),
MIPS (R4000 Compatible) / SH3 / SH4 / StrongARM 等下载完成之后,您会得到pjav
awince-1_1-beta1-XXX.zip(XXX为CPU规格如arm或是sh3),接着我们将他解压缩到一
个暂时存放的目录(如c:\temp或是c:\tmp如此类的目录)里面会有两个档案pjavawinc
e.XXX.CAB、Readme.Txt(XXX为CPU的规格),接着透过Window操作系统中的「我的计算
机」中的Mobile Device(若您正确的安装了Microsoft的Active Sync各位读者计算机种
的我的计算机内应该会有一个Mobile Device的目录),pjavawince.XXX.CAB档案放入W
inCE中的\My Pocket PC\ Temp目录里面,然后点选两下,就安装完成??。
Java on CE程序设计(中)
By SoG
您需要了解的URL(Uniform Resource Locator)
URL(Uniform Resource Locator)是一个网络资源的位置或是参考(reference)。下
面是一个URL的范例:
**由于系统限制,因此排版若有不当请见谅,本站将于近期改版修正**
一个URL的类别需要下面几个两个主要的参数: 协议的定义(如http或是ftp)等 资源
的名称(包含网址或是port) 关于URL的部分笔者只有为各位作简单的介绍,接着附上
个读取网页的范例,当然啦!!先玩玩看??!!然后再讨论一下吧。
//httptest.java
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
public class httptest extends Frame
{
private Label lb1 = new Label("URL");
private TextField tf1 = new TextField(10);
private TextArea ta1 = new TextArea();
private Button btn1 = new Button("Get");
Panel p1 = new Panel();
public httptest()
{
p1.add(lb1);
p1.add(tf1);
p1.add(btn1);
//sp1.add(ta1);
add(p1,BorderLayout.NORTH);
add(ta1,BorderLayout.CENTER);
btn1.addActionListener(new btn1ActionEvent());
setSize(240,320); //for iPAQ
setVisible(true);
}
public static void main(String args[])
{
new httptest();
}
class btn1ActionEvent implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String URLStr;
try
{
//开启一个新的URL对象
URL u = new URL(tf1.getText());
ta1.append("\t You hava entered:"+lb1.getText()+"\n");
ta1.append("\t URL info"+u.toString()+"\n");
InputStreamReader ir = new InputStreamReader(u.openStream());
BufferedReader bf = new BufferedReader(ir);
ta1.append("\t URL stream connection: Read file now...\n");
String aLine;
while((aLine = bf.readLine())!=null)
{
ta1.append(aLine + "\n");
}
bf.close();
ir.close();
}
catch(MalformedURLException mue)
{
//System.out.println("网址不正确");
}
catch(IOException ioe)
{
//System.out.println("Error "+ioe);
}
}
}
}
编译及执行程序
javac ?Cclasspath %pjeeclasspath%;. httptest.java(编译)
pjava ?Cclasspath %pjeeclasspath%;. httptest (执行)
接着输入个网址,记得要连上网络啊!!笔者是输入http://www.javatwo.net,接着会
跑出很多很多东西唷!!
图 在仿真器中的画面(1)
图 在仿真器中的画面(2)
相信大家都觉得很奇怪,为什么无法看看到如我们浏览器一般的美丽图样及文字呢?因
为我们必须要在为这些取得的字符串还有档案作剖析(parse)的动作,如读到了图形的
字节就需要使用使用绘图软件打开,读到音乐的字节就需要使用媒体播放工具来开启,
这是可一门相当大的学问也是相当的苦工唷。
分布式的应用程序
在为各位读着介绍下一个更炫更酷的RMI技术之前笔者先为各位介绍一些分布式应用程序
的观念,另外附上一个网络程序与数据库连接的范例架构如下图所示,我们将SocketSe
rver中间安置许多真实的程序逻辑,最后再透过JDBC连接到数据库,如此我们可以将数
据库的联机降至最低,至于Client端联机的处理则就需要靠各位撰写程序的技巧??!!
这是常常看到的多层式(N-tier)架构或是分布式的应用程序皆是以此技巧发展出来的
笔者所附上的范例程序是属于三层式架构(3-tier)。
图(三层式)的系统架构
Server端的应用程序
皆下来的程序满有趣而且也很实用的,希望各位读者会喜欢。下面附上的Server端中具
有连接数据库查询及提供Socket服务的Server,各位读者可以在PC端执行。
//netDBServer.java
import java.sql.*;
import java.net.*;
import java.io.*;
import java.util.*;
import org.hsql.util.*;
public class netDBServer
{
String clientMessage;
ServerSocket sSocket;
//宣告使用ServerSocket的类别
Socket csocket;
//取得Client联机封包的Socket,各为别想太多就是Client端的联机
public netDBServer()
{
try
{
sSocket = new ServerSocket(900,200);
//开启Port 900,并限定Client联机的数量为200,若开启正常则开始等待Client端的联机

while(true)
{
csocket=sSocket.accept();
Thread t=new MyThreadDB(csocket);
t.start();
}
}
catch(IOException ioe)
{
System.out.println("开启Server异常!!!");
}
}
public static void main(String[] args)
{
new netDBServer();
}
}
class MyThreadDB extends Thread
{
Socket conn;
String tempStr;
DataInputStream dis;
DataOutputStream dos;
int ikey;
String val;
static Connection con = null;
String sTestData[]= {
"create table Place (Code integer,Name varchar(255))",
"create index iCode on Place (Code)",
"delete from place",
"insert into Place values (4900,'Langenthal')",
"insert into Place values (8000,'Zurich')",
"insert into Place values (3000,'Berne')",
"insert into Place values (1200,'Geneva')",
"insert into Place values (6900,'Lugano')",
"create table Customer (Nr integer,Name varchar(255),Place integer)",
"create index iNr on Customer (Nr)",
"delete from Customer",
"insert into Customer values (1,'Meier',3000)",
"insert into Customer values (2,'Mueller',8000)",
"insert into Customer values (3,'Devaux',1200)",
"insert into Customer values (4,'Rossi',6900)",
"insert into Customer values (5,'Rickli',3000)",
"insert into Customer values (6,'Graf',3000)",
"insert into Customer values (7,'Mueller',4900)",
"insert into Customer values (8,'May',1200)",
"insert into Customer values (9,'Berger',8000)",
"insert into Customer values (10,'D''Ascoli',6900)",
"insert into Customer values (11,'Padruz',1200)",
"insert into Customer values (12,'Hug',4900)"
};
static boolean DBCheckInit;
//建构者
public MyThreadDB(Socket inSocket)
{
conn = inSocket;
}
public void run()
{
try{
System.out.println
("Server go connect from:"+conn.getInetAddress().getHostName());
dos = new DataOutputStream(conn.getOutputStream());
dos.writeUTF("输入查询的资料");
//get the request conntent
dis = new DataInputStream(conn.getInputStream());
tempStr = dis.readUTF();
//响应一下
try{
new org.hsql.jdbcDriver();
Class.forName("org.hsql.jdbcDriver").newInstance();
}catch (Exception e){System.out.println(e);}
try{
con = DriverManager.getConnection("jdbc:HypersonicSQL:test","sa","");
Statement select = con.createStatement();
ResultSet result = select.executeQuery("Select Code,Name FROM Place");
//初始化数据库
System.out.println("初始化数据库");
for(int i=0;i>sTestData.length;i++)
select.executeQuery(sTestData[i]);
ResultSet result =
select.executeQuery("Select Code,Name FROM Place Where Code ="+tempStr);
System.out.println("Got results:");
while(result.next()){
ikey = result.getInt(1);
if(result.wasNull()){ikey=-1;}
val = result.getString(2);
if(result.wasNull()){val=null;}
System.out.println("Code = "+ikey);
System.out.println("Name = "+val);
}
}catch(Exception e)
{
System.out.println(e);
}/*finally
{
if(con!=null){try{con.close();}
catch(Exception e){e.printStackTrace();}}
}*/
//dos.writeUTF("您查询的资料为"+tempStr+"系统正在为您查询中请稍后...");
dos.writeUTF("您查询的资料为"+val+"系统正在为您查询中请稍后...");
System.out.println("Server recivews data ="+tempStr);
conn.close();//断线
}
catch(IOException e)
{System.out.println(e);}
}
}
Client端的应用程序
Client端的应用程序笔者并没有作窗口程序的设计,只是提供一个雏形给大家使用。
//Client.java
import java.net.*;
import java.io.*;
public class Client
{
public Client()
{
try{
//请配合Server的IP修改
Socket csocket = new Socket("192.168.0.1",900);
DataInputStream dis = new DataInputStream(csocket.getInputStream());
String data = dis.readUTF();
System.out.println("Client get datafrom server = "+data);
//write response to server
DataOutputStream dos = new DataOutputStream(csocket.getOutputStream());
dos.writeUTF("3000");
data = "";
data = dis.readUTF();
System.out.println("Client get datafrom server = "+data);
data = dis.readUTF();
System.out.println("Client get datafrom server = "+data);
csocket.close();
}catch(IOException e)
{
System.out.println(e);
}
}
public static void main(String[] args)
{
new Client();
}
}
编译及执行
Server端
javac ?Cclasspath %pjeeclasspath%;hsql.jar netDBServer(编译)
pjava ?Cclasspath %pjeeclasspath%;hsql.jar netDBServer(执行)
注意
-classpath之后的套件位置请依照情况修改另外别忘记了唷~
Client端 javac ?Cclasspath %pjeeclasspath% Client.java (编译)
pjava ?Cclasspath %pjeeclasspath% Client (执行)
并且移到我们的PocketPC中执行
图 Server端激活之后收到Client讯息的画面
图 PDA中的画面
希望这个小架构能够经过各位的修改及调整之后给各位不管是对于研究或是事业上能够
帮上一点小小的忙,接着我们就准备进入RMI章节了唷~
Remote Method Invocation(RMI)
RMI,是Java所提供的分布式架构的机制,可以用来撰写成是和成是之间的通讯方法,当
然你也可以透过Socket来撰写分散的程序(如前一个段落我们所介绍的),但是在使用
这些函数需要做相当多繁琐的调整,另外再使用Socket通讯的时候,只能够传递资料,
但是是若使用RMI技术不仅可以传递资料也能够传递对象呢!!所以各位只要好好的发挥
您的想象力,想想您的程序架构就可以了!
RMI原理介绍
我们先看一下下面的联机是意图吧!!在分散室的架构中我们将程序分为Client及Serv
er两端,再使用RMI的机制的时候Client会透过Server的Stub(向是Server的分身)透过
RMI的一些运算找到Server的Skeleton,接着Client端就透过控制Server的分身就能够达
到使用Server的函示及资源了。
图 RMI联机示意图
RMI联机过程说明
如图所示,虽然使用起来RMI感觉是相当的容易的,但是其实他包含了下面几个重要的动
作,Client先透过Server的Stub联机的一个注册中心,接着注册中心将Stub和Server的
Skeleton联机,然后Client端就可以使用Server端的资源??。
图 RMI联机示意图
Java on CE程序设计(下)
By SoG
简单的联机程序范例
// CustWork.java 定义Server端提供服务的接口
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface CustWork extends Remote{
public String getSvrMsg() throws RemoteException;
}
// CustWorkImpl.java 这是Server端的服务
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Calendar;
import java.rmi.server.*;
public class CustWorkImpl implements CustWork{
public CustWorkImpl() throws RemoteException{
UnicastRemoteObject.exportObject(this);
}
public String getSvrMsg() throws RemoteException{
String threadName = Thread.currentThread().getName();
String curTime = Calendar.getInstance().getTime().toString();
System.out.println(threadName+" : Aclient connected at "+ curTime);
return (threadName + " :Message from Server at "+curTime);
}
}
// JSESocketFactory在程序中激活RMI的注册中心及Server服务
import java.rmi.registry.*;
import java.rmi.*;
import java.rmi.RMISecurityManager;
public class JSESocketFactory
{
public static void main(String[] args){
try {
//小技巧
Registry regObj = LocateRegistry.createRegistry(1099);
CustWorkImpl obj = new CustWorkImpl();
Naming.rebind("myServer", obj);
System.out.println
("myImpl created and bound in the registry to the name myServer");
}
catch (Exception e)
{
System.out.println("myImpl.main: an exception occurred:");
e.printStackTrace();
}
}
}
//RMIClient.java Client端的程序
//程序中有关IP的部分请填入Server的IP Address
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
public class RMIClient
{
static String servMsg ="";
public static void main(String[] args)
{
try{
if(System.getSecurityManager() == null)
System.setSecurityManager(new RMISecurityManager());
CustWork serRef =
(CustWork) Naming.lookup("rmi://192.168.0.1:1099/myServer");
servMsg = serRef.getSvrMsg();
System.out.println(servMsg);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
编译及执行程序
注意!!
此部分的编译方法为jdk1.1.8的编译方法,若想在计算机中当Server且和J2SE联机的话
,你需要设定C:\jdk1.3.1\jre\lib\security 中的 java.policy 一些联机权限的设定
,另外产生 stub 及 skeleton 的时候也需要使用rmic ?Cv1.1的参数,因为 Perosnal
 Java 是参照jdk.1.1.x的规格实作出来的。
编译程序Server端的Interface及Service
c:\jdk1.1.8\bin\javac ?Cclasspath %pjeeclasspath%;. CustWork.java(1)
c:\jdk1.1.8\bin\javac ?Cclasspath %pjeeclasspath%;. CustWorkImpl.java(2)
产生Stub及Skeleton
c:\jdk1.1.8\bin\rmic -classpath %pjeeclasspath%;. CustWorkImpl(3)
编译Server端程序
c:\jdk1.1.8\bin\javac -classpath %pjeeclasspath%;. JSESocketFactory.java(4)

编译Client端程序
c:\jdk1.1.8\bin\javac -classpath %pjeeclasspath%;. RMIClient.java(5)
执行程序
注意您需要开两个DOS窗口来执行这两只程序
激活RMI Server程序 pjava -classpath %pjeeclasspath%;. JSESocketFactory(1)
图 RMI Server激活画面
激活RMI Client程序
pjava -classpath %pjeeclasspath%;. RMIClient
图 RMI Client激活画面
另外将Client端移植到WinCE中千万别忘了把XXXX_Stub档案也一起移动过去喔。
结论
当网络技术,配合无线网络卡,或是其它的产品,相信会是相当有趣的事情喔

--
-
 ╭────────────────────────────╮
 │   风萧传瑟声,叶落根深处,青阶入野无归途,他乡不知顾   │
 │   泣下问和谁,叹者行已暮,寒眉傲骨今尚在,奈何入凡土   │
 ╰────────────────────────────╯
                                                                             

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.229.154]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:207.172毫秒