分享

JavaME学习笔记

 aaie_ 2012-07-15

1 体系介绍和环境配置 ... 1

1.1 J2ME 分为两类: ... 1

1.2 J2ME 体系架构 ( 底层— > 高层 ) 2

1.3 环境搭建 ... 2

2 高级界面开发 ... 2

2.1 MIDlet(Mobile Information Devices let) 移动信息设备小程序 ... 2

2.2 MIDlet 三种状态 ... 2

2.3 JAD 文件 ... 3

2.4 MANIFEST. 3

2.5 界面开发 (javax.microedition.lcdui) 3

2.6 多个按钮加入界面的排布规律 ... 3

2.7 Command 事件响应 ... 3

2.8 List 3

2.9 TextBox. 4

2.10 Ticker 滚动条 ... 4

2.12 表单元素 ... 5

2.12.1 ChoiceGroup. 5

2.12.2 CustomItem.. 5

2.12.3 DateField. 5

2.12.4 Gauage 进度条 ... 5

2.12.5 ImageItem.. 5

2.12.6 TextField 类似 TextBox. 6

2.12.7 StringItem 类似 Label 6

2.13 ItemCommandListener(item 事件 ) 6

2.14 ItemStateListener 6

3 数值运算 Math. 6

4 定时器 ... 6

5 手机震动和闪烁 ... 7

6 画布开发 Canvas (低级界面) ... 7

7 RMS 编程 (Record Management System) 8

8  网络编程 ... 9

9 Http 编程 ... 10

10 GameAPI 11

11 代码优化 ... 13

1 体系介绍和环境配置

 

1.1 J2ME 分为两类:

1 CDC(Connected Device Configuration) PDA CVM

2 CLDC(Connected Limeted Device Configuration) 如手机 KVM(Kilo Virtual Machine)

 

1.2 J2ME 体系架构 ( 底层— > 高层 )

底层操作系统—》配置 (Configurations) —》描述 (Profiles) —》可选包

注:手机属于 CLDC MIDP(Mobile Information Device Profile)

 

1.3 环境搭建

1 JDK1.6  java.sun.com/j2se

2 WTK2.5.2 java.sun.com/j2me

              WTK 重要目录介绍

              apps :例子及源码 bin :命令行工具 docs :文档 lib :类库

3 )插件 EclipseMe1.7.7 www.eclipseme.org 分别与 eclipse WTK 绑定

4 wtk 提供了四种手机模拟器,需要特殊模拟器可以到相应手机厂商网站下载

              Nokia www.forum.nokia.com

              Moto developer.motorola.com

 

2 高级界面开发

 

2.1 MIDlet(Mobile Information Devices let) 移动信息设备小程序

 

2.2 MIDlet 三种状态

a) 运行状态 ,startApp()

b) 暂停状态 ,pauseApp(), 通过 notifyPaused() 可进入该状态

c) 销毁状态 ,destroyApp(), 通过 notifyDestroyed() 可进入该状态

注:程序运行调用构造函数一次,在运行状态和暂停状态可相互切换,关闭则进入销毁状态

 

2.3 JAD 文件

描述具体运行的配置以及 JAR 文件所在位置

 

2.4 MANIFEST

描述 MIDlet Suite 的配置,扩展名为 .mf

 

2.5 界面开发 (javax.microedition.lcdui)

1) 界面组件 Displayable 及子类

2) 把组件添加到界面 Display

              Display d = Display.getDisplay(this);

              d.setCurrent(Displayable dis);

3)Command

不同于 Displayable ,只能用 Displayable.addCommand(Command c);

 

2.6 多个按钮加入界面的排布规律

1 )不同种类按钮, WTK 优先级排序:

ITEM,SCREEN,OK,HELP,BACK,EXIT,CANCEL,STOP

2 )同一种类按钮,在构造函数内划分优先级,越小越优先

3 BACK,CANCEL,EXIT,STOP 倾向抢占左方,优先级为 BACK,CANCEL,EXIT,STOP

4 )只在 WTK 满足这样的规律

 

2.7 Command 事件响应

1 )编写一个类实现 CommandListener javax.microedition.lcdui

2 )用 Displayable.setCommandListener() 方法将 Displayable 与该类绑定(与 J2SE 不同)

 

2.8 List

1) 三种类型: implicit 互斥, exclusive 另一种互斥, multiple 多选

2 )操作:

       添加项 append()

       删除项 delete() deleteAll()

       修改项 set()

       插入项 insert()

       得到项内容 getString() getImage()

       设置项字体 setFont()

       获取所选项 getSelectedIndex()

       list 总共多少项 size()

 

注:

获得多选项

1 )遍历每一项判断是否选中

2 )利用 getSelectedFlags() 判断那些项被选中

 

List 内置一 command 专门为 implicit 模式,可通过 SELECT_COMMAND 获得

 

2.9 TextBox

1) 创建 TextBox 时用到 TextField 的常量进行约束

2) 操作:

       获得光标位置 getCaretPosition() 0 开始

       获取所有文本 getString()

       插入文本 insert()

       替换文本 setString()

       删除文本 delete()

       设置初始输入法 setInitialInputMode()

       获取输入文字个数 size()

 

2.10 Ticker 滚动条

Displayable.setTicker();

 

2.11 Alter

1 Display.setCurrent()

2 alterType

       alarm 提醒 confirmation 确认 error 错误 info 通知 warning 警告

3 setTimeout() 设置持续时间 setTimeout(Alter.FOREVER) 永远不消失

 

2.12 表单元素

1 Form.append(item)

2 Display.setCurrentItem(item) 如有多个选择,设置为默认选择,但是在之前必须先把 item 添加到 Form

 

2.12.1 ChoiceGroup

类型: Choice.EXCLUSIVE 单选, Choice.MULTIPLE 复选, Choice.POPUP 下拉列表

 

2.12.2 CustomItem

用户自定义 Item ,必须继承自该抽象类

 

2.12.3 DateField

1 )三种模式

       DateField.DATE 只显示或修改日期

       DateField.TIME 只显示或修改时间

       DateField.DATE_TIME 显示或修改日期时间

2) getDate() setDate()

 

2.12.4 Gauage 进度条

1) interactive 参数:是否可以修改进度条的值

2 setValue() getValue()

 

2.12.5 ImageItem

1 )参数 layout :布局

   参数 altText :图片加载失败时显示的文字

   参数 appearanceMode :图片显示的样式

   s

2.12.6 TextField 类似 TextBox

 

2.12.7 StringItem 类似 Label

 

2.13 ItemCommandListener(item 事件 )

适用于表单上将某个表单元素和命令按钮进行绑定

步骤 1) implements ItemCommandListener

步骤 2 item.addCommand(Command)

步骤 3) item.setItemCommandListener(ItemCommanListener)

 

 

2.14 ItemStateListener

某个表单元素状态改变时触发事件

步骤 1 implements ItemStateListener

步骤 2 Form.setItemStateListener(ItemStateListener)

 

3 数值运算 Math

              ceil 不小于一个数字的最小整数 eg:ceil(1.3)=2

              floor 不大于一个数字的最大整数 eg:floor(1.8)=1

              toDegrees 弧度转角度

              toRadians 角度转弧度

             

4 定时器

每隔一段时间做一件事情

步骤 1 :定义一个类,继承 TimerTask ,重写 run 方法

步骤 2 :定义一个 Timer

       schedule(TimerTask task, Date time);   某时刻触发

       schedule(TimerTask task, Date firstTime, long period);      某个时刻开始执行,指定重复执行的周期,单位是毫秒

       schedule(TimerTask task, long delay);  某段时间之后触发

       schedule(TimerTask task, long delay, long period);      某段时间之后触发开始执行

      

5 手机震动和闪烁

震动: Display.flashBacklight(int) int 为持久时间

