Habitat Framework

专注于Java EE企业级开发
posts - 13, comments - 81, trackbacks - 0, articles - 5
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2007年4月23日

Nokia在Maxis推广Widget的时候告诉我Widget只能在S603.2上运行,所有S603.0系列手机可以通过软件升级来支持这个新功能

Baidu一把,发现一大把人在说不能升级到S603.2,那不和Nokia的说法矛盾,Google一把Nokia software upgrade,找到一个自动更新程序
连上手机,可以自己帮你识别你的电话是否有最新软件升级可用,花了10多分钟就下载完114Mb的升级文件,然后又花了5分钟刷机成功,开机后感觉速度没有太大提升,反而铃声没有以前清脆了,我一款短信铃声以前听起来高音非常不错,现在听有爆音了.......马上测试了下我自己开发的Widget,果然可以识别并提示安装,装好了就和普通的Symbian Application一样,不错,又有得玩了........

但是由于一直没有查到S60的版本查看方法,所以我始终不知道我到底是不是升级到了3.2,如果有人知道,麻烦留言告诉一声

posted @ 2008-07-23 12:44 Kerwin Weng 阅读(293) | 评论 (0)编辑 收藏

好像国内对Adobe的新产品AIR反应还不多,我个人试用了下觉得其实用处还是很大的,于是我就抛砖引玉写一篇相关介绍文章吧

AIR其实是一套框架和一个VM,它允许用户把Javascript,HTML,CSS集成到统一的客户端,在用户桌面运行,避免了浏览器差异,并且实现了跨平台的通用性,同时又对Javascript功能进行了很多扩展,比如读取本地磁盘文件,做跨域的远程访问,使用多媒体文件等等(相信是flash的底层在支持),相对于两年前的Flex,AIR在RIA领域无疑又是一个跨越,
想象一下以后我们可以用JS+HTML+CSS来写基于http的远程且防火墙安全的C/S应用了,还是蛮爽吧
Demo在这里:http://labs.adobe.com/showcase/air/?promoid=BJXTF
用JS来写应用的文档在这里:http://livedocs.adobe.com/labs/air/1/devappshtml/


Adobe AIR出新版SDK后,出乎意料的是很多之前的Demo不能跑了,会出"parsing disallowed"
,原因就是adobe换用了新的安全框架,禁止掉了Javascript中某些可能对其框架做出安全威胁的API,比如说JSON的命根--eval

Adobe的官方解释是在AIR2禁止掉了类似eval这种动态代码加载技术在其Application sandbox中的运行,解决办法是把你有eval的应用移到Browse sandbox中执行,所谓的Browse sandbox意思是你的应用主页面是通过application.xml中配置的根页面来用iframe引入的,在iframe引入的页面中你就可以做eval,而把其他如跨域查询等AIR提供的高级API操作放到根页面中去做,然后通过一个parent/childSandboxBridge来做互相引用和传递数据的桥梁,
但是同时你在iframe中的js也不能直接使用AIR所提供的一些高级API,比如air.trace().原文的解释在这里 ,Adobe甚至还写了一篇文章来鼓吹这种方式其实更符合设计模式--根页面负责数据传递,iframe页面负责业务逻辑.但是无论如何这篇文章作为Browse sandbox的入门来讲还是很值得细读的

于是结合自己当前的实际需要,我写了一个批量查询airasia.com机票的小工具,因为airasia从来都是打广告说从多久到多久,从那里飞到那里才几块MYR! 就是这个"起"字相当关键......直接造成每次我去查的时候发现因为"已经快满坐"了,所以价格和平时的一样,甚至更高,听同事说他们都是先一天一天去查看哪天便宜就赶快预定,太辛苦了吧,那我要查2007-11-05到2008-01-31日的机票要花多少时间啊,而且不查到最后一天还不知道是不是最便宜的,嘲笑他们原始之后我就决定自己写个工具来查

所以我写的第一个AIR应用就是这个AirAsiaTicketsSearch,可以批量查询某个时间段去和某个时间段回的所有机票,并且把机票价格用jQuery.tablesort给排序出来,并且用jQuery.tablesort.page做了分页(说句题外话,jQuery的tablesort确实很强大,但是在排序"1,280.00 CNY"这种数据的时候还是有问题).另外开发环境值得一说,无论是eclipse+aptana或者aptana standalone都一样的,aptana就是一个Eclipse的RCP,关键就是aptana真的是很好用的工具,目前不仅支持AIR,而且还支持开发Apple iPhone的应用,只是专业版要收费.....

