作者:孙东风 2010-01-07(转载务必注明出处)
笔者最近需要移植一个J2ME的项目到Android平台上,所以抽空研究了一下Android平台的接口规范。
Android平台除了在一些接口上采用了和J2ME不一样的名称之外,基本的接口内容还是一样的,那么移植J2ME到Android平台最方便的方法就是利用Android平台的接口重写J2ME的接口,本着这个思路笔者写了一个Wrap包,利用这个Wrap包,基本上J2ME程序不用修改,只需要重新导入一下重写后的Graphics、Image等类,就可以无缝的运行在Android平台上,所以笔者题目中所说的“两个小时精通Android”的前提是先精通J2ME。
既然要重写J2ME下的这些接口,那么就要先了解Android和J2ME平台到底有哪些不同,然后重写这部分不同的接口即可。
Ø Font类
Android平台里不再提供J2ME下面的Font类,而是以Typeface代替,这为读者提供了更多的选择空间,因为Typeface是可以自定义的,但是为了无缝移植J2ME程序到Android平台上,笔者封装了以个类似于J2ME平台下的Font类,如下:
import android.graphics.Typeface;
public class Font {
public static final int STYLE_PLAIN = 0;
public static final int STYLE_BOLD = 1;
public static final int STYLE_ITALIC = 2;
public static final int STYLE_UNDERLINED = 4;
public static final int SIZE_SMALL = 22;
public static final int SIZE_MEDIUM = 31;
public static final int SIZE_LARGE = 40;
public static final int FACE_SYSTEM = 0;
private int face;
private int style;
private int size;
private int baseline;
private int width;
private int height;
public void setWidth(int width)
{
this.width = size;
}
public void setHeight(int height)
{
this.height = height;
}
public int getWidth()
{
return size;
}
public int getHeight()
{
return height;
}
private Typeface iTypeface = Typeface.DEFAULT;
public Typeface getTypeface()
{
return iTypeface;
}
public void setSize(int fontSize)
{
size = fontSize;
}
public int getSize()
{
return size;
}
private static final Font DEFAULT_FONT = new Font(null,22);
public Font(Typeface aTypeface,int aSize)
{
if(iTypeface != null)
iTypeface = aTypeface;
size = aSize;
}
public static Font getFont(int fontSepcifier)
{
switch(fontSepcifier)
{
case SIZE_SMALL:
return new Font(null,22);
case SIZE_MEDIUM:
return new Font(null,31);
case SIZE_LARGE:
return new Font(null,40);
}
return DEFAULT_FONT;
}
public static Font getDefaultFont()
{
return DEFAULT_FONT;
}
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;
}
public int charWidth(char arg)
{
return size;
}
public int stringWidth(String arg)
{
return size*(arg.length());
}
}
Ø Graphics类
Android平台下不再提供Graphics类进行“视图上下文”的控制,而是以Canvas、Paint联合进行控制,笔者封装的Graphics类如下:
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
public class Graphics {
public static final int HCENTER = 1;
public static final int VCENTER = 2;
public static final int LEFT = 4;
public static final int RIGHT = 8;
public static final int TOP = 16;
public static final int BOTTOM = 32;
public static final int BASELINE = 64;
public static final int SOLID = 0;
public static final int DOTTED = 1;
private Bitmap bitmap;
private Canvas canvas;
private Paint paint;
private Rect clip;
private Font font;
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();
}
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);
}
}
public void fillRoundRect(int x,int y,int width,int height,int arcWidth,int arcHeight)
{
paint.setStyle(Style.FILL);
canvas.drawRoundRect(new RectF(x,y,x+width,y+height), arcWidth, arcHeight, paint);
}
public void drawRoundRect(int x,int y,int width,int height,int arcWidth,int arcHeight)
{
paint.setStyle(Style.STROKE);
canvas.drawRoundRect(new RectF(x,y,x+width,y+height), arcWidth, arcHeight, paint);
}
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);
}
public Font getFont()
{
return font;
}
public void setAntiAlias(boolean flag) {
paint.setAntiAlias(flag);
}
public void setAlphaValue(int alpha) {
paint.setAlpha(alpha);
}
public void setAlpha(float alpha) {
setAlphaValue((int) (255 * alpha));
}
public void translate(int x,int y)
{
canvas.translate(x,y);
}
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 drawImage(Image img, int x, int y) {
canvas.drawBitmap(img.getBitmap(), x, y, paint);
}
public void drawImage(Image img, int x, int y,int align) {
setAlign(align);
drawImage(img, x, y);
}
public void drawLine(int x1, int y1, int x2, int y2) {
if (x1 > x2) {
x1++;
} else {
x2++;
}
if (y1 > y2) {
y1++;
} else {
y2++;
}
canvas.drawLine(x1, y1, x2, y2, paint);
}
public void drawRect(int x, int y, int width, int height) {
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(x, y, x + width, y + height, paint);
}
public void drawString(String str, int x, int y) {
canvas.drawText(str, x, y, paint);
}
public void drawString(String str, int x, int y,int align) {
setAlign(align);
canvas.drawText(str, x, y, paint);
}
public void drawClear() {
paint.setColor(Color.BLACK);
canvas.drawColor(Color.BLACK);
}
public void fillRect(int x, int y, int width, int height) {
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(x, y, x + width, y + height, paint);
}
public int getClipHeight() {
return clip.bottom - clip.top;
}
public int getClipWidth() {
return clip.right - clip.left;
}
public int getClipX() {
return clip.left;
}
public int getClipY() {
return clip.top;
}
public int getColor() {
return paint.getColor();
}
public void dispose() {
paint = null;
canvas = null;
}
public void clearRect(int x, int y, int width, int height) {
canvas.clipRect(x, y, x + width, y + height);
canvas.drawARGB(0xff, 0xff, 0xff, 0xff);
}
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}
if (x + width > bitmap.getWidth()) {
width = bitmap.getWidth() - x;
}
if (y + height > bitmap.getHeight()) {
height = bitmap.getHeight() - y;
}
Bitmap copy = Bitmap.createBitmap(bitmap, x, y, width, height);
canvas.drawBitmap(copy, x + dx, y + dy, null);
}
public void clipRect(int x, int y, int width, int height) {
canvas.clipRect(x, y, x + width, y + height);
clip = canvas.getClipBounds();
}
public void setClip(int x, int y, int width, int height) {
if (x == clip.left && x + width == clip.right && y == clip.top
&& y + height == clip.bottom) {
return;
}
if (x < clip.left || x + width > clip.right || y < clip.top
|| y + height > clip.bottom) {
canvas.restore();
canvas.save(Canvas.CLIP_SAVE_FLAG);
}
clip.left = x;
clip.top = y;
clip.right = x + width;
clip.bottom = y + height;
canvas.clipRect(clip);
}
public void drawOval(int x, int y, int width, int height) {
paint.setStyle(Paint.Style.STROKE);
canvas.drawOval(new RectF(x, y, x + width, y + height), paint);
}
public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) {
canvas.drawLine(xpoints[npoints - 1], ypoints[npoints - 1], xpoints[0],
ypoints[0], paint);
for (int i = 0; i < npoints - 1; i++) {
canvas.drawLine(xpoints[i], ypoints[i], xpoints[i + 1],
ypoints[i + 1], paint);
}
}
public Canvas getGraphics() {
return canvas;
}
public Paint getPaint() {
return paint;
}
public Rect getClip() {
return clip;
}
public Bitmap getBitmap() {
return bitmap;
}
}
Ø Connector类
Android平台下不再提供这个静态接口类,而是提供HttpURLConnection以及URL进行网络通讯,这个类的封装如下:
package org.loon.framework.android.game;
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();