闪烁: Display.vibrate(int)     int 为持久时间

 

6 画布开发 Canvas (低级界面)

步骤 1 :写一个 class 继承 Canvas ,必须重写 paint Graphics

步骤 2: Display.setCurrent Canvas

 

showNotify ()画布放在界面最前端显示时自动调用

hideNotify ()画布隐藏时自动调用

paint Graphics )画布出现后自动调用

setFullScreenMode boolean )设置全屏

getHeight (), getWidth () 获取高度和宽度

 

Graphics 方法:

       setColor()       设置绘图颜色

       setStrokeStyle()     设置划线样式 SOLID 实线 DOTTED 虚线

       drawLine()     画直线

       drawRect()/fillRect()     画矩形 / 实心矩形

       drawRoundRect()/fillRoundRect() 画圆角矩形 / 圆角实心矩形

       drawArc()/fillArc() 画弧线 / 填充弧线

       fillTriangle()    填充三角形

       repaint()  强制重画

       setFont() 修改字体

       drawString()   画字符串

       注:确定定位点 LEFT,HCENTER,RIGHT | BUTTOM,TOP,BASELINE

                     将字画在屏幕正中,要用到 Font.stringWidth(String),Font.getHeight()

       drawImage()   画图片

       drawRegion()  截取图片的一部分画到另外一个地方去

      

按键事件:

       keyPressed(int keyCode)       按下某个键

       keyReleased(int keyCode)      释放某个键

       keyRepeated(int keyCode)     一直按着某个键

      

      注:除 0-9 键外其他键被认为为特殊键(游戏键),特殊键不能直接通过 keyCode 获得,要通过 getGameAction(keyCode) 转换才能得到相应值,反之可以通过 getKeyCode(action) action 转换为 keycode

      

指针事件:

       pointerDragged(int x, int y)

       pointerPressed(int x, int y)

       pointerReleased(int x, int y)

       注: x,y 为指针当前位置

       hasPointerEvents() 判断手机是否支持指针按下,释放

       hasPointerMotionEvents() 判断手机是否支持指针拖动

 

7 RMS 编程 (Record Management System)

 

1)javax.microedition.rms

2)RecordStore 相当于

4) 数据文件路径在:用户名 /j2mewtk/appdb/temp.DefaultColorPhone** 下面的 *.db 文件

3) 记录集操作

    打开记录集                                 RecordStore.openRecordStore()

              得到记录集大小                 RecordStore.getSize();

              关闭记录集                        RecordStore.closeRecordStore();

              列出当前所有记录集            RecordStore.listRecordStores();

              删除记录集                          RecordStore.deleteRecordStore();

              获取记录集可用空间            RecordStore.getSizeAvialable();

5)RecordStore 记录操作(每条记录都有 ID ,第一条记录 ID 1

              添加记录                                                       addRecord()

              得到当前记录条数                           getNumRecords()

              根据 ID 获得记录                                    getRecord()

              根据 ID 获得记录字节数                    getRecordSize()

              修改记录                                                                setRecord()

              删除记录                                                                deleteRecord()

              获取下一条要插入的记录 ID getNextRecordID()

6) 将对象写入 RMS

              自己写方法将对象转为字节数组

              DataOutputStream

              ByteArrayOutputStream baos = new ByteArrayOutputStream();

              DataOutputStream dos = new DataOutputStream(baos);

              dos.writeUTF(this.cname);

              dos.writeUTF(this.phone);

              dos.writeUTF(this.age);

              baos.toByteArray();

7) 遍历记录

              RecordStore rs = RecordStore.openRecordStore();

              RecordEnumeration re = rs.enumerateRecords();

              while(re.hasNextElement())

              {

                            re.nextRecord();

              }

8) 记录监听 (implements RecordListener)

              记录添加时触发            recordAdded(RecordStore, recordid);

              记录修改是触发            recordChanged(RecordStore, recordid);

              记录删除时触发            recordDeletedRecordStore, recordid);

              绑定监听器                   rs.addRecordListener(RecordListener);