后面给出截图,
结果发现昨天还有295.99的机票,到了今天就涨到349.99了-_-!


posted @ 2007-11-05 20:39 Kerwin Weng 阅读(3792) | 评论 (7)编辑 收藏

几个月前就想弄明白什么是闭包,听名字多神奇,而且犀牛书上好像也没有讲到,baidu出来的结果倒是很多很准确,但是看着那些牛人们翻译的英文文章,讲了上千字我还是没有明白什么是闭包,遇到复杂的地方没法翻译还只能引用原文来解释,本来我的FF受某个插件影响开CSDN不仅慢还会停止响应10多秒,我都是忍痛点下CSDN的连接,结果看到这种垃圾文章真是让人愤怒,写了一大堆,最后还是不能让人明白他到底想要解释什么是闭包,还是炫耀他对技术的理解,还是要满足他对翻译的狂热.

结果今天终于看到一篇Morris Johns的文章,用了不到5分钟就把闭包是什么讲的清清楚楚,比如文章中有一句话:
In JavaScript, if you use the function keyword inside another function, you are creating a closure.

妈的,还有比这更简单的解释吗,为什么那些国内所谓的牛人就是写不出这种平实的话,就非要浪费自己和别人的时间讲一堆貌似浮云的定义,我觉得他们真的该思考下自己写技术文章的目的,是为了在传递知识,还是在满足自己的虚荣,如果是后者,建议直接在Tag中注明"自慰贴",免得浪费大家的时间.

在后面的文章中,作者列举了很多生动的例子,每个例子后面的解释都非常平实,没有任何为了表现自己能力的华丽辞藻,通过他的例子,我很快理解的闭包的特点,可以用来做什么,前后不到30分钟,回想我几个月前光是找合适的解释就找了近一个小时.

当我对闭包的特点已经谙熟于心后,作者再开始讲一些抽象的定义,让人感觉没有一点障碍,就如作者自己的话:
If everything seems completely unclear then the best thing to do is to play with the examples. Reading an explanation is much harder than understanding examples. My explanations of closures and stack-frames etc are not technically correct - they are gross simplifications intended to help understanding. Once the basic idea is grokked, you can pick up the details later.

最后给出那篇文章的地址,相信不懂闭包的人也能像我一样很快就理解,同时也希望大家看完后别忘了别人踏踏实实写技术文章的态度
http://www.javascriptkit.com/javatutors/closures.shtml

posted @ 2007-10-18 13:28 Kerwin Weng 阅读(1575) | 评论 (14)编辑 收藏

最近写AJAX的应用遇到很多需要丰富的Javascript集合的地方,可惜javascript没有Java的Collection那么强大的集合类,于是打算自己尝试写一个模拟Set的API,结果写出来的模拟类和Set有点不同,有一个优势--可以有序取单个对象,但也有一个劣势,就是删除单个对象需要遍历该集合,由于我的应用不大可能用到单个删除,所以我暂时还没有想到一种数据结构可以实现不遍历的单个对象删除,又能满足现有的API都高效完成,如果谁有更好的代码来实现请回复

目前想到可以实现的方法:

add(o);
addAll(array)
contain(o);
get(int);
getAll();
sort(comparator); //传进去的是一个fn,还没有写例子....
size();
remove();
reverse();


基本数据结构是两个数组,一个是index数组,数组下标连续,用来存放第二个数组的下标,另一个是存放对象的数组,不连续,下标是对象的id或者对象中其他任何可以转换成唯一Integer的Field(Set也要求放进去的对象必须要有hashCode嘛,不然没法区别第一个和第二个)

实现的API:
function Collection(){
    this.chain=new Array();
    this.table=new Array();
}
Collection.prototype.get=function(i){
    return this.table[this.chain[i]];
}
Collection.prototype.add=function(o){
    this.table[o.id]=o;
    this.chain.push(o.id);
}
Collection.prototype.addAll=function(array){
    for(var _i=0;_i<array.length;_i++){
        this.add(array[_i]);
    }
}
Collection.prototype.contain=function(o){
    if(this.table[o.id]){
        return true;
    }else{
        return false;
    }
}
Collection.prototype.getAll=function(){
    tempList=new Array();
    for(var _i=0;_i<this.chain.length;_i++){
        tempList.push(this.table[this.chain[_i]]);
    }
    return tempList;
}
Collection.prototype.sort=function(comparator){
    this.chain.sort(comparator);
}
Collection.prototype.remove=function(o){
    var _var = this.chain;
    for(var _i=0;i<this.chain.length;i++){
        if(this.table[this.chain[_i]].id==o.id){
            this.table[this.chain[_i]]=null;
            this.chain.splice(_i,1);
            return;
        }
    }
}
Collection.prototype.size=function(){
    return this.chain.length;
}
Collection.prototype.reverse=function(){
    this.chain.reverse();
}
目前还有一个addAll方法也是暂时没有想到有什么不用遍历的好的实现

前同事提供了一种完全和Set一样的实现,效率满高
function Map(){
    this.obj = {};
    this.count = 0;
}

Map.prototype.put = function(key, value){
    var oldValue = this.obj[key];
    if(oldValue == undefined){
        this.count++;
    }
    this.obj[key] = value;
    return oldValue;
}

Map.prototype.get = function(key){
    return this.obj[key];
}

Map.prototype.remove = function(key){
    var oldValue = this.obj[key];
    if(oldValue != undefined){
        this.count--;
        delete this.obj[key];
    }
    return oldValue;
}

Map.prototype.size = function(){
    return this.count;
}

function Set(getKey){
    this.map = new Map();
    this.getKey = getKey;
}

Set.prototype.add = function(value){
    var key = this.getKey(value);
    this.map.put(key, value);
}

Set.prototype.remove = function(value){
    var key = this.getKey(value);
    this.map.remove(key);
}
Set.protorype.getAll=function(){
    tempArray=new Array();
    for(var i in this.obj){
       tempArray.push(i);
    }
    return tempArray;
}

Set.prototype.size = function(){
    return this.map.size();
}

还有一个朋友的实现和我最初的差不多,但是remove方法相当有创意,用正则表达式来删除
Collection.prototype.remove=function(o){
    var _var = this.chain;
    this.table[o.id]=null;
    var re = new RegExp("(^["+o.id+"]$)|(^["+o.id+"][,])|([,]["+o.id+"]$)","g");
    var s = "["+this.chain.toString().replace(re,"").replace(","+o.id+",",",")+"]";
    this.chain=eval(s)
}

有人回复说需要添加做验证,我觉得不必了,如果添加的值和之前的一样就直接替换好了,如果希望不被replace,直接在添加新对象之前用contain判断一次就可以了,毕竟在我的实现中已不是完全在模拟Set了,目前更倾向于设计一个更高效和强大的集合类

posted @ 2007-10-12 11:46 Kerwin Weng 阅读(3534) | 评论 (2)编辑 收藏

使用AJAX不可以跨域一直是一个麻烦的问题,
最近做AJAX框架时发现一种方法,不仅可以跨域,而且相比XHR可以省去很多解析XML的步骤,
后来居然发现GoogleMap的API就在用,非常惊喜,赶快分享一下

test.html
<html>
<title>Dynamic Script Object</title>
<head/>
<body>
 <div id="jsArea">
  <script id="js" src=testa.js></script>
 </div>
 <br>
 <input type="button" value="test" onclick="testSrc()">
</body>
</html>
<script>
//author:Kerwin.Weng
//mail:hunteva@163.com
 function testSrc(){
  var jsObj = document.getElementById("js");
  var body = jsObj.parentNode;
  body.removeChild(jsObj);
  jsObj = null;
  var newJS=document.createElement("script");
  newJS.id = "js";
  newJS.src = "testb.js";
  body.appendChild(newJS);
  jsArea.innerHTML="Asynchronous"
 }
 var jsArea = document.getElementById("jsArea");
</script>

testa.js
document.write("This is A");

testb.js
setTimeout(function(){jsArea.innerHTML="This is B,now imagine i'm a servlet";},100)

测试结果表明可以在不刷新页面的情况下更新jsArea中的内容,如果我们把testb.js换成一个servlet会怎么样
那不是可以在serverside直接写数据或function给client用了吗,完全不需要XHR来中转,省去了不少麻烦,而且还可以实现跨域访问

但是有两点要注意,testb.js用document.write没有作用,如果不用setTimeout,会直接让我的IE7和IE6crush,具体原因不明,有牛人知道请告诉我
目前在FF2.0.0.4/Opera9.2/IE7/IE6下测试通过.

由于找了好久都不知道这种方式的官方名称,并且很明显这不Asynchronous JavaScript and XML,这里连XML和XmlHttp的影子都没有,
所以为了称呼方便我暂时叫它DSSO(DynamicSwitchScriptObject),当然这不是我发明的,Google不知道用了多久了,如果你知道准确的名字请麻烦告知我

