📄 may01_ericg.txt
字号:
J 2 M E T E C H T I P S
TIPS, TECHNIQUES, AND SAMPLE CODE
WELCOME to the Java Developer Connection(sm) (JDC)
Java(tm) 2 Platform, Micro Edition (J2ME(tm))
Tech Tips, for May 29, 2001. This issue covers:
* The Connected Device Configuration and the Foundation
Profile
* Handling Multiple Simultaneous MIDP Alerts
The J2ME Tech Tips are written by Eric Giguere
(http://www.ericgiguere.com), an engineer at iAnywhere
Solutions, inc., and author of the book "Java 2 Micro
Edition: Professional Developer's Guide."
You can view this issue of the J2ME Tech Tips on the Web at
http://java.sun.com/jdc/J2METechTips/2001/tt0529.html
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
THE CONNECTED DEVICE CONFIGURATION AND THE FOUNDATION PROFILE
Much of what's been written about Java 2 Platform, Micro Edition
(J2ME) talks about the Connected Limited Device Configuration, or
CLDC for short. The CLDC defines an extremely small subset of
the Java Platform for very limited devices -- devices, like
cellular telephones, that do not have enough memory or enough
processing power to handle a full-blown Java implementation.
There is, however, another configuration available that is midway
between the CLDC and a full Java 2 Platform, Standard Edition
(J2SE(tm)) implementation: the Connected Device Profile, or CDC
for short.
The CDC defines a much less radical subset of J2SE. Unlike
the CLDC, which is aimed at devices with less (often much
less) than 512K bytes of total available memory, the CDC
requires devices to have at least 2 megabytes of total memory
available for Java. This can be a combination of read-only
and read-write memory. The Java virtual machine* (VM) and core
class libraries are likely to be stored in read-only or
flash memory.
The CDC really targets the next generation of wireless, handheld
consumer devices. These devices pack large amounts of memory and
faster processors into the same or smaller form factors than
today's most prevalent devices. The CDC can also be used for
larger consumer devices such as set-top boxes that deliver
content through televisions, that is, devices that don't need
a general purpose Java implementation such as J2SE.
The CDC is also a superset of the CLDC. All the classes of the
CLDC, including the new javax.microedition.io classes defined by
the Generic Connection Framework, are part of the CDC. This means
that CLDC-based applications can run unchanged in a CDC-based
environment. That's true provided that any required CLDC-based
profiles the applications use (such as the Mobile Information
Device Profile) are available on the device.
Perhaps the biggest difference between the CDC and the CLDC is
that the CDC includes the CVM virtual machine, a full
J2SE-compliant virtual machine. The CLDC made changes to the
virtual machine specification. It disallowed all floating-point
operations, changed the way classes are verified, and did not
support low-level standards such as the Java Native Interface
(JNI) or the Java Virtual Machine Debug Interface (JVMDI). By
comparison, all of the features of a full J2SE virtual machine
must be supported by the CVM virtual machine. The J2SE VM itself
is not a requirement of the CDC --- all the CDC requires is a VM
that implements the full set of VM features. Vendors can license
it and adapt it for their devices quickly. The CVM virtual
machine can even be used with real-time operating systems.
The CDC includes classes from the java.lang, java.util, java.net,
java.io, java.text and java.security packages. Not every class
from each package is supported. However those classes that are
supported behave identically to and have the same public
interfaces as those in J2SE; the one exception is that most
deprecated methods have been removed. No changes are usually
required to port existing J2SE code to the CDC.
Just as there are profiles for the CLDC, there are also profiles
being developed for the CDC. The first profile, the Foundation
Profile, was released at the same time as the CDC. Generally, the
two are meant to go hand-in-hand. The Foundation Profile extends
the CDC by adding most of the missing J2SE core libraries, except
for those related to creating user interfaces. These additions
include socket classes, the complete internationalization and
localization classes, and the full set of classes in the
java.lang and java.io packages. There are still gaps, for
example, the java.beans, java.rmi and java.sql packages are not
part of the CDC or the Foundation Profile.
As you might guess, the Foundation Profile is meant to serve as
a foundation for other profiles. The PersonalJava(tm) API is
being redefined as a Personal Profile that extends the Foundation
Profile. An RMI Profile, in the final stages of development, adds
RMI support to the Foundation Profile. Other profiles are sure to
be developed.
Reference implementations of the CDC and the Foundation Profile
are available for Linux and VxWorks platforms under the terms and
conditions of the Sun Community Source License (SCSL) agreement.
You can download them by following the links from the main CDC
page at http://java.sun.com/products/cdc.
Here's a CDC-Foundation Profile application that illustrates some
of the things described in this tip. In particular, the application
uses CDC java.net classes to create device connections (Socket and
ServerSocket). The application is comprised of two programs.
One program, PeerFinder, acts as a client; the other program,
PeerListener, acts as a server.
Here's the source code for PeerFinder:
import java.io.*;
import java.net.Socket;
import java.net.InetAddress;
import java.util.Vector;
public class PeerFinder {
static final int PORT_NUM = 4321;
static final int DATA_BUFFER_MAX = 256;
static final String PING_MSG = new String("ping");
static final String PONG_MSG = new String("pong");
static String command = System.getProperty("command");
static String portprop = System.getProperty("port");
static String hostname = System.getProperty("hostname");
static Socket socket;
static int port = PORT_NUM;
static BufferedOutputStream outputStream;
static BufferedInputStream inputStream;
public static void main(String args[]) {
byte[] dataBuffer = new byte[DATA_BUFFER_MAX];
String dataString = null;
// Set default port if not set by user
if ((portprop != null) && !portprop.equals("")) {
port = Integer.parseInt(portprop);
}
// Set default command if not set by user
if ((command == null) || (command.equals(""))) {
command = PING_MSG;
}
// Set default security manager
try {
if (System.getSecurityManager()==null) {
System.setSecurityManager(new SecurityManager());
}
} catch (Exception e) {
e.printStackTrace();
}
// Open a socket to the given peer listener host port
try {
if ((hostname != null) && hostname.equals("")) {
System.out.println("Opening to local
host port # "+port);
socket = new Socket(
InetAddress.getLocalHost(), port);
} else {
System.out.println("Opening peer listener host "+
hostname+
" port # "+port);
socket = new Socket(hostname, port);
}
} catch (Exception e) {
e.printStackTrace();
}
try {
// Get the input and output streams of socket to peer
outputStream = new BufferedOutputStream(
socket.getOutputStream());
inputStream = new BufferedInputStream(
socket.getInputStream() );
// Check to send a ping
if (command.equals(PING_MSG)) {
sendPing();
}
// Listen for peer listener reply
System.out.println("Listening for return message...");
// Reading from peer listener
while (inputStream.read(dataBuffer, 0, DATA_BUFFER_MAX)
!= -1) {
dataString = new String(dataBuffer);
// Print received message
System.out.println("Received peer listener reply:
"+ dataString);
// Check if pong was received
if (dataString.indexOf(PONG_MSG) != -1) {
break;
}
}
// Cleanup and close
inputStream.close();
outputStream.close();
socket.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
static void sendPing() {
byte[] dataBuffer = PING_MSG.getBytes();
try {
outputStream.write(dataBuffer, 0, dataBuffer.length);
outputStream.flush();
System.out.println("Sent: "+PING_MSG);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here's the source code for PeerListener:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class PeerListener {
static final int PORT_NUM = 4321;
static final int DATA_BUFFER_MAX = 256;
static final String PING_MSG = new String("ping");
static final String PONG_MSG = new String("pong");
static String command = System.getProperty("command");
static String portprop = System.getProperty("port");
static ServerSocket peerSocket;
static Socket socket;
static int port = PORT_NUM;
static BufferedOutputStream outputStream;
static BufferedInputStream inputStream;
public static void main(String args[]) {
byte[] dataBuffer = new byte[DATA_BUFFER_MAX];
String dataString = null;
// Set default property if not set by user
if ((portprop != null) && !portprop.equals("")) {
port = Integer.parseInt(portprop);
}
// Set default security manager
try {
if (System.getSecurityManager()==null) {
System.setSecurityManager(new SecurityManager());
}
} catch (Exception e) {
e.printStackTrace();
}
// Open a peer socket to the given port
try {
peerSocket = new ServerSocket(port);
} catch (Exception e) {
e.printStackTrace();
}
// Start listening for peers
System.out.println("Listening for peer finder
connection...");
while (true) {
try {
// Block here for peer finder requests to connect
socket = peerSocket.accept();
// Get the input and output streams from peer socket
outputStream = new
BufferedOutputStream(socket.getOutputStream());
inputStream = new
BufferedInputStream(socket.getInputStream() );
// Read loop
while (inputStream.read(dataBuffer, 0,
DATA_BUFFER_MAX-1)
!= -1) {
dataString = new String(dataBuffer);
System.out.println("Received: "+ dataString+"");
// Check if this is a ping request message
if ((dataString.indexOf(PING_MSG)) != -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -