Adobe Apollo 初步研究
这几天在一家公司实习,上班不安逸,还是在学校好玩,才去的时候老板叫我学一下Flex,昨天又叫我去关注一下Apollo.正在郁闷,又学这个又学那个的.当我了解到Apollo技术的时候,就被他深深的吸引了.下面是网上对Apollo的一些评论,然后我会讲解一个使用apollo做一个简单记事本的例子.
时下,关于Apollo的消息被炒得沸沸扬扬。其实结合部分国内外blogger的探讨,我认为,Apollo的革命并非技术上的,而是商业上的。Apollo的技术封装让现有的技术得到了极大的保留,设计师和开发工程师们可以方便地将自己的代码平移到新的平台上,并且发布、部署的方式比之前的任何一款开发工具都方便得多。
Apollo带来的革命,号称“Desktop2.0”。其内容从Flash, HTML/CSS/JS, 到PDF,几乎涵盖了时下最“流行”的Web内容载体。此外,“可离线”应用模式能让用户更加安全、舒适的进行工作和娱乐。用户们不必再抱怨因网络故障而造成的信息损失了,而且也可以借助本地资源更好地节省带宽和其他“紧张而充满麻烦”的网络资源。
把Web2.0应用搬回家,估计会让Apollo的Start-up们又有不少copy case可以做了。从商业的角度来讲,Apollo创造的价值远胜于给用户带来用户体验上的提升。对于终端用户来说,他们想要获得一份Web-Desktop应用,都要经过下载、安装、建立连接的过程,他们不会关心你的程序是由什么开发的。站在产品的角度上,只要能进入桌面,文件系统的支持以及本地各种服务、应用的支持都不是问题,更有许多成熟的框架和接口能让UI层直接调用GPU指令来构建绚丽的应用。然而,Apollo应用却让以往只属于.net/Java/C++程序员和企业能达到的目标对于一名普通的WebDeveloper或者一家小型的网站来说也“易如反掌”!多年以来旁人对WebDeveloper比.net/Java/C++程序员差的舆论必然会得到缓解?抛开一些“浮躁”、“效率不济”等Web程序员和Web产品的“通病”不谈,Web应用的一大优势是:其产品往往是各类软件产品中面对用户群最多、最广,变动频率最高的产品。优秀的Web产品的用户体验必然是经得住考验的,尤其是此类产品往往都拥有较高的“用户体验开发效率”,即单位时间工作成本增量所带来的用户体验提升会更高。
Apollo的价值在于,大大地提高了产品Designer和Developer的“开发体验”,从战略角度来讲,Apollo应用将会有更广大的开发者基础。
对于采用Apollo应用程序部署产品线的企业而言,桌面应用程序更是避免了Marketing中的“Clutter”问题:一部分通过习惯使用搜索引擎来寻找服务的用户不会再被搜索引擎“领到”一个“满是您竞争对手的结果列表页”了,这样您的用户发现您的同行业竞争对手的机会就会大大降低。
除了不如直接在页面中打开方便、下载后的安全隐患之外,Apollo也有很多其他的争议。其中最“有趣的”的无外乎,有人认为Apollo并非直接与微软为敌,而是与Firefox3竞争……
以上信息来自于
Apollo:
http://www.awflasher.com/blog/archives/834
开发的商业前景及革命(上)
到底什么是Apollo呢?
我迫不及待的download了关于Apollo 开发的一系列资源,其中包括:
apollo runtime,
apollo_win_alpha1_031907.msi
apollo sdk,
apollo_sdk_alpha1_031907.zip
flex extensions for apollo,
fb_apollo_extensions_win_alpha1_031907.exe
这3个是最重要的吧,其实sdk可以不用,但我做了一个记事本的例子用到了他.
当然Flex Builder 2也是需要的,当然你也可以选择eclipse,但我觉得还要配置,麻烦死了.
所有东西都可以从adobe官网上免费下载,现在版本是alpha1.
当你安装了
fb_apollo_extensions_win_alpha1_031907.exe后,就可以在FB2上开发apollo应用程序了,我做了一个简单的记事本程序,给大家瞧瞧.
在fb2中新建一个apollo project就可以开始了.整个界面用mxml来搭建,是不是很爽,这用我们可以做出很漂亮很漂亮的界面来.
记事本的编辑框我用的<mx:TextArea>这个东西直接支持右键菜单(复制粘贴剪切删除),而apollo到目前这个版本并没有给出menu和toolbar之类的组件,不过在desktop2.0可以不需要这些东西了吧.
现在的关键问题是我们如何打开和保存一个文件,幸运的是在这个版本中,adobe已经给出了file io api,在adobe提供的Apollo for Adobe Flex Developers一书中第4章做了较详细的介绍.我也简单说一下,如果想做更多的了解请参见:
我们需要声明一个File对象,他将引用一个文件,这和java,c#
的方式很相似
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4fd96b3cf02f4c7b5c8964ac8167f7af.gif)
这个函数的作用是从文本文件中读出文本,参数name是文本文件的路径.file的声明是
var file:File = File.appResourceDirectory;
File.appResourceDirectory引用了一个默认的目录,这是在该工程的bin目录下.如果在resolve中只给出了文件名,那么他将在这个默认的目录下查找该文件.其中还包括了:
File.appResourceDirectory : application被安装到的目录
File.currentDirectory : 顾名思义不翻译了
File.desktopDirectory : 同上
File.documentsDirectory : 上边讲过,是文档文件夹
File.userDirectory : 这是用户的home directory 例如在Mac OS上是 User/
File.currentDirectory : 顾名思义不翻译了
File.desktopDirectory : 同上
File.documentsDirectory : 上边讲过,是文档文件夹
File.userDirectory : 这是用户的home directory 例如在Mac OS上是 User/
然后,我们在初始化了一个FileStream对象, FileStream打开文件.
stream.open(file,FileMode.READ);
第2个参数说明了打开方式,其中包括:
FileMode.APPEND 只写模式,所有被写的数据都会附加到文件的最后 Upon opening, any nonexistent file is created.
FileMode.READ 只读模式,file必须存在 (missing files are not created).
FileMode.UPDATE 读写模式,数据可以写在文件的任何位置或者附加到尾部。Upon opening, any nonexistent file is created.
FileMode.WRITE 只写模式,如果文件不存在,将会创建新的文件,如果存在将会被覆盖
FileMode.READ 只读模式,file必须存在 (missing files are not created).
FileMode.UPDATE 读写模式,数据可以写在文件的任何位置或者附加到尾部。Upon opening, any nonexistent file is created.
FileMode.WRITE 只写模式,如果文件不存在,将会创建新的文件,如果存在将会被覆盖
于是调用stream.readUTFBytes可以按UTF-8编码读取文件.
最后stream.close();
这个没什么好说的,和java,c#都一个样子.
同理还需要一个写文件的函数
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4fd96b3cf02f4c7b5c8964ac8167f7af.gif)
现在我们来用这2个函数来做一个简单的记事本.
这里有一个问题,我们需要一个对话框,用来保存和打开文件.在apollo sdk中提供了这样的组件,打开apollo_sdk_alpha1_031907.zip/samples/Apollo Components,其下包括
DirectorySelectionPanel.mxml
FileOpenPanel.mxml
FileSavePanel.mxml
把后面2个添加到我们工程中(当然也可以直接粘代码),或许你需要做一写修改,比如把一下英文名字该成中文的,不过在apollo中显示中文效果不大理想.另外,还需要一写更改
[Bindable]
public var extensionFilterInfo:Array =
[
{ label: "All files", data: null },
{ label: "Flex files", data: [ ".mxml", ".as" ]}
];
public var extensionFilterInfo:Array =
[
{ label: "All files", data: null },
{ label: "Flex files", data: [ ".mxml", ".as" ]}
];
这段代码可以在FileOpenPanel.mxml中找到,作用是一个Filter,除了有所有文件的选择外,就只能打开.mxml和.as,下面是我修改后的
[Bindable]
public var extensionFilterInfo:Array =
[
{ label: "所有文件", data: null },
{ label: "文本文件", data: [".txt"]}
];
public var extensionFilterInfo:Array =
[
{ label: "所有文件", data: null },
{ label: "文本文件", data: [".txt"]}
];
好了,我们应该怎么使用这2个组件呢.他们都包裹一个静态的函数show,原形如下
public static function show(directory:File = null):FileOpenPanel
{
var panel:FileOpenPanel =FileOpenPanel(PopUpManager.createPopUp(
DisplayObject(mx.core.Application.application),FileOpenPanel, true));
PopUpManager.centerPopUp(panel);
panel.setup(directory);
return panel;
}
{
var panel:FileOpenPanel =FileOpenPanel(PopUpManager.createPopUp(
DisplayObject(mx.core.Application.application),FileOpenPanel, true));
PopUpManager.centerPopUp(panel);
panel.setup(directory);
return panel;
}
看起来有点象Alert.但是我们需要他返回一个文件的地址,应该怎么做呢?
OnClickOpen()函数,我们使用FileOpenPanel.show()显示出对话框,并且获得了他的一个引用,使用addEventListener添加了一个事件监听器,FileEvent定义了事件的类型,其中包括SELECT(选择),CLOSE(关闭),CLOSING,CANCEL.
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4fd96b3cf02f4c7b5c8964ac8167f7af.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
这是打开按钮的
当触发select事件后(就是选中文件点确定),将交给fileOpenPanel_selectHandler函数处理,这和java一模一样.
event.file.nativePath中获得我们选择的文件路径. 剩下的事就是交给readText来处理了.
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4fd96b3cf02f4c7b5c8964ac8167f7af.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
我们可以从
整个程序的关键部分就这些了,save和saveas都和这个差不多.
原代码下载: http://www.cnblogs.com/Files/adamxx/flex0704071150_First%20Apollo.zip