9) 数据过滤

              implements RecordFilter,

              实现 match 函数 ,

              用枚举方法遍历 , 传入类的对象

10) 数据排序

              implements RecordComparator,

              实现 compare 方法 , 返回指定值

                     RecordComparator.PRECEDES: 记录 1 在记录 2 前面

                     RecordComparator.FOLLOWS: 记录 1 在记录 2 后面

                     RecordComparator.EQUIVALENT: 记录 1= 记录 2,

              用枚举方法遍历 , 传入类的对象

11) 注意事项

              a. 可以修改 MF 或者 JAD 文件中的 MIDlet-Data-Size 属性来改变 RMS 的最小存储字节数 , 首选 JAD

              b. 一个记录集的容量有限 , 100K, 如果数据太大 , 考虑用多个记录集

             

8  网络编程

 

1)Socket 编程 (javax.microedition.io)SocketConnection

       a. 服务器端

              // 监听 9999 端口

              ServerSocketConnection ssc =

                            (ServerSocketConnection)Connector.open("socket://:9999");

              ssc.getLocalAddress();         // 获取本地 IP 地址

              ssc.getLocalPort();               // 获取本地端口

              // 等待客户端连接 , 如果没有客户端连接则阻塞

              SocketConnection sc = (SocketConnection)ssc.acceptAndOpen();

              sc.getAddress();                   // 获得客户端 IP 地址

              DataInputStream dis = sc.openDataInputStream();

              String str = dis.readUTF();    // 如果没有读到内容则死等

       b. 客户端

              // 连接到服务器端 , 与服务器端的 sc 是同一对象

              SocketConnection sc = (SocketConnection)Connector.open("socket://127.0.0.1:9999");

              DataOutputStream dos = sc.openDataOutputStream();

              dos.writeUTF(String);

             

2)UDP 编程 (javax.microedition.io.UDPDatagramConnection)

       a. 服务器端

              // 监听 9999 端口

              int max = 255;

              UDPDatagramConnection udc =

                            (UDPDatagramConnection)Connector.open("datagram://:9999");

              // 接收数据报

              Datagram dg = udc.newDatagram(max);

              udc.receive(dg);

              byte[] data = dg.getData();

              String str = new String(data, 0, dg.getLength());

               

       b. 客户端

              UDPDatagramConnection udc =

                            (UDPDatagramConnection)Connector.open("datagram://127.0.0.1:9999");

              // 发送数据报

              String str = " 你好 ";

              Datagram dg = udc.newDatagram(str.getBytes(), str.getBytes().length);

              udc.send(dg);

             

9 Http 编程

 

       HttpConnection hc = (HttpConnection)Connector.open("http://localhost:9999/test.html");

       hc.getResponseCode();                // 返回代码,如 500 404

       hc.getResponseMessage();           // 返回信息

       hc.getHost();

       hc.getPort();

       hc.getProtocol();

       hc.getURL();

       hc.getQuery();                                   // 得到查询字符串

       hc.getRequestMethod();               // 得到请求方法 Post Get

       hc.setRequestMethod(String);       // 设置请求方法

       hc.getLength();                                  // 获得网页大小

 

       与服务器交互:

       hc.openDataInputStream();/hc.openInputStream();

       hc.openDataOutputStream();/hc.openOutputStream();

      

10 GameAPI

 

1)    javax.microedition.lcdui.game 提高游戏性能

 

2)    GameCanvas :游戏画布,比普通画布更加适合游戏开发

       a) 基本结构

              public MyGameCanvas extends GameCanvas implements Runnable{

                     public MyGameCanvas(){

                            //true 特殊键被禁用,通过 getKeyStates() 获得按下哪些游戏键

                            super(true);

                     }

                     public void run(){}

              }

       b) 可以通过 getGraphics() 得到画笔 , 不用写 paint() 函数 , 不用 repaint() 开销 ,

         flushGraphics() 将缓冲区里的图像显示在屏幕上

      

      

 

