harry 用air写了个flickr图片上传工具 Shuttle功能非常全,能满足大部分上传功能,界面也非常酷,而且大小非常小,安装出来才900多k,推荐色友们使用它!特别注意的是它是多平台的,在win、linux、mac上都能运行!而官方的客户端只支持win和mac的,并且如果本地图片路径里有中文的话官方上传工具识别不了。。。
AsWing是Harry介绍给我的(鼎力推荐:”)),它是一个开源的flash框架也是OSFlash上的一个子项目,它的结构是模仿Java Swing,如果你对Java Swing很熟的话那用起AsWing一定很容易上手的:)。最重要的一点是,这个框架大部分是我们国人iiley写的,非常佩服他,敢想敢干!AsWing一个特点是可以让我们用纯代码来构造一系列的界面,而且它的体积非常小。最近听Harry说他们正在开发一种客户端缓存组件的技术(只限AS3)叫Flash DLL,据介绍可以把swf大小剪掉90%以上,因为是开源的你也能定制自己的共享库缓存端。相比之下AS3版本的AsWing要比AS2的在效率方面要快许多(因为我只用过AS3版本没有亲身经历过到底有多大的不同,但是依靠FlashPlayer和AVM2性能的提升相信也是无需置疑的,呵呵)。
下面来介绍一些AsWing的教程:
AsWing主页:http://www.aswing.org 不过上面都是英文(面向世界),可能英文不好的朋友看起来有点吃力。
胡矿AsWing教程的blog:http://thiswind.flashseer.org 这个blog从头到尾都是胡矿写的AsWing教程而且是全中文的弥补了缺乏中文教程的不足:),非常的不错,你可能在学习Aswing的同时对AS3也有很大的提高。
Harry的blog:http://harryxu.cn/blog Harry会在他的blog上时不时的发一些他写的AsWing教程,有浅有深,如基本的组件使用,但也有像在使用AsWing时碰到的问题和解决的总结、AsWing一些bug之类的有深度的文章!
Java Swing教程:http://java.sun.com/docs/books/tutorial/uiswing/TOC.html 如我前面介绍的AsWing是模仿Swing的框架,所以一些组件的使用也可以借鉴现有的Java Swing教程:)
随着AsWing的使用越来越普及,一些有质量的教程会相继出现,我也会不断更新这个列表,当然可能其中也包括我的,我会把平时使用过程中遇到的问题和解决的方法都发表在未来的日志中,希望大家始终关注我的blog:)
cheers!
就像许多前辈都指出的“尽量使用接口而不是抽象类”,我从中有所感悟,用我前面举的抽象类的例子来解释一下如何用接口替换抽象类(专门写这篇,是想看看我是不是真正理解了-只有能表达出来的东西才算你真正理解,背诵不算:),呵呵)
不提倡使用抽象类的原因是因为你一旦继承了这个类就是这个类型了(被定义了一种语义),就像前面我举的关于内核的例子,你继承了AbstractBrowserCore,那么它就代表了一种浏览器的内核。因为不管java还是as它们都是单继承的,也就是只有一个父类,父类的定义显然是很宝贵的,不能随随便便的来定义。
我在前面的例子上再举个例子:
像FF和IE都提供了很多不错的插件(ActiveX),这么好的资源不能浪费啊!!!我决定不只是利用其它浏览器的内核,它们的插件我也要!还有其它功能(如书签什么的),我准备把它作成服务。
这些服务包括:
使用其它浏览器的内核,使用浏览器插件,得到浏览器书签等等。
上面每个功能我都用接口来定义:
[code:php]
interface IBrowse
{
function browse(url:String):String;
function back():void;
function forward():void;
function home():void;
}
interface IPlugin
{
function getPlugins():Array;
function invoke(plugin:Object):Boolean;
}
interface IBookmark
{
function addBookmark(b:Object):void;
function getBookmarks():Array;
}
我用一个FFBrowserService来实现前面定义的所有接口(只用FF来举例):
public class FFBrowserService implements IBrowse, IPlugin, IBookmark
{
public ovarride function browse(url:String):String
{
// 调用FF的api
}
.........
// 实现的所有接口方法
..........
}
使用 FFBrowserService类:
public class BrowserApp
{
private var _browserService:Object;
private var _bookmark:Array;
public function set browserService(bs:Object):void
{this._browserService = bs;}
public function init()
{
if(this._browser is IBookmark)
{
var bm:IBookmark = this._browserService as IBookmark;
this._bookmark = bm.getBookmarks();
}
}
public function onBackBtRelease():void
{
if(this._browserService is IBrowse == false) return;
var b:IBrowse = this._browserService as IBrowse;
b.back();
}
public function onEnterRelease():void
{
if(this._browserService is IBrowse == false) return;
var b:IBroser = this._browserService as IBrowse;
checkStatus(b.browse(inputText.text)); //检查http状态
}
public function pluginOnRelease(pl:Object):void
{
if(this._browserService is IPlugin == false) return;
var p:IPlugin = this._browserService as IPlugin;
p.invoke(pl);
}
}
[/code]
像这样用接口而不是用抽象类是不是觉得更加的灵活呢?假设一种浏览器不支持插件,那么可以不用实现IPlugin这个接口。而从语义上来讲,FFBrowserService这个类代表了整个第三方浏览器所提供的服务,而不仅仅是内核而已。
希望我的理解对你有所帮助:)
抽象类就是不能实例化的类,因为它内部的一些抽象方法还没有被实现(你不可能去创建一个连方法内容都没有的类的对象)。
它的作用是,把一些子类共有的方法全部集中在父类(也就是这个抽象类)中,但它还提供一些抽象方法(所谓抽象方法就是没有实现的方法只是声明了一下方法名和参数)子类一定要去实现它们。
问题就在,为什么它要提供这些抽象方法?为什么它自己不实现这些方法?
我简单举个例子,比如说:
我觉得现在的一些浏览器的功能不能满足我,我想做个浏览器自己实现了一些功能,但是浏览器的内核我没有能力来写(能写出来我就是高手啦,哈哈),所以我想调用其它现有浏览器的内核(就像the world做的那样),但是我想做的比它还好,因为the world只能用IE内核,我想IE和firefox的内核都能用(可能还有其它的内核),觉得IE好的用IE内核,觉得FF好的用FF的内核,根据用户的爱好设定。
其它功能部分我都实现了,为了满足我前面的需求我建了一个抽象类:
[code:php]
import flash.errors.IllegalOperationError;
public class AbstractBrowserCore
{
……..
public function someOtherCommonFunction(){….} //一些非抽象公共函数
………
// 抽象方法
public function browse(url:String):String
{throw new IllegalOperationError(”abstract function must be overriden”);}
}
// IE实现类
public class IEBrowserCore extends AbstractBrowserCore
{
override public function browse(url:String):String
{
// 调用IE的api
}
}
// FF实现类
public class FFBrowserCore extends AbstractBrowserCore
{
override public function browse(url:String):String
{
// 调用FF的api
}
}
// 未来浏览器内核的实现类
public class SomeOtherBrowserCore extends AbstractBrowserCore
{
override public function browse(url:String):String
{
// 调用其它浏览器内核的api
}
}
// 调用这些类
public class RunApp
{
private var bcore:AbstractBrowserCore;
public function set broswerCore(core:AbstractBrowserCore):void
{
this.bcore = core;
}
public function onKeyDownEvent(e:Event)
{
var code:String = this.bcore.browse(this.inputText.text);
if(code == 404) outputText.text(”文件未找到”);
else if…..
}
}
[/code]
用户只要设置了他喜欢的内核就可以了,这就是多态的力量!可以随意更换实现,但是主程序更本就不需要有什么改变,就像FF的插件一样,非常灵活,来去自由,容易扩展。
其实像http就是一个非常抽象的协议,我们根本就不关心服务器的后台到底是什么,管它是jsp,php,asp,我们只要能看到我们想看到的就可以了。
不知道有没有解释清楚,呵呵:-)
http://www.zeuslabs.us/2007/08/19/enforcing-abstract-classes-at-runtime-in-actionscript-3/
看了下他关于用AS3实现的Abstract Class,个人感觉这个实现有点麻烦而且有效率的损失。我试着自己写了一个Abstract Class实现:
抽象类:
[code:php]
package jeff.abstract
{
import flash.errors.IllegalOperationError;
public class MyAbstractClass
{
public function MyAbstractClass(self:MyAbstractClass)
{
if(self != this)
{
throw new IllegalOperationError("Abstract class did not receive reference to self. MyAbstractClass cannot be instantiated directly.");
}
}
public function mustBeOverriden1(param:String):void
{
throw new IllegalOperationError("abstract function must be overriden");
}
public function mustBeOverriden2(param:String):void
{
throw new IllegalOperationError("abstract function must be overriden");
}
}
}
实现类:
package jeff.abstract
{
public class MyImplementClass extends MyAbstractClass
{
public function MyImplementClass()
{
super(this);
}
public override function mustBeOverriden1(param:String):void
{
trace("From or1 "+param);
}
public override function mustBeOverriden2(param:String):void
{
trace("From or2 " + param);
}
}
}
未实现抽象类中的方法的实现类:
package jeff.abstract
{
public class NotImplementAbstract extends MyAbstractClass
{
public function NotImplementAbstract()
{
super(this);
}
}
}
运行类:
package {
import flash.display.Sprite;
import jeff.abstract.MyAbstractClass;
import jeff.abstract.MyImplementClass;
import jeff.abstract.NoImplementAbstract;
public class AbstractTest extends Sprite
{
public function AbstractTest()
{
var a:MyAbstractClass = new MyImplementClass();
a.mustBeOverriden1("hi");
a.mustBeOverriden2("world");
// output: From or1 hi
From or2 world
var b:MyAbstractClass = new NotImplementAbstract();
b.mustBeOverriden1("hi");
b.mustBeOverriden2("world");
// throw exceptions
}
}
}
[/code]
我只是在抽象类中要被抽象的方法中写了个异常抛出语句,意思就是如果你没有覆盖它的话,那么在运行的时候调用这个方法就会抛出异常(并不是像他那样在new的时候就检查是否覆盖了抽象方法)。如果对我这个实现有其它看法的话欢迎评论:)
前些时间一直在研究聊天系统,在网上搜了一下,发现了一个不错的开源jabber服务器Openfire。幸运的是这个站点的子项目中有个xmpp actionscript实现 XIFF,真的是踏遍铁鞋无觅处得来全不费功夫,一个站点就包含了我所需要的所有工具:XIFF, Openfire, Smark(一个xmpp java实现),Spark(一个jabber客户端java实现,可以登录gtalk)。
Openfire 配置起来非常容易,它的管理系统对中文支持的很好,操作起来非常直观。而且它还支持自定义插件(我也简单的试了一下,很容易上手),好像还有个red5的插件不过Openfire要装在Windows上才能用。
XIFF 的as2版本相对比较成熟、bug较少,有个外国人对它进行了修改和补充,他在sourcefroge 建了个项目叫“xiffan”我前面找了一下找不到了,不过我共享了一个我本地的拷贝。现在as3用的人都非常多了XIFF 项目也在升级,不过as3版本的始终没有release,但是可以从svn下载到最新的代码,需要对它的代码进行一些很小的改动才能跑起来(不知道现在最新的版本需不需要改了)。
我在用xiff做这个聊天室过程中遇到些问题:
在昵称冲突的情况下,Openfire 没有任何的反映,但是XIFF 代码里有针对昵称冲突的事件,不知道是不是Openfire 的问题。还有个问题就是这个聊天室不处在活动的状态下,Openfire 会自动踢掉在聊天室内的所有成员,不知道有没有办法可以使它不自动踢人。。。-_-!

以后有空的话我会再研究一下 Smark 试试看做个gmail机器人什么的:)
p.s. adobe的Daniel Dura也写了个xmpp actionscript3的实现as3xmpp,不过比较底层,如果要使用的话要自己写一些处理协议的逻辑,我曾经问过他什么时候会有高层次的实现,他表示会在一个月内完成,不过到现在svn上还是没动静。。。