现在我们比较下AJAX和DSSO的特点:
AJAX DSSO
跨域访问 不支持 支持
异步操作 支持 支持(body.appendChild后不需要等到完成才会继续,当然完整的异步访问需要另外的pattern来支持)
数据载体 XML或JSON或TEXT 可以直接由server写成Javascript
操作复杂性 需要解析XML或JSON 可以直接使用

目前暂时想到这么多可以比的,期待大家的讨论

posted @ 2007-06-13 23:06 Kerwin Weng 阅读(3780) | 评论 (7)编辑 收藏

我不得不承认,我从来没有想象过同事会对我这么的好.

cy知道我一个人刚来,家里没有Internet,没有TV,一个人在家会闷出病来,说周六正好是我生日,到时候带我去KL的downtown逛逛,
可是后来这个计划搁浅了,因为hh,ps,lp的加入,cy决定组织大家去附近的Putra jaya去运动运动.....

在离公司不远的一个叫公主城的地方,我们吃着晚饭,计划着第二天的安排,谁知道居然聊到了23点,我们吃了好大一堆东西,好消息是我发现我吃海鲜不会过敏了:D,而且我决定要学广东话啦~~~~~~因为使用范围实在太广了,有中国人的地方就会有人说.......

于是生日这天我起的很早,到公司楼下等hh来接我,hh载着lp来,我们又一起去接cy,然后和ps汇合,他们说20分钟左右的车程,原来好远,换成是在国内糟糕的交通状况,肯定不止一个小时,吃过早午饭(已经10点左右了),5人挤上ps的车前往Putra jaya

比我想象的近,也可能是马来公路又宽,车又少,交通灯也少的原因,车速很快,我们很快就来到了马来西亚政治宗教中心,一个花了全国纳税人的钱,但是不准华裔入住的城市Putra jaya,

先是去一个叫Botani的植物公园,因为在马来西亚几乎人人都有车,路上根本没有给行人走的路,也没有看到街上有自行车,所以他们很想骑自行车,所以来自自行车王国的我,肯定算是他们中的高手了:D

马来西亚的太阳真的好晒,事实证明我后来又被晒伤了.....不过没有在惠州严重.........但是我们玩得很开心;

之后,我们去附近家乐福吃饭,让我惊讶的是,他们居然去给我买了一个小小的蛋糕,上面还插有一根蜡烛为我庆祝生日:) 满感动得,原来之前关于友谊的某些想法是我错了,不过我很高兴发现我错了;

cy真的好厉害,是个人都会羡慕她的,比我还吃得多,一点都不胖,瘦得可以媲美日本明星.....ps很是自豪地介绍他家的蛇宠物,听得我背后直冒冷汗;

饭后,在太阳比较和蔼后,我们去一个湖边划船,我和cy坐的叫kaya,类似皮划艇,不过是塑料的,船底还故意设计了一个洞,虽然不会沉,但不停涌入的水却让我第一次穿的亚麻休闲库和内裤都湿透了......好在我们脱了鞋的

划到湖中间,我们还把两艘船靠在一起,在湖中品尝着在家乐福买的烤鸡....感觉真的很像回到了学生时代:D

没有过多久,起风了,现在应该是马来的雨季吧,每天都会在下午下一场雷阵雨,我来的时候正好还穿过了雷阵雨云....我和cy赶快划向岸边,ps,hh,lp的大船来不及驶到岸边就被迅速增强的大风吹到了湖的另一边,还好马上有人驾快艇前去救援....

我和cy回到岸边,她走在鹅卵石的湖边如履平地,我一下船,踩到地面就痛得走不动,看来身体真的越来越不好了.....差点没有爬在地上....

之后我们又去了Putra jaya的马来全国最大的回教堂,居然说在做礼拜,不准中国人进,好不容易等到可以进了还要我们穿上一个黄色的雨衣才可以,我们干脆作罢;

之后在回程的路上我们都睡着了,所以本来说我要请大家吃饭的计划也推迟了...

hh送我回家,洗了澡,换了衣服,一个人出去大排档,吃了一盘4.5RM的椰浆饭作为我24岁的生日晚宴,还拍照留恋.....一个人在异乡的确会寂寞,但正是这些很好的同事们让我过了一个非常有意义的生日,吃了一个巨好吃的身体蛋糕,第一次划kaya........

