- Technical article
- 无缝移植J2ME程序到OPhone平台解决方案
无缝移植J2ME程序到OPhone平台解决方案
OPhone平台开发, 2010-03-01 17:34:50
Tags : 移植 Ophone平台 J2me
为什么需要移植J2ME程序

private static final Font DEFAULT_FONT = new Font(null,22);
public static Font getFont(int face,int style,int size)
{
switch(style)
{
case STYLE_PLAIN:
return new Font(Typeface.defaultFromStyle(Typeface.NORMAL),
size);
case STYLE_BOLD:
return new Font(Typeface.defaultFromStyle(Typeface.BOLD),
size);
case STYLE_ITALIC:
return new Font(Typeface.defaultFromStyle(Typeface.ITALIC),
size);
}
return DEFAULT_FONT;
}
笔者这里定义的默认字体DEFAULT_FONT大小为22像素,开发者可以根据屏幕大小和项目需要自定义三种风格字体的大小。除此之外,还需要定义Font类常用的接口,比如获取字符宽度以及获取字体高度等,代码如下:
public int charWidth(char arg)
{
return size;
}
public int stringWidth(String arg)
{
return size*(arg.length());
}
2:Graphics类
public Graphics(Bitmap bitmap) {
this.bitmap = bitmap;
this.canvas = new Canvas(bitmap);
this.canvas.clipRect(0, 0, bitmap.getWidth(), bitmap.getHeight());
this.canvas.save(Canvas.CLIP_SAVE_FLAG);
this.paint = new Paint();
this.clip = canvas.getClipBounds();
}
接下来就封装了一下J2ME平台下Graphics类的绘制操作,比如画线、画图、画字符串等操作,代码如下:
public void fillTriangle(int x1,int y1,int x2,int y2,int x3,int y3)
{
paint.setStyle(Style.FILL);
canvas.drawLine(x1, y1, x2, y2, paint);
canvas.drawLine(x2, y2, x3, y3, paint);
canvas.drawLine(x3, y3, x1, y1, paint);
}
public void setFont(Font font)
{
paint.setTypeface(font.getTypeface());
paint.setTextSize(font.getSize());
FontMetrics fontMetrics = paint.getFontMetrics();
float height = fontMetrics.bottom-fontMetrics.top;
font.setHeight((int)height);
}
public void fillArc(int x,int y,int width,int height,
int startAngle,int arcAngle)
{
paint.setStyle(Style.FILL);
canvas.drawArc(new RectF(x,y,width,height),
startAngle, arcAngle, true, paint);
}
public void drawArc(int x,int y,int width,int height,
int startAngle,int arcAngle)
{
paint.setStyle(Style.STROKE);
canvas.drawArc(new RectF(x,y,width,height),
startAngle, arcAngle, true, paint);
}
除此之外,还需要在Graphics类里封装J2ME下布局控制的代码,OPhone平台下利用Paint类进行布局控制,所以笔者在Graphics的构造函数里初始化了一个Paint对象,J2ME平台下常见的布局控制是文本对齐方式以及画刷填充格式等,封装如下:
public void setAlign(int align)
{
if(LEFT == align
||(Graphics.LEFT | Graphics.TOP) == align
||(Graphics.LEFT | Graphics.BOTTOM) == align)
{
paint.setTextAlign(Align.LEFT);
}else if(HCENTER == align
||(Graphics.HCENTER|Graphics.TOP) == align)
{
paint.setTextAlign(Align.CENTER);
}else if(RIGHT == align
||(Graphics.RIGHT | Graphics.TOP) == align)
{
paint.setTextAlign(Align.RIGHT);
}
}
另外,J2ME平台里设置Graphics绘图句柄的颜色有两种格式:setColor(int r,int g,int b)和setColor(0xRGB),而OPhone平台通过setColor(argb)设置画笔颜色或画刷颜色,代码封装如下:
public void setColor(int rgb) {
paint.setColor(rgb);
}
public void setColor(int r,int g,int b) {
int argb = (0xff000000)+(r<<16)+(g<<8)+b;
paint.setColor(argb);
}
public void setFont(Font font)
{
paint.setTypeface(font.getTypeface());
paint.setTextSize(font.getSize());
FontMetrics fontMetrics = paint.getFontMetrics();
float height = fontMetrics.bottom-fontMetrics.top;
font.setHeight((int)height);
}
public Canvas getGraphics() {
return canvas;
}
public Paint getPaint() {
return paint;
}
public Rect getClip() {
return clip;
}
public Bitmap getBitmap() {
return bitmap;
}
import java.net.HttpURLConnection;
import java.net.URL;
public class Connector {
public static final int READ = 1;
public static final int WRITE = 2;
public static final int READ_WRITE = 3;
private static String platform;
private static boolean j2me;
public static HttpConnection open(String name,int mode,
boolean timeouts)
throws java.io.IOException
{
URL url = new URL(name);
HttpURLConnection conn =
(HttpURLConnection) url.openConnection();
// Allow Inputs
conn.setDoInput(true);
// Allow Outputs
conn.setDoOutput(true);
conn.setConnectTimeout(100000);
HttpConnection co = new HttpConnection();
co.setConnEx(conn);
return co;
}
}
public void setRequestProperty(String field,String newValue)
throws java.io.IOException
{
connEx.setRequestProperty(field, newValue);
}
public String getHeaderField(String key)
{
int temp = connEx.getHeaderFieldInt(key, 1024);
return String.valueOf(temp);
}
但是OPhone平台下获取HTTP包长度的接口名称有所不同,在J2ME平台下是通过getLength()方法获取的,而OPhone平台下通过getContentLength()方法获取,这样命名似乎更加合理。
首先,需要在OPhone平台下定义J2ME平台GameCanvas类常用的键值码,这些键值码对应J2ME平台下常用的按键:
public class GameCanvas extends Screen {
public static final int UP = 1;
public static final int DOWN = 6;
public static final int LEFT = 2;
public static final int RIGHT = 5;
public static final int FIRE = 8;
public static final int GAME_A = 9;
public static final int GAME_B = 10;
public static final int GAME_C = 11;
public static final int GAME_D = 12;
public static final int KEY_NUM0 = 48;
public static final int KEY_NUM1 = 49;
public static final int KEY_NUM2 = 50;
public static final int KEY_NUM3 = 51;
public static final int KEY_NUM4 = 52;
public static final int KEY_NUM5 = 53;
public static final int KEY_NUM6 = 54;
public static final int KEY_NUM7 = 55;
public static final int KEY_NUM8 = 56;
public static final int KEY_NUM9 = 57;
public static final int KEY_STAR = 42;
public static final int KEY_POUND = 35;
}
当然,为了适配J2ME平台的按键以及触摸响应,笔者还定义了如下接口,在接收到相应的按键或者触摸消息时,会转发给相应的J2ME视图,代码如下:
protected abstract void keyRepeated(int keyCode); protected abstract void keyPressed(int keyCode); protected abstract void keyReleased(int keyCode); protected abstract void pointerPressed(int x, int y); protected abstract void pointerReleased(int x, int y) protected abstract void pointerDragged(int x, int y);
public int keyActual = 0;
public int keyAction = 0;
public void keyPreparse(int keyCode,KeyEvent e)
{
if(keyCode == KeyEvent.KEYCODE_0)
{
keyActual = GameCanvas.KEY_NUM0;
}else if(keyCode == KeyEvent.KEYCODE_1)
{
keyActual = GameCanvas.KEY_NUM1;
}else if(keyCode == KeyEvent.KEYCODE_2)
{
keyActual = GameCanvas.KEY_NUM2;
}else if(keyCode == KeyEvent.KEYCODE_3)
{
keyActual = GameCanvas.KEY_NUM3;
}else if(keyCode == KeyEvent.KEYCODE_4)
{
keyActual = GameCanvas.KEY_NUM4;
}else if(keyCode == KeyEvent.KEYCODE_5)
{
keyActual = GameCanvas.KEY_NUM5;
}else if(keyCode == KeyEvent.KEYCODE_6)
{
keyActual = GameCanvas.KEY_NUM6;
}else if(keyCode == KeyEvent.KEYCODE_7)
{
keyActual = GameCanvas.KEY_NUM7;
}else if(keyCode == KeyEvent.KEYCODE_8)
{
keyActual = GameCanvas.KEY_NUM8;
}else if(keyCode == KeyEvent.KEYCODE_9)
{
keyActual = GameCanvas.KEY_NUM9;
}else if(keyCode == KeyEvent.KEYCODE_POUND)
{
keyActual = GameCanvas.KEY_POUND;
}else if(keyCode == KeyEvent.KEYCODE_STAR)
{
keyActual = GameCanvas.KEY_STAR;
}else if(keyCode == KeyEvent.KEYCODE_DPAD_UP)
{
keyActual = GameCanvas.UP;
keyAction = GameCanvas.UP;
}else if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN)
{
keyActual = GameCanvas.DOWN;
keyAction = GameCanvas.DOWN;
}else if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT)
{
keyActual = GameCanvas.LEFT;
keyAction = GameCanvas.LEFT;
}else if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT)
{
keyActual = GameCanvas.RIGHT;
keyAction = GameCanvas.RIGHT;
}else if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER)
{
keyActual = GameCanvas.FIRE;
keyAction = GameCanvas.FIRE;
}
else if(keyCode == KeyEvent.KEYCODE_SOFT_LEFT)
{
keyActual = Globe.softKeyLeft;
}
else if(keyCode == KeyEvent.KEYCODE_SOFT_RIGHT)
{
keyActual = Globe.softKeyRight;
}
}
public boolean onTouchUp(MotionEvent e) {
if (isEvent) {
return isEvent;
}
pointerReleased((int)(e.getX()),(int)(e.getY()));
return isEvent;
}
public boolean onTouchDown(MotionEvent e) {
if (isEvent) {
return isEvent;
}
pointerPressed((int)(e.getX()),(int)(e.getY()));
return isEvent;
}
public boolean onKeyDown(int keyCode, KeyEvent e) {
keyPreparse(keyCode,e);
keyPressed(keyActual);
return true;
}
public boolean onKeyUp(int keyCode, KeyEvent e) {
keyPreparse(keyCode,e);
keyReleased(keyActual);
return true;
}
public int getKeyStates()
{
return keyActual;
}
public int getGameAction(int keyCode)
{
return keyAction;
}
public String read(String file) {
String data = "";
try {
FileInputStream stream =
System.getSystemHandler().getContext().openFileInput(file);
StringBuffer sb = new StringBuffer();
int c;
while ((c = stream.read()) != -1) {
sb.append((char) c);
}
stream.close();
data = sb.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
public void write(String file, byte[] msg) {
try {
FileOutputStream stream =
System.getSystemHandler().getContext().openFileOutput(file,
Context.MODE_WORLD_WRITEABLE);
stream.write(msg);
stream.flush();
stream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean put(String key, byte[] value) {
boolean bSaveOk = false;
this.searchKey = key;
byte[] data = null;
if (value == null) {
throw new NullPointerException();
}
ByteArrayOutputStream bout = null;
DataOutputStream dout = null;
try {
bout = new ByteArrayOutputStream();
dout = new DataOutputStream(bout);
dout.writeUTF(key);
dout.writeInt(value.length);
dout.write(value, 0, value.length);
data = bout.toByteArray();
write(dbName,data);
bSaveOk = true;
} catch (Exception e) {
bSaveOk = false;
e.printStackTrace();
}
closeDb();
return bSaveOk;
}
public byte[] getByteArray(String key) {
ByteArrayInputStream bin = null;
DataInputStream din = null;
byte[] data = null;
try {
String valueKey = read(dbName);
din = new DataInputStream(
new ByteArrayInputStream(valueKey.getBytes()));
while(din.available() > 0)
{
String getKey = din.readUTF();
int getLength = din.readInt();
data = new byte[getLength];
int bytesRead = 0;
while (bytesRead < data.length) {
int count = din.read(data, bytesRead, data.length
- bytesRead);
if (count == -1)
break;
bytesRead += count;
}
if(getKey.equals(key))
break;
}
din.close();
din = null;
} catch (Exception e) {
e.printStackTrace();
data = null;
}
closeDb();
return data;
}
}
关于作者
(声明:本网的新闻及文章版权均属OPhone SDN网站所有,如需转载请与我们编辑团队联系。任何媒体、网站或个人未经本网书面协议授权,不得进行任何形式的转载。已经取得本网协议授权的媒体、网站,在转载使用时请注明稿件来源。)