3)    Layer :图层,表示画布上的某个可视的物体,是抽象类

              a)Sprite :可以充当游戏中的具体角色,一般用于运动角色,如子弹,汽车等

                     * 重要方法

                            move(int x, int y);                // 移动相对位置

                            setPosition(int x, int y);  // 移动绝对位置

                            Sprite(Image image);

                            Sprite(Image image, int frameWidth, int frameHeight);

                            paint(Graphics g);                // 将图层画到屏幕上

                     * 悬挂

                            defineReferencePixel(int x, int y);  // 定义图层悬挂点

                            setRefPixelPosition(int x, int y);    // 定义悬挂点在屏幕的某个位置

                            setTransform(int transform)                // 旋转

                     * 碰撞

                            // 定义一个矩形的不可碰撞区域

                            defineCollisionRectangle(int x, int y, int width, int height);

                            // 判断是否和另外一个 Sprite 碰撞,参数 2 true ,则认为不透明点发生碰撞才算碰撞

                            collidesWith(Sprite s, boolean pixelLevel);

                            // 判断是否和 TiledLayer 发生碰撞

                            collidesWith(TiledLayer t, boolean pixelLevel);

                     * 带动画的角色

                            // 切割图片原则:首先走行,一行走完,取下一列,编号从 0 开始

                            Sprite(Image image, int frameWidth, int frameHeight);

                            // 得到总帧数

                            int getRawFrameCount();

                            void nextFrame()/void preFrame()/void setFrame(int sequenceIndex);

                            // 设置帧的顺序

                            setFrameSequence(int[] sequence);/int getFrameSequenceLength();

                            // 设置图片

                            setImage(Image img, int frameWidth, int frameHeight);

                           

              b)TiledLayer :可以充当游戏中的具体角色,一般用于环境角色,如地图等

                     * 构造函数

                            // 将图片用 tileWidth tileHeight 分割,指定将要填充的列数和行数

                            // 图片小块 index 1 开始

                            TiledLayer(int columns, int rows, Image image, int tileWidth, int tileHeight)

                            void patint(Graphics g);

                            // 将某个图片小块填入相应的位置

                            void setCell(int col, int row, int tileIndex);

                            // 得到某行某列图片的 Index

                            int getCell(int col, int row);

                            int getCellHeight();/int getCellWidth();

                            int getColumns();/int getRows();

                            // 用一个图片小块填充整个网格

                            void fillCells(int col, int row, int numCols, int numRows, int tileIndex);

                            // 修改图片

                            void setStaticTileSet(Image image, int tileWidth, int tileHeight);

                     * 技巧

                            应将不同的物体弄成不同的图层,便于碰撞检测

4)    LayerManager: 管理图层的变换

              void append(Layer l);

              void remove(Layer l);

              // 设置窗口可视部分

              void setViewWindow(int x, int y, int width, int height);

              // 将所有图层统一画出来

              void paint(Graphics g, int x, int y);

             

11 代码优化

       1) 微观编程

              * 除法优化 / 改为 >>

              * 局部变量赋值性能高于全局变量

              * 使用 switch 代替 if else, 可读性比较好

       2) 字符串

              * String str = "China";

              * s.length()==0

              * (StringBuffer)sb.append(',');

              * StringBuffer 比较好

       3) 异常处理 , 尽量少用

       4) 内部类需要额外开销

       5) 引用不用后置空

          连接最终要关闭

       6) Midlet 各函数功能分配

              * 成员变量生成和构造函数 , 在生命周期中执行一次 , 一般完成资源分配 , 对象创建

              * 一般在定义时创建对象 , 或在构造函数中创建对象

              * pause 函数运行之后如果再继续 ,startApp 会运行 , 所以可以在 pause 函数中释放一些资源 , startApp 中获得

              * destroyApp 释放所有资源

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多