晚上收到来自最爱的祝福和礼物,幸福得不得了,应该说我的这个生日算是精彩了,但是如果我的生日愿望也实现的话,就更好了:D

图片地址:http://www.blogjava.net/hunteva/gallery/21931.html

posted @ 2007-04-23 17:32 Kerwin Weng 阅读(293) | 评论 (0)编辑 收藏

在珠海过夜,第二天早从澳门搭亚航的AK51到KL

很辛苦的过程,尤其一大早在澳门通关,我7点30到,因为是周一,所以耗费了整整一个小时才上了出租车;
好在澳门很漂亮,而且天气好得出奇,阳光灿烂的可以把我晒伤,没想到小时候在课本上不知道怎么读的澳凼大桥十多年后我也有机会从上面经过;

澳门机场小得可以,但是却很方便,值机柜台的一个姐姐是中葡混血,不会中文,但是好好好漂亮.....有照片,可惜忘了带AS-10,A701拍的一点都不清楚

辛苦是值得的,因为亚航的AK51是新飞机--A320,因为是单一仓位,所以看起来很干净整洁,因为是廉价航空,没有仓位限制,我挑了个倒数第二排靠窗的位置,是看风景的绝佳位置,我是说机外和机内 :D,空姐是两个马来混血,一个华裔,都还算漂亮--至少个人认为;这架新A320的冷气超好,空调出风口还冒着白烟,亚航机上不提供免费食物的,但是买的价格也不贵,就几块马币,纪念品也顶多几十块,这点让我很惊讶,我买了一顶亚航的棒球帽,因为没有带墨镜...

早就听说澳门机场是从海里起飞,从窗外看去很有趣,飞机先滑行到离登机楼很远的海上跑道,没有过多久就开始加速起飞,加速感比南航的老737强很多,整个人都被重力加速度压在座椅上,机尾刚离开地面不到20米,飞机就一个起码是45度倾斜的右转,吓了我一跳,因为很少有飞行员会在还没有爬行到一定高度之前就做这种会减少浮力的动作,而且高度太低了,如果有什么闪失,根本没有补救的机会,估计只有对驾驶技术和飞机有充分信心的飞行员才敢这样做吧

起飞几分钟后,飞机掉头还路过了昨天我降落的珠海机场,看到有飞机正在起飞,从高空看飞机起飞真的更有意思;果然,飞机起飞后的半小时内一直在爬升,看来也是要飞到国际航线的高度才会平飞.

中途在机上和空姐聊天,还拍了照,她们都很亲切,华裔空姐还会说华语,我要一杯咖啡,她递给我后,翘起嘴并竖起4根手指(4.00RM)的样子真的很可爱,让我想起了野蛮女友 :-)

更有趣的是,A701收得到GPS信号,而且信号超好,收到了10颗星,而且信号很强,好在我有亚洲地图,飞机经过了哪个海岛,哪个国家的哪个城市我全部可以从地图上找到对应,并且实时知道飞机的高度,速度,方向,位置,这种体验真的是很过瘾......

记下自己的坐标,留作以后纪念:
N 17,22'37.8''
E 112,33'47.5''
高度:11658m
方向:NE 216
速度: 790 km/h

在飞到马来西亚靠近KL上空,我从舷窗外看到我们的右后方有另外一架亚航的红飞机也跟着我们一起飞,并且慢慢并入我们的航道,看来它要飞我们后面,跟着我们一起降落;

3点到KL,暴雨,飞机在雷雨云中穿行,颠簸,从来没有遇到过这么厉害的颠簸和振动,以前如果飞行中遇到了气流,还觉得抖动起来会更有趣,
这次真的不觉得好玩了,我都下意识的检查了几次自己的安全带,心里想着迫降和经济着陆的姿势,不过好在机长的水平十分的高超,飞机一直缓慢的匀速下降,没有突然降低和左右转的感觉

终于穿出云层了,看到地面的景物是那么清晰,飞机以非常平稳的姿态在LCCT着陆,滑行,我下机之前,那架跟随我们的亚航飞机也降落了,效率满高的.

LCCT也是一个廉价机场,下机后要自己走去入境大厅,之前机上的华裔空姐还提前去为我们开门,看来亚航的服务真是做的到位,

通关很快,海关简单问了我几句,我的两个大包一个都没有检查就放行了....换钱,买taxi的车票,前往Puchong.....


 

照片在这里

http://www.blogjava.net/hunteva/gallery/21904.html


posted @ 2007-04-23 12:29 Kerwin Weng 阅读(394) | 评论 (1)编辑 收藏