KavaFrame是什么
1.KavaFrame是一套基于MIDP2.0的Java ME应用程序开发微型框架。
2.KavaFrame只使用MIDP中的低级图像用户界面API。
3.KavaFrame适用于多用户界面的应用程序开发,不适合于游戏开发。
4.KavaFrame侵入性小,代码精简,内存占用量少,易于扩展,易于使用。
在哪里下载KavaFrame
以下是KavaFrame的google project主页,你可以从那里的下载栏目下载
http://code.google.com/p/kavaframe/
或者,如果你安装了svn客户端,可以从以下地址checkout:
http://kavaframe.googlecode.com/svn/trunk,这是最好的方式,这样你就能和最新代码同步。
你可以在项目论坛里发表你的意见,项目论坛在这里:
http://groups.google.com/group/kavaframe
KavaFrame怎么用
让我们首先浏览一下demo工程的代码,看完这个demo后,你就知道如何使用KavaFame了。
首先根据下载的代码,在eclipse中搭建好工程。
注意点:
a. 此工程是UTF-8编码的。
b. 此工程适合于240*320屏幕大小的手机。
工程搭建完毕,运行一下,你可以看到demo的运行效果:
接下来,让我们看看demo工程的代码:
首先是DemoMIDlet,该类实现了一个KavaFrameUser的接口,该接口包括以下3个方法。
public void handleAppMessage(int msgCode, String msg) ;
public void launch();
public int numAlphaLevels();
其中第一个方法handleAppMessage,用于处理从KavaFrame传来的消息。在应用程序运行过程中,不同的模块经常要进行异步通信。使用KavaFrame,只需要消息源向KavaFrame发送消息,KavaFrame会把消息放入消息队列,一个daemon线程会把消息队列中的消息一个个取出,交由KavaFrameUser处理,直到程序结束。
launch()方法,是KavaFrame中的GUI系统的执行入口点。Kava GUI中,每一个应用程序界面就是一个Form对象。注意,这里的Form,并不是javax.microedition.lcdui.Form对象。每一个Form对象都有一系列的属性,比如前景色,背景色,字体大小等属性。另外,Form对象还具有触笔处理方法,按键处理方法,以及一个paint(Graphics g)方法。也就是说,每个Form都能接收输入,处理输出。另外,在KavaFrame系统中,有一个Form栈,这个Form栈就是一个Form对象管理器。你可以使用KavaFrame.push(Form form)方法,把一个新生成的Form对象入栈,也可以使用KavaForm.pop()方法,把栈顶的Form对象弹出。当一个Form对象成为当前Form时,也就是它获得焦点时,其onActive方法会被KavaFrame系统调用,当一个Form对象失去焦点时,其onDeactive方法也会被KavaFrame系统调用。Form对象管理器拦截了内部GameCanvas对象的所有输入,交由顶层Form对象处理。因此,你只需要在launch()方法中,把第一个Form界面入栈,接下来的流程,就由用户输入来驱动了。
第三个方法numAlphaLevels,目前没什么特别的用处,只需返回Display对象支持的alphaLevel即可。
接下来我们要看的,是主界面MainForm的代码。在截屏图中我们看到,MainForm包含4个界面元素,一个是KavaFrame的标签,2个椭圆型的按钮,还有一个右软键按钮。在KavaFrame系统中,这种包含多个页面元素的Form都是ContainerForm或者ContainerForm的子类。ContainerForm中的每一个元素,都是一个Widget对象。ContainerForm内包含多个Widget对象。每个Widget对象的属性就更多了,比如背景色,背景图片,聚焦背景色,聚焦背景图片,前景色等等。你当然可以用程序的方式生成一个个Widget对象,给这些Widget对象的属性赋值,再把这些Widget对象加入到ContainerForm中,但是KavaFrame支持UI脚本,你只需在配置文件中定义好界面的UI脚本,调用脚本解析器就能轻松的搞定这一切。KavaFrame的UI脚本类似于MS Visual studio的资源文件。以下就是msgbox Form的UI脚本:
msgbox form begin
x = 43
y = 114
width = 154
height = 92
title = msgbox
pngs = msgbox.png
bgImage = msgbox.png
fgColor = 0x0
widgets begin
id = 1,x = 15,y = 70, width = 20, height = 20, text = 是,focusBgColor = 0xaa1002,focusFgColor = 0xffffff,visual = false
id = 2,x = 114,y = 70, width = 20, height = 20,text = 否,focusBgColor = 0xaa1002,focusFgColor = 0xffffff,state = STATE_FOCUSED,visual = false
widgets end
msgbox form end
这段脚本,定义了msgbox的各种属性和它的各个Widget的属性。每一个属性名称都很通俗易懂,我就不一一说明了。你可以试着改动属性值看看效果。这里值得一说的是Form对象的pngs属性,该属性中定义了一系列的png文件路径。这些png文件就是该Form绘制时所需的所有图片资源。在KavaFrame中,为了节省内存,根类Form的onActive方法中,写有装载png资源的代码,而在其onDeactive方法中,写有其释放png资源的代码。
因此,在MainForm的构造函数中,有这么一句:ScriptParser.parseFormFromScript(this, "/ui.txt", "MainForm");该句的作用就是使用脚本解析器,解析脚本文件ui.txt中的MainForm段落,来初始化MainForm。
MainForm中的其他函数都很简单,无非就是override父类ContainerForm的输入处理函数,实现应用程序特定的逻辑罢了。
另一个界面类MsgBox的代码也和MainForm类似。也是差不多的处理流程。使用KavaFrame这个Java ME应用程序开发框架,好像我们又回到windows api编程的时代,只不过,这里使用诸多的override方法,代替了老式的winproc中庞大的swich结构。
MsgBox中值得一提的是它的onActive中有这么一段:
if(this.autoDismiss){
this.setTick(System.currentTimeMillis());
KavaFrame.addAppMessage(DemoMIDlet.APP_MSG_CHECK_MSGBOX_LIVE, null);
}
这个代码段的意思是指在MsgBox对象获得焦点的时候,在KavaFrame的消息队列中添加一个应用程序相关的消息。KavaFrame的消息处理线程会在稍后把这个消息交给KavaFrameUser处理,在这里也就是我们的DemoMIDlet对象,DemoMIDlet对象的handleAppMessage方法中会对该类消息进行处理。仔细看这个处理过程就知道,DemoMIDlet会检测MsgBox的显示时间,如果显示时间不到1秒钟,那么继续在消息对列中添加此类消息,从而引起DemoMIDlet对此类消息的再一次处理;如果MsgBox显示时间超过1秒钟,那么DemoMIDlet就会把这个顶层Form从栈中弹出。这就是MsgBox的autoDismiss属性的含义。你可以充分利用这个KavaFrame的消息处理机制,做一些有意思的事情,比如动画等等。
在KavaFrame系统中,应用消息包括2个部分,一个是消息码(通常是应用程序定义的消息常量),一个是String类型的消息内容。本来KavaFrame的旧版本中有专门的KavaEvent对象,后来笔者觉得此对象太重,过于oo,不适合在Java ME中使用,所以就改成了现在这种轻量的形式。
大家可以看到,KavaFrame使用了多个配置文件来减少代码量。除了代表界面配置的ui.txt外,还有kc.txt配置文件定义了键码,str.txt配置文件定义了字符串资源,config.txt定义了应用程序相关的key-value对。这里要提一下的是config.txt中的launch_time属性,该属性有两个值,或者是“FIRST_SHOW”(默认),或者是“FIRST_SIZECHANGE”。这个属性告诉KavaFrame在什么时候调用KavaFrameUser的launch方法。FIRST_SHOW指的是在KavaFrame内部GameCanvas的第一次showNotify时调用launch,而FIRST_SIZECHANGE指的是该GameCanvas的第一次sizeChange时调用launch。
最后,我们来看看DemoMIDle中的exit方法,该方法中又调用了KavaFrame的destory方法。查看KavaFrame的源代码可知,该destory方法所做的事情,是把Form栈中的Form对象逐一弹出,释放所有资源。并且设置应用消息队列的daemon线程的终止标志,并且坐等该线程死亡。
至此,demo工程的代码分析完毕。你还可以把工程的WTK换成一个支持触笔的SDK(比如Moto E680)来运行一下代码。你会发现无论是触笔还是键盘,该demo工程都能很好的支持。
总的来说,KavaFrame会让你专注于应用逻辑,减少底层接口的羁绊,保持代码的简单易读,随着你应用程序界面的不断增加,其优势会越来越明显。
KavaFrame的内部机制
KavaFrame的核心代码,都在kava.framework.lcdui和kava.framework.util这两个包中。前者为GUI系统,后者提供工具支持。
kava.framework.lcdui
该包中包含以下几个类:
- KavaFrame
该类为KavaFrame的核心类。使用单例模式。对外暴露的方法都为public static方法。该对象包含一个GameCanvas子类对象,作为其内部画布。该对象还包含一个Form栈,字符串资源表,配置条目表。还包含一个消息队列以及消息处理线程。
当该单例对象生成时,它会读取字符串资源和配置条目,启动消息处理线程。
用户主要通过KavaFrame的push,pop,peek等方法来操作其Form栈。每当Form栈中元素发生增减变化,KavaFrame都会调用相关Form对象的onActive方法和onDeactive方法,装载或者释放资源。并且重绘需要重绘的Form对象。有一点要注意,在KavaFrame中,除了Form对象的入栈,出栈外,其他所有的绘制都是按需绘制的,KavaFrame并没有专门的线程来帮你实时刷屏。也就是说当你触发了一个事件,比如点击一下按钮,如果该动作并不引起Form栈的变动,但是你想重绘一下屏幕的某一区域或者整屏刷新,你就必须从KavaFrame那里获取Graphics对象,进行相应的绘制操作。之所以这样做,是出于对性能的考虑。
- Form
该类为所有Form对象的根类。该类规定了所有Form对象都必须实现的输入(响应用户输入),输出(绘制)方法,同时也定义了所有Form对象都具有的属性,比如坐标,宽高,标题,前景色,背景色等。另外,对于Form对象所关联的png图片的加载和释放方法,也都是在根类Form中定义的。
- ContainerForm
ContainerForm是Form的直接子类。顾名思义,ContainerForm是包含界面子元素的Form。尽管你可以直接继承Form来实现一个包含多个界面元素的界面,但是如果继承ContainerForm,将获得更大的便利。相对于Form,ContainerForm增加了管理界面子元素的功能。
- Widget
该类对象代表ContainerForm上的界面子元素,你可以把这些对象看做是一个个的Button。该类对象包含的属性很多,你可以从前述的UI脚本文件文件中看出来。基本上,该类就是一个典型的Java Bean。因为考虑到它只是一个View层面的东西,相对而然不太重要,所以为了保持整体框架的精简,笔者把它的所有属性都定义成了public的,而且不提供getter,setter。
- ScriptParser
该类提供UI脚本解析功能。
- KavaFrameUser
该接口定义了使用KavaFrame框架所必须实现的接口。
kava.framework.util
该包为KavaFrame所使用的工具包,包含以下几个类:
GUIUtil :提供绘制工具函数
NetLoadListener:网络下载侦听接口,当你需要为网络下载提供进度信息时,此接口比较有用,Uitl类的getViaHttpConnection方法依赖于此接口。
URLEncoder:此类提供J2SE中同名类的相似功能,该类来自网络。
Util:该类提供了一系列很有用的工具方法,如整数和字节数组之间的相互转换,字符串的split和replace,UTF文件的读取,基于http的网络访问等等。
其他
KavaFrme的优势在于提供了一个最基础的MIDP应用程序开发框架,它让你告别了繁琐的状态机代码,提供了一套类似Windows的编程方式,能让你的主要精力集中在应用逻辑代码上,从而节省你的开发时间和成本。当然,它的UI脚本和J2ME Polish的CSS比较起来,简直可以称得上原始人。另外该框架定位在“使用低级GUI进行应用程序开发”这一领域,因此它对游戏开发意义不大,这些都是其劣势所在。另外,笔者在好几个实际项目中应用了这套framework,感觉还是提高了不少生产效率。
作者信息
Jagie,移动开发爱好者,可以通过chen_cwf@163.com与他联系。本文来源于Jagie的google page: http://chencwf.googlepages.com/kavaframe


