May
27
2008
这是一个手机上少见的OpenSource的J2ME应用,Imity是一个社交软件,其最大的特点是利用蓝牙来在你的周围寻找志趣相投的朋友,也就是说如果两个人都在手机上安装这个软件,那么如果他们某个时间在同一个地方出现,那么Imity会记录下这些偶遇,并且如果设置了某些过滤条件的话,比如有共同的爱好什么的,Imity也可以做即时的提醒。这个创意本身并不是特别新颖,很多年以前日本人好像就有类似的电子玩意,只是现在随着蓝牙在手机上的普及,变得更加方便实用了。
我比较困惑的就是,这个蓝牙应该不会一直打开的(费电),所以如何控制好这个蓝牙的搜索?比如每分钟开10秒钟这种简单的算法可能会导致两个人永远的错过(假设他们的手机时间差10秒),又或是象以太网一样用一个随机的关闭时间,再或者是保证手机时间同步(那样用什么算法都可以了),比如可以从运营商网络那里获取时间。
有意思的是,Imity开放了手机端的源码,从这个J2ME的源码里面,可以看到蓝牙部分是通过JSR82(蓝牙接口)来实现的,看了一下,它的算法很简单,就是简单的周期性开蓝牙(类似每分钟开10秒),难道老外的手机都是缺省时间同步的吗? 有些不解。
no comments | tags: j2me, mobile | posted in tech|软件、开源、业界
Apr
26
2008
J2ME里面,直到MIDP2.0都没有Log的功能,本来不是大的问题,可以自己做一个嘛,不过在J2ME里面却不那么简单了,因为不知道把Log往哪里放,最常见的两个Log输出选项在J2ME都不具备(或者说不完全具备):
- 控制台(console):大部分J2ME设备没有控制台,system.out.print的东东都会消失掉,不过Sun的模拟器倒是可以的,但毕竟是模拟器,没法进行设备上的调试。
- 文件:这个要支持JSR75的设备才行,遗憾的是,很多设备都不支持(主要是早期的)。
所以,基本的做法只能是记在内存里,需要时把这个字符串取出来显示,不过这真不是一个好的解决方法,很简单的问题,如果代码崩溃了,就看不到的了。比较理想的一个方式是蓝牙(直接在PC端看Log),不过比记文件条件更高啊,需要两端都有蓝牙,并且设备端支持JSR82(N73好像支持),但起码我的笔记本还没有蓝牙。
no comments | tags: j2me, java | posted in code|编程
Apr
16
2008
在用J2ME的低级UI时,所有的界面绘制要靠自己来实现,主要是在paint消息中来做,这里涉及几个接口:paint,repaint,serviceRepaints,callSerially,我搞了一段时间才把它们弄明白。
paint
paint相当于是个回调函数,被J2ME主线程(处理UI和事件)来调用,任何时候我们都不能自己直接调用paint,程序在paint里面按部就班的画出界面即可,paint会带一个Graphics参数,用这个graphics去作图就可以了。
现在的很多J2ME平台已经默认支持双缓冲,所以在paint执行时,实际上界面并没有画出,而是等到paint执行完成后,一次性刷新到屏幕上的,不过这是和平台相关的。
repaint
这个是通知系统,我们需要刷新界面了,但仅仅是个通知,repaint会立即返回(无阻塞),paint会在合适的时候被系统调用,所以paint和repaint不是一一对应的,有一个repaint并不意味着一定会触发一个paint,多个repaint可能会被合并到一个paint调用。
如果在paint里面调用repaint,那么就意味着这个paint结束后会被再次调用,这在有些需要连续不段的刷屏的程序中可能有用,不过显然不太合适,比如下面这种代码。
public void paint (Graphics g) {
repaint();
}
serviceRepaints
如果调用serviceRepaints,则会直接立刻重绘界面,阻塞式调用,直到paint完成。所以如果我们写出下面的paint接口:
public void paint (Graphics g) {
repaint();
serviceRepaints();
}
后果相当于递归调用,并很快造成内存耗尽(Out of memory)异常,因为serviceRepaints里面又会直接调用paint(),所以使用serviceRepaints一定要小心,可以在某些地方使用serviceRepaints,但绝不能在paint里面调用。
callSerially
这个接口可以将一个Runable的接口抛在系统队列尾部,处理完消息之后,执行这个Runable接口的run,这在有些使用paint绘制的程序中会用到,可以在paint完以后,通过callSerially触发run接口,表示界面已经画完,可以做别的事情了,又不会阻塞系统队列。
1 comment | tags: canvas, j2me | posted in code|编程
Mar
23
2008
需要承认,我一直没有注意Netbeans的Visual Mobile Designer(VMD),因为毕竟Netbeans不是VB/Delphi这种专门的RAD工具,在Netbeans里面提供这种让程序员用所见即所得的方式去控制界面和自动生成代码的工具,总感觉有些怪异,而且VMD还不仅仅是画界面,它还提供了程序逻辑功能,有点象流程图,并且里面的箭头都是“绘制”出来的,你会习惯用这种方式写程序吗?
由于J2ME本身用户界面部分的代码并不复杂,因此手动用代码来实现其实也可以接受,不过如果想快速写一个程序,VMD还是蛮合适的。而且除了标准的J2ME控件外,VMD还提供了一些基于J2ME控件的Custom控件(想一想VB/Delphi都有这些),比如什么Splash/Login 等等,这些如果手动写代码还是有点麻烦的,所以想用这些的话,VMD也挺合适的。
至于使用“流程图”来代替逻辑部分的编程,显然只能对小程序适用,而恰恰很多J2ME的程序都很小,因此也可以一用。我自己试用的结果是效率是有一些提高,而且和所见即所得的界面编辑功能结合起来,还真挺方便的,印象大为改观,什么时候用这种方式“画”一个程序出来看看效果如何。
一些参考文档:
no comments | tags: j2me, netbeans | posted in code|编程
Mar
16
2008
Synclast是J2ME的一个UI库,提供了常见的一些GUI控件,这些GUI控件在不同的手机中可以保持一致的外观。
需求
一般来说,J2ME的GUI有两层API,一层是高级UI,提供了各种GUI控件,但是J2ME只是规定了这些控件的接口,没有规定实现,因此不同厂商的这些UI的实现有很大的差异,也就是在不同的手机上看到的UI可能会有差异,另一层是基于Canvas的低层绘图接口,这一层次上需要应用程序直接在Canvas上绘制用户界面,不提供控件功能,但是好处是在各个手机上有一致的效果。
很多应用程序希望得到这种一致的效果,但直接在Canvas上编程又太麻烦了,于是就有了各种基于Canvas的UI库,Synclast是其中的一个。
安装
在Ubuntu下,不能用apt-get来安装synclast,需要到Sourceforge上去下载(似乎已经很久没有更新版本了,最新的可下载版本还是2004年的,但直接用cvs版本的话会有不少更新),展开后的Synclast包括了源码,例子以及编译好的jar包,要安装例子程序,可以使用下面的命令:
export J2ME_HOME=/usr/local/netbeans-6.0/mobility8/WTK2.5.2/
sudo ant demo
这会将Synclast的例子程序安装到系统中去。
运行
启动Netbeans6,选择New Project中的Mobility下的Import Wireless Toolkit Project,就自然可以看到SynclastUIDemo这个工程了,创建它,剩下的工作就很简单了,直接在Sun模拟器下运行就可以看到Synclast UI的几个例子。
因为我没有用过它,所以不作评价,类似的这种UI库还有J4ME,J2ME Polish等,不过感觉还是不够多,可能和J2ME在手机应用程序领域的流行度有关。
no comments | tags: j2me, netbeans, ubuntu | posted in code|编程
Mar
11
2008
Double buffer(双缓冲)曾经是游戏编程中常用的一个技巧,可以使动画更平滑,它的原理很简单,就是在刷新显示时,先在内存中作图,再从内存“拷贝”到真正的显示设备上,通常拷贝比直接绘图要快,因此这个方法可以显著提高显示切换的速度,做到平滑的显示效果,因为要准备一个内存中额外的缓冲,所以这种方法通常被称为双缓冲(Double buffer)。
J2ME中的UI部分,如果使用低级的Canvas来做用户界面的话,Canvas仅仅提供了一些最基本的绘图操作(线,框,填充等),要支持象按钮,列表等这些UI控件的话,不免要自己来做绘制了,这时Double Buffer就可以派上用场了。在有些平台上,Double Buffer已经内嵌就支持了,我在Sun的模拟器和N73上实测的结果是这两个平台已经都支持了Double Buffer,无需再写代码去实现额外的显示缓冲了,在Symbian S60的网站上也找到了一篇文章证实了我的猜测。
这里的一篇文章详细介绍了在使用Canvas时如何使用Double Buffer,还提供了一个动画的例子程序,这个例子代码使用了Canvas的isDoubleBuffer接口来判断一个Canvas是否已经支持了DoubleBuffer,如果不支持的话,才自己分配一个buffer来做Double Buffer,如果已经支持了,那么直接绘图就可以了。但是代码中有一个明显的bug,这句话:
g.drawImage (offscreen, 0, 0, Graphics.TOP | Graphics.RIGHT);
需要改为:
g.drawImage (offscreen, 0, 0, Graphics.TOP | Graphics.LEFT);
不过这个语句只在Canvas不支持Double buffer才用到(用于buffer的拷贝),所以在模拟器上是没有影响的,我也是为了验证double buffer的效果,特地注释了前面的isDoubleBuffer的检测(强制使用代码实现的Double Buffer)才发现这个bug。
no comments | tags: j2me | posted in code|编程
Feb
17
2008
《Core J2me Technology》,不要被书名忽悠了(又或是我对Core这个单词理解不够),这本书是很基础的一本J2me书,深入浅出,细节讲解透彻,示例代码也清晰明了,这应该算是不错的评价了吧,就是涉及的内容少了点,一些内容提都没有提到,还有就是前面开发环境搭建的章节有些过时了(开发工具发展比较快,书没有跟上),但作为一本学习MIDP编程的入门书还是很好的。
《Beginning J2ME: From Novice to Professional》书名则要清晰的多了,从目录上看,内容也要比上本书丰富许多,包括了Core一书中没有提到的诸如蓝牙,短信,多媒体等内容,可惜在细节上下的功夫不够,我对比了两本书讲同一内容的几处章节,Core一书大多要清楚一些,所以这本书我就没怎么看了(那些蓝牙之类的章节我还没有需求)。不过在Amazon上它也是4星的评价,也算不错啦。
对比一下,好像Core一书可以说是“少而精”,而Beginning一书则相对“多而糙”,你喜欢哪种?
no comments | tags: book, j2me | posted in code|编程
Feb
1
2008
这是J2ME里处理Web连接最常用的方法, 但一个小问题很容易被遇到:
Connector.open通常会使得J2ME虚拟机弹出一个警告:是否连接网络?真实的手机上也会有类似的警告(比如Nokia N73)。而这个警告是需要用户选择同意的,如果在程序的主线程中执行Connector.open,由于主线程同时需要处理GUI事件,那么这里就形成一个"死锁"。
如果是用Netbeans的话,Netbeans在调试运行时,会"发现"这类主线程中的网络调用,并在调试控制台显示警告信息,提示这类调用应该在单独的线程中执行,这个比较人性化,要是它能自动实现这个单独的线程,那岂不更妙(做梦吧。。。)
3 comments | tags: j2me, netbeans | posted in code|编程
Jan
25
2008
Sun的模拟器我感觉还是不错的,不过还可以给它们做很多设置,在
/usr/local/netbeans-6.0/mobility8/WTK2.5.2/wtklib/devices
下面可以看到每种设备有一个目录,在每个目录下都有一个xxx.properties (xxx取决于设备名)文件,编辑这个文件就可以设置某类模拟器的很多细节参数,比如
设置 touch_screen = true 就可以得到一个带触摸屏的模拟器(当然要运行的程序也支持触摸屏,才能看到效果),Cool。
no comments | tags: j2me, netbeans | posted in code|编程
Jan
22
2008
使用Nokia模拟器可以很方便的在PC上调试midlet,不过我用下来最深的感受是,慢。。。
也许是我的PC性能不佳,也有可能是这个Nokia Emulator优化不够,又或是Windows系统有关,反正在Netbeans里面,直接调用Nokia Emulator来调试的话,肯定是Emulator连不上而超时(因为模拟器还在那慢腾腾的启动呢),如果先用一般的run模式启动模拟器运行一下midlet,然后不关闭模拟器,再选调试就可以了。
Nokia的SDK包还支持真机调试,需要在手机上装一个Debug agent,我还没有试过,不过Nokia模拟器的模拟度似乎很高,估计大部分情况时是不需要这个牛刀的。。。
no comments | tags: j2me, netbeans | posted in code|编程