May 26, 2010, 9:05 am
第一次用java swing写了套桌面程序,来自动化一些工作上的事情。有人问我为什么不用AIR ,毕竟是比较熟悉的flash开发模式,我的理由是AS 相关的文档处理类库不够丰富,可能这也是AIR 的一个不太好的地方。
熟悉AIR 和swing的人应该知道,AS 这类动态语言在UI编程的效率方面比java 好N多,比如bind非常实用和简便。可是java swing借助一些丰富的类库也能实现类似功能,比如这次要讲的betterbeansbinding,可以实现JList,JTable等swing组件 和java beans的绑定,单向或双向的都行。
举例一段代码
jtb = SwingBindings.createJTableBinding(UpdateStrategy.READ_WRITE, vec, wage_list);
BeanProperty<SJPerson, ?> sjp_name = BeanProperty.create("personName");
BeanProperty<SJPerson, ?> sjp_wage1 = BeanProperty.create("wage1");
BeanProperty<SJPerson, ?> sjp_wage2 = BeanProperty.create("wage2");
jtb.addColumnBinding(sjp_name).setColumnName("姓名").setEditable(false);
jtb.addColumnBinding(sjp_wage1).setColumnName("底薪").setColumnClass(Float.class);
jtb.addColumnBinding(sjp_wage2).setColumnName("技术津贴").setColumnClass(Float.class);
jtb.bind();
它的作用是将
Vector<SJPerson> vec
JTable wage_list
双向绑定,vec是一组beans,在JTable里显示一个row。
更多信息可搜索或者Google code
January 13, 2010, 10:12 pm
终于到了编码阶段,写code大家都熟悉不细讲,有兴趣可以上svn下载jonFTP的代码,带有一些注释应该容易看懂。我这里要谈到的不是如何写code,而是写code的过程。在此之前,有些知识需要提前弄明白(每个AIR 项目都有不同的知识基础,要在编码之前学习,边学边写不是啥好习惯),如FTP协议,命令等。
就我个人来讲,测试驱动和设计图是两条主轴,两条故事线。而设计图应该在测试驱动之前。
设计涂鸦
是UML吗,不一定,设计图主要是为了理清思路,知道哪里抽象,哪里改写。基于这个目的,是不是UML,要不要遵守UML语法并不是问题核心,关键自己要有数,看不懂不行。而设计图也应该先从逻辑层开始,下面是我涂鸦出来的JonFTP 的架构:
这里最重要的就是GLFTPClient,GLProcess和GLGroup:
GLFTPClient代表一个session,管理socket,处理发送和接收字节。
GLProcess代表一个处理单元(将FTP命令分类管理,组织成不同的逻辑单元),是个抽象类,子类都是具体的逻辑单元,比如GLList,就是取得当前远程路径下的文件信息。GLProcess向GLFTPClient发送指令,并分析GLFTPClient获得的字节。
GLGroup,一个特殊的GLProcess,管理逻辑组合,比如批量删除,上传和下载。
这只是一个大致的结构(实际上我都是在草稿纸上画的),反正就一个意思。设计图帮助你理清逻辑层的架构,时时刻刻保证路线正确。
差点忘了,时刻重构来修改设计图。
测试驱动
我不是要讲TDD怎么怎么好,这里只是要提醒,时刻准备好测试你的代码,如果你先有算法,那么就测试算法;如果你有一些单元功能,就准备一个简单的UI来展示一下。反正就是说,时时刻刻要测试你的工作。这样可以尽早发现问题。
January 4, 2010, 10:49 am
假设之前已经有一张列表,描述操作流程(也就是初定下的需求)。下面就可以开始设计程序结构了。我觉得,拉起来就写code并不是多好的习惯,至少脑子里也该有个结构概念吧。
还是MVC
MVC是个永恒经典的结构模型,不光可以脱离UI的束缚,而且可以让人形成一种习惯,就是,没了UI也叫程序,让逻辑决定程序的走向。试想下,如果AIR 项目没有UI那算啥。设计就要先从没有UI开始。这一点,flex和flash做得不是太好,因为程序的开头总是sprite或mxml。
所以说,细化程序结构的第一步就是拆分逻辑层和视图层。拿JonFTP 为例,现在抛弃UI的概念,试想下一个FTP流程该什么样子。登录,上传,关闭。一个主要的流程就是如此。
workflow1
而若干流程的集合就是逻辑层 ,不需要想的太复杂,比如用户该怎么选怎么点,这是视图层该干的事情。
怎么把若干流程揉合在一起
我以前总是到最后才考虑怎么把各个功能综合起来,其实它应该在考虑细节之前考虑。比如上面讲的,登录,上传,关闭是一条路,登录,上传,下载,关闭也是条路,中间的操作可以任意组合而不应该含有冲突。也就是说,无论怎么变化,有几点是肯定的:
登录,关闭一定是一条流程的首尾
中间的操作可以任意变化,且不能相互冲突
流程之前不能有联系(新的session需要用户身份)
于是,我就设计了这么个结构:
准备一个“工厂”,产生,托管和消灭一条流程(Session)
流程以登录操作为开始,以关闭操作为结束
任何操作方式(包括登录和关闭)设计为独立的过程(process),过程之间可能要有联系。不要忘了,过程组合也是过程的一种。
初期我是这么考虑的,到了后来还是出现了一些变化,这是后话。
转换到计算机语言
有了上面的“大白话”结构,就可以用计算机语言(AS 3)来描述了。相应的就是:
准备一个全局的FTPClient类,代表一个session,实例由工厂方法或者工厂类产生。
准备一个树状的继承结构,顶层为CProcess,代表一个过程(向FTP服务器请求并获得数据,解析),子类包括一个CGroup,可以add若干个CProcess,它代表一个过程组合(比如批量删除)。
FTPClient接受CProcess作为输入,执行并处理数据,CProcess以事件方式通知UI执行成功与否。
初期的设计就是如此,不过随着开发的进展,肯定会有修改甚至是推翻。不过都是正常的。这里总结下我的设计步骤 :
拆分逻辑层和视图层
先设计逻辑层
逻辑层以流程(session)为主导,不可依赖用户操作
以书面化形式描述各种流程,并寻找相同点和不同点
转换用计算机语言描述,并形成一个大致的架构
开发过程中不断修改
December 28, 2009, 11:45 am
今天开始系列教程的第一篇了,准备把我自己的AIR 项目 JonFTP 的开发经验 分享下。
调整你的精神状态
今天看了部片子叫《校花我爱你》(《I Love You, Beth Cooper》),我觉得用它来强调我们做事的动力再合适不过了。这部片子强调的一个主题就是“只留青春,不留遗憾”。当你要做一件事的时候,能避开人的惰性,避开世俗的眼光,才能不留遗憾。想做就做吧。
坚定你的想法
当你开始准备一个自己的项目 的时候,初期的准备往往是很重要的。兵马未动粮草先行,用在项目开发上同样适用。拿JonFTP (一个FTP客户端)来说,首先需要考虑,这个项目是用来干嘛的,最好不要让你的概念模糊,不然以后会乱套,直接打击你并使你失去兴趣。所以第一桩事情就是反复对自己讲:这个东西是干嘛使的。目的就是给自己一个继续的理由,给项目一个目标。最好给自己准备一张白纸,写下你对这个项目的理解以及产品描述,贴在你的桌子上。
查看同类产品
你不会牛到发明吧(这样的话不必看下去了),呵呵,不管你的目的是不是抄袭,先看看同类产品。我这里说的看,不是去找源码,要明白的是,编码是后面的事情,初期先把自己当成一个不懂编码的普通用户,查看同类产品的目的。就是来坚定你的想法并核实产品描述的正确性,或者给自己一个直观体验,让描述更加具体。还是拿JonFTP来说,我需要做的就是找找比较有名的几个FTP客户端产品,比如FileZilla,这类成熟的产品往往在用户体验(操作体验)上也是成熟的。要借鉴的就是它的操作体验。你可以拿张纸随便涂鸦,先从简单的开始。还是拿FTP客户端为例,用FTP的操作大体上是:
准备host,用户名,密码连接远端的ftp服务器
连接失败后返回上一步,连接成功后到下一步
显示远端服务器的文件系统
做各种操作
关闭连接
退出程序
当然我的blog上只能用1234的标号,如果自己写的话可以随意的用树的方式组织(因为操作的流程总不可能是流线型的吧,分支合并非常常见),但一定要让自己看懂。不详细不要紧,因为借鉴总是反反复复的。
除了程序还需要什么
这个容易被忽视因为我们是写程序的。为啥要提到这个,我们的用户总不是写程序的吧,那么就需要照顾他们的感受。我觉得开源 项目需要:
官网 — 放你的blog里吧,包括系统介绍,和截图。
用户手册 — 一定要的,不然没人会用,即使你的程序傻瓜到极点,要知道,没有最懒只有更懒的人。
更新Log — 展示每次升级带来的好处。
升级系统 — 最好不要每次都让用户去下载,尽量在程序中集成自动升级(不是强制升级)
留言板 — 给反馈一个通道
December 24, 2009, 4:20 pm
Out of browser是silverlight 3新添加的一个特性,使silverlight 3可以安装 到桌面 ,脱离浏览器 运行。说到这里,熟悉AIR 的哥们儿一定会将它们联系起来。其实它们是不具可比性的。因为Out of browser并不能赋予silverlight操作文件系统的能力,它还是一个基于浏览器 的插件(你可以看成被套在一个看不见的浏览器外壳),该没有的还是没有,比如不能定义安装 位置等等。
silverlight 官网上有个很好的视频 教程,我这里就不贴代码。
另外,基于GoogleTranslater App(以前弄的,见这篇 )我实现了Out of browser,给出几张截图吧,还真的挺像桌面 程序呢。
December 11, 2009, 4:38 pm
这篇是对《AIR update framework入门》 补充,那次忘了对update.xml做个介绍。建议你先浏览下那篇文章。update.xml是部署在服务器上的“更新文件”,简单的将,它是个配置文件,用来告诉你的AIR 程序,比如目前的最新版本号啦,更新文件在哪里啦,还有经典的“what’s new”啦等等。下面是一个例子:
<?xml version ="1.0" encoding ="utf-8" ?>
<update xmlns ="http://ns.adobe.com/air/framework /update/description/1.0" >
<version> 0.2</version>
<url> http://gain-loss.org/wp-content/myprojects/jonftp/JonFTP Client.air</url>
<description>
<![CDATA[
1 Improve siteManager, which now support storing multiple site information
2 fixed some small bugs.
]]>
</description>
</update>
相信也没啥好解释的,基本上这么个结构就能对付大多数需要了。version就是当前的更新版本号,可能会疑惑,更新包的版本号和version是不是一样呢,我个人认为不必相同(最好一样啦),因为更新包是一个打包好(压缩过)的文件,读取它的版本信息不太现实,于是才有这个version节点的出现。description的内容会显示在更新界面的下方,让用户了解下新版本有哪些改动。
其实观察下air update framework ,也算比较简单易用了。如果你打算要点牛X的功能(update的确需要长远的考虑),还是建议要好好的扩展下update.xml,比如针对不同旧版本有不同的升级方案,强制升级等等。
December 10, 2009, 10:56 pm
本来一直认为AIR 对sqlite的操作都是异步的,很悲剧啊,后来看到tv.adobe.com上面一个教程视频的时候才注意到,也可以做同步操作。考虑到网上对这方面的问题论述不是太多(包括livedoc),所以这里有必要说明一下。
如果你有实践过AIR 的sql操作,那十有八九用过SQLConnection和SQLStatement两个类,没错,基本上都是它们来完成sql操作。先来看看SQLStatement.execute这个方法的解释:
In asynchronous execution mode, if the responder argument is not null the specified Responder object indicates the methods that are called to handle the results of the operation. If the responder argument is null, a result event is dispatched if the operation is successful, or an error event is dispatched if the operation fails.
When the statement completes in synchronous mode, or the result event is dispatched in asynchronous mode, the results of the operation can be accessed using the SQLStatement.getResult() method.
里面提到过同步和异步模式对execute的影响。同步模式下,AIR 会在执行数据库操作的时候停止执行代码,在有些情况下这么做很方便,逻辑很清楚。而决定是同步还是异步的开关不在SQLStatement类下,它是由SQLConnection来决定的,看open方法的解释:
The operations of creating and opening the database, as well as all other operations that are performed using this SQLConnection instance (including statement execution and other operations performed by a SQLStatement instance associated with this SQLConnection instance) are performed synchronously when the database is opened using this method. To perform operations asynchronously, open the database connection using the openAsync() method instead.
说白了也简单,SQLConnection决定了同sqlite的连接方式,同时也决定了它们的交互方式。如果说SQLStatement是搬运工,那SQLConnection就是仓库管理员。
December 1, 2009, 10:44 am
AIR update framework 可以让你的AIR 应用程序支持更新,并且已经被AIR 1.5支持。
准备
AIR update framework 已经加入到最新的flex sdk了。我一直用的是flex builder3,sdk是3.0.0,所以需要下载最新的sdk 3.4.0和air 1.5 sdk。上http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3 和http://www.adobe.com/products/air/tools/sdk 分别下载吧。把他们解压到一个文件夹里(不会有覆盖的),这样最新的sdk就弄好了。下面就可以配置到flex builder里,不清楚的可以见这里 。
update原理
说来也比较简单(adobe的framework也不见得多高明),在网站上准备一个update.xml来定义更新的信息,比如最新的版本号和对应的AIR文件。air update framework api 会去访问那个update.xml和现在的版本号比较,如果有更新就下载update.xml定义的air文件并安装,来达到更新的目的。
开始开发
首先我们需要了解下AIR update framework API。打开livedoc ,找到air.update.*,它的API不多,我们主要关注这个,ApplicationUpdaterUI,它所管理的就是update的整个过程和界面。网上有介绍说是用configuration file来定义update过程,这是可以的,不过我发现简单的设置下ApplicationUpdaterUI也有同样的效果。入门嘛当然看简单的。设置的话要关注几个isXXXXVisible样式的public property,它们就是定义某些界面是否可见,比如isCheckForUpdateVisible,就是指一个检查是否有更新的界面是否会显示,如果你想要悄悄的检测而不弹出界面的话就设false。默认的它们都是true。来看看我的代码:
private var _updater: ApplicationUpdaterUI = new ApplicationUpdaterUI( ) ;
private function onLoad( ) : void
{
//updater framework
_updater.updateURL = "http://gain-loss.org/wp-content/myprojects/jonftp/update.xml" ;
_updater.isCheckForUpdateVisible = false ;
_updater.addEventListener ( UpdateEvent.INITIALIZED, onUpdateInitializedHandler) ;
_updater.initialize( ) ;
}
private function onUpdateInitializedHandler( event: UpdateEvent) : void
{
_updater.checkNow( ) ;
}
差点忘了介绍updateURL,它就是前面所说的update.xml(名字可以变)。当air update framework initialized 以后就可以开始check了(方式随你),由于我把isCheckForUpdateVisible设为false,检查更新的界面就不会显示,如果有更新它就会直接弹出提醒页面的。下面?没有啦,air update framework都帮我们做掉了,开始测试吧。
我遇到的几个ERROR
16824:注意下版本号的写法,反正我一开始写了v0.1什么的,好像就报这错误,如果改成0.1这样的标准格式,就没事。
16828:注意了,在flex builder里测试就会遇到这样的错误,安装好了就不会。
December 1, 2009, 9:47 am
最初的话:
利用很多的业余时间炮制出来的,一款基于AIR 的FTP客户端程序终于出炉了。从最初的构思到设计,我花了不少心思来学习和修改,也学到和实践了不少东西。这个过程能让人受益良多。我还希望利用将来的业余时间来继续完善和开发新功能,争取赶上并超过目前主流的FTP客户端工具,很欢迎大家帮忙测试和提出建议,感兴趣的朋友可以发邮件交流。下载和帮助见这里 。
Continue reading ‘[置顶]基于Adobe AIR 技术的FTP客户端’ »
November 23, 2009, 10:16 am
之所以想写这篇,就是想给初学者推开一点门缝,毕竟现在网上的资料比较少,且没有一个阶梯的过程。
AIR 是什么
AIR 是Adobe公司推出的一个产品,一般我们讲AIR,可以指AIR应用程序也可以指AIR运行环境(AIR runtime)。其实它就是这么个东西,将AIR运行环境(也是个程序哦,Adobe制作)安装在操作系统(windows,linux皆可,这就是为什么说它是跨平台的)上,然后AIR应用程序就可以依托AIR运行环境程序而运行了。知道大名鼎鼎的Java吧,它也是有个java虚拟机对于与AIR运行环境。我们说的AIR,其实就是runtime和应用程序的结合体。再多说一个,我们用flex builder或者flash开发的AIR,指的是应用程序,而不是runtime,AIR runtime是Adobe为我们准备的运行环境程序,应该已经安装了的。
为什么要AIR runtime
要知道,不同的操作系统有不同的系统指令,一般我们所有的应用程序都会去调用那些指令,所以应用程序都必须开发出windows版本,linux版本等等来对应于不同的操作系统。而AIR runtime就是一个中介,AIR应用程序向AIR runtime发出指令,AIR runtime再向系统发出指令。于是,只要AIR runtime对于应用程序来说是接口一致就行了。开发者只要开发一套应用程序就能在不同的操作系统上运行了。也可以说,AIR应用程序是一定要依赖AIR runtime的,没有中介传递指令,系统是不会承认的。
AIR API和Flex framework啥关系
AIR开发所使用的API的大部分,是flex framework。也就是说,flex API +一部分API = AIR API。
AIR runtime和flash player啥关系
一般的理解,flash player是浏览器的一个插件对吧。那AIR runtime可以这么理解,它抛弃了浏览器,自己是一套程序再加上flash player,于是它就是一个可以独立运行的桌面程序。这也可以解释上面一个问题,AIR其实就是Flex的全部加上一些桌面程序才有的功能。
AIR开发环境如何搭建
Adobe为我们建立了很傻瓜式的开发方式,flex builder3或者flash都可以编码和编译。
AIR运行环境搭建
依照上面讲的,首先需要安装AIR runtime,到这里 下载。