[转载]Android传感器介绍及指南针的实现

mikel阅读(1058)

[转载]Android传感器介绍及指南针的实现 – jowett – 博客园.

Android平台支持的丰富的传感器是其亮点之一,虽然相比iPhone来说稍有逊色,但相对于原来占据智能市场的Synbian等手机平台有一个明显 的飞跃。我们现在看到的旅游出行必备的指南针,甩一甩就显示火苗的模拟打火机都是基于Android内置的传感器。本文主要向大家介绍一下传感器的类型和 调用方法,并根据Android官方实例打造一个纯手工的指南针程序。
传感器类型介绍
Android库中显示的可支持的传感器类型共有11种,但是并不是每部手机都装置了所有的传感器,比如我手头的这款HTC G7就只有5种传感器。这全部11种包括,加速度(accelerometer),磁场(magnetic field),方位角(orientation),陀螺仪(gyroscope),光线(light),压力(pressure),温度 (temperature), 周围物体感应(proximity),重力(gravity),线性加速度(linear acceleration),旋转矢量(rotation vector)。
在接下来的演示的代码中,我们从手机设备中读出所有的的传感器,下面是我的手机里面的传感器设备:加速度传感器(BMA150 3-axis Accelerometer),磁场传感器(AK8973 3-axis Magnetic field sensor),方位角传感器(AK8973 Orientation sensor),周围物体传感器(CM3602 Proximity sensor),光线传感器(CM3602 Light sensor)。

感应矢量的参照坐标系
对于矢量感应,比如方位角,磁场,陀螺仪等等,它们都有自己的参照坐标系,并且都不相同。必须理解它的坐标系,否则从事件中接收到的整数值对我们也是也没有任何用处的。这里以方位角的坐标系为例,参看下所示

把 手机水平放置在桌面上,头部指向北,这时候所有的方位角都是零度。这里提到的北极是地球磁场的北极,与我们日常所说的正北方向之间有一个夹角,就是磁偏 角。那么接下来对应到上图的位置,就是磁场的北方对应的就是Y轴的正半轴,水平方向转过的角度就是正向的极方位角azimuth,范围是【0,360】; 以手机头部为轴,底部向正上抬起,现在的转向是从Y的正半轴转向Z的正半轴,转过的角度就是正向的倾斜角pitch,范围是【-180,180】;以手机 右边为轴,左边向上抬起,现在的转向是从Z的正半轴转向X的正半轴,转过的角度就是正的转角roll,范围是【-90,90】。

辨认它的每种转角的正负有一个简单的方法,从每种转角转动时所绕的轴(或者说与转动方向始终垂直的轴)的负半轴向正半轴 看去,转动的顺时针方向就是正方向。比如,当水平方向有转动时,azimuth的正角度就是从Z轴的副半轴向正半轴望过去的顺时针方向。
指南针应用
编写一个指南针应用其实非常简单,只需要注册方位角传感器,然后获取其中的极方位角azimuth;如果现在极方位角发生偏移,让我们的指示针反方向偏转 同样的角度就可以了。下面的程序代码没有使用图片资源,只是通过画笔paint在界面上的移动来实现指南针的图形。画布的背景是白色,每当极方位角发生移 动时(手机在水平方向有转动),整个画布向反方向移动同样的角度,大家看起来就像是指南针图形在移动。
同时在程序中我们打印出设备配置的所有的传感器,记录在日志中。具体代码,请查看博客原文阅读  http://www.ijowett.com/android-sensor-compass.html

[转载]从SVN迁移到GIT

mikel阅读(985)

[转载]从SVN迁移到GIT – 徐淼 – 博客园.

最近由于代码处在测试阶段,本地需要保留好几个测试分支,原来的SVN用起来不是很方便,于是改用GIT配置管理工具了。留篇日志备忘。

GIT客户端与SVN服务器

原来很多代码还是存在SVN服务器中,所以使用GIT客户端配合SVN服务器是一种不错的选择,即可以体验到GIT的好处,也可以保留原有的SVN数据。

下面是必须要安装的几个软件:

1. Git-1.7.4, 这个是GIT客户端,可以在GIT的官方网站上下载。

2. SVN客户端,只有安装了SVN客户端才能利用Tortoisegit访问SVN服务端,如果不装那就只能访问GIT的服务器了。

3. Tortoisegit , 这个工具为Windows用户提供了良好的GIT操作界面,而且如果习惯了使用SVN的人几乎没有难度。

这几个软件的关系是:Tortoisegit提供了良好的界面操作GIT,底层实际使用Git-1.7.4客户端完成所有GIT功能,并且Tortoisegit依赖SVN客户端来提供将本地GIT管理的数据提交到SVN服务器上的功能。

最好按照上面列出的顺序依次安装,否则需要手动配置一些路径。

这个时候可以在Windows的右键菜单中发现Git Clone这个选项。通过这个选项就可以把SVN服务器上的数据下载到本地,并由GIT客户端进行管理。

image

如上图,从SVN克隆数据必须勾选红框中的CheckBox,然后在填写分支名称,登陆用户名等信息。这个对话框上面一半是用于从GIT服务器上克隆已有项目的。

这样就可以按照一般GIT客户端的方式在本地管理代码,上传到远端服务器时需要在右键菜单中选择SVN Dcommit命令,就可以把代码提交到SVN服务器上了。

全面使用GIT

当然想要发挥GIT配置管理工具的所有特性,最终还是要把服务端也迁移到GIT上来。在Windows系统下配置GIT服务端在网上可以找到很多攻略,这 里就不讲了。由于Windows没有原生支持ssh,所以安装GIT服务器是个比较麻烦的过程。如果只是自己想要试用用一下,可以选择一些公共的GIT服 务器,比如GitHub等。这些平台提供的免费GIT服务器必须要求项目开源,否则必须支付一定费用。如果只是自己玩一下,就用GITHub足够了。

这里面最关键的就是必须要使用PuttyGen工具来生成公有和私有的key,最终要把公有的key上传到GitHub网站上,然后在本地使用私有的key才能通过GIT客户端访问服务器。

[转载]不使用style="overflow-x:hidden"解决iframe横向滚动条问题。

mikel阅读(843)

[转载]不使用style=”overflow-x:hidden”解决iframe横向滚动条问题。 – FireFore.

百度上搜索了一下。发现很多教人去掉iframe横向滚动条都是使用

style="overflow-x:hidden"

这个样式。结果我估计很多人跟我一样,使用了之后发现问题没解决。

后来疯狂搜索。才找到有人提出来了这么个观点:

在设置Frame时,有一属性是scrolling=”yes/no/auto”,IE6的mozilla都支持,但很显然地,IE的开发人员在这个地方懒了一下,他们对auto的理解很不人性化。auto的意思是自动,就是要的时候有,不要的时候没有。但如果设成auto,则在网页过长需要出竖起滚动条时,IE会自动地把水平滚动条也显示出来,哪怕网页完全不超宽。而设成yes时,IE则会一直出竖直滚动条,而不随便出水平条,这差不多是对的。所以如果要用Frame的话,还是要把这个属性设成Yes,这完全是为迁就IE。 mozilla则在任何时候都是对的。

所以,咱们这里的解决方法就是:

scrolling="yes"

以上解决方法只有适用于竖滚动条需要出现,而横向滚动条不需要出现的情况。

[转载].net HTMLParser详细使用说明

mikel阅读(887)

[转载].net HTMLParser详细使用说明 强大的Filter类 解析HTML文档如此简单 – cestarme – 博客园.

背景:

HTMLParser原本是一个在sourceforge上的一个Java开源项目,使用这个Java类库可以用来线性地或嵌套地解析HTML文 本。他的 功能强大和开源等特性吸引了大量Web信息提取的工作者。然而,许多.net开发者朋友一直在寻找一种能在.net中使用的HTMLParser类库,笔 者将介绍Winista.HTMLParser类库,对比于其他原本数量就非常少的.net版HTMLParser类库,Winista的版本的类库结构 可以说更接近于原始Java版本。
该类库目前分为Utltimate、Pro、Lite和Community四个版本,前三个版本都是收费的。只有Community版本可以免费下载并查看所有的源码。

(一)Filter类
Filter一看就知道,肯定是对结果进行过滤,取得需要的内容。HTMLParser在org.htmlparser.filters包之内一共界说了16个差别的Filter,也可以分为几类。
判定类Filter:
TagNameFilter
HasAttributeFilter
HasChildFilter
HasParentFilter
HasSiblingFilter
IsEqualFilter
逻辑运算Filter:
AndFilter
NotFilter
OrFilter
XorFilter
其他Filter:
NodeClassFilter
StringFilter
LinkStringFilter
LinkRegexFilter
RegexFilter
CssSelectorNodeFilter

所有的Filter类都实现了org.htmlparser.NodeFilter接口。这个接口只有一个主要函数:
boolean accept (Node node);
各个子类分别实现这个函数,用于判定输入的Node是否相符这个Filter的过滤条件,假如相符,返回true,不然返回false。

(二)判定类Filter
2.1 TagNameFilter
TabNameFilter是最轻易理解的一个Filter,凭据Tag的名字进行过滤。

下面是用于测试的HTML文件:
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>
<head><meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″><title>新灵感网站自动更新系统-www.xinlg.com</title>& lt; /head>
<html xmlns=”http://www.w3.org/1999/xhtml“>
<body >
<div id=”top_main”>
<div id=”logoindex”>
<!–这是注释–>
新灵感网站自动更新系统-www.xinlg.com
<a href=”http://www.xinlg.com“>新灵感网站自动更新系统-www.xinlg.com</a>
</div>
新灵感网站自动更新系统-www.xinlg.com
</div>
</body>
</html>
测试源代码:(这里只列出了Main函数,全部源代码请参考 HTMLParser使用入门(2)- Node内容,自己添加import局部)
public static void main(String[] args) {

try{
Parser parser = new Parser( (HttpURLConnection) (new URL(“http://127.0.0.1:8080/HTMLParserTester.html”)).openConnection() );

// 这里是控制测试的局部,后面的例子修改的就是这个地方。
NodeFilter filter = new TagNameFilter (“DIV”);
NodeList nodes = parser.extractAllNodesThatMatch(filter);

if(nodes!=null) {
for (int i = 0; i < nodes.size(); i++) {
Node textnode = (Node) nodes.elementAt(i);

message(“getText:”+textnode.getText());
message(“=================================================”);
}
}
}
catch( Exception e ) {
e.printStackTrace();
}
}
输出结果:
getText:div id=”top_main”
=================================================
getText:div id=”logoindex”
=================================================
可以看出文件中两个Div节点都被取出了。下面可以针对这两个DIV节点进行操纵.

2.2 HasChildFilter
下面让我们看看HasChildFilter。方才看到这个Filter的时候,我想虽然地认为这个Filter返回的是有Child的Tag。直接初始化了一个
NodeFilter filter = new HasChildFilter();
结 果挪用NodeList nodes = parser.extractAllNodesThatMatch(filter);的时候HasChildFilter内部直接产生 NullPointerException。读了一下HasChildFilter的源代码,才发觉,实际HasChildFilter是返回有相符条件 的子节点的节点,需要另外一个Filter作为过滤子节点的参数。缺省的结构函数虽然可以初始化,但是由于子节点的Filter是null,所以使用的时 候产生了Exception。从这点来看,HTMLParser的源代码还有很多可以优化的的地方。呵呵。

修改源代码:
NodeFilter innerFilter = new TagNameFilter (“DIV”);
NodeFilter filter = new HasChildFilter(innerFilter);
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:body
=================================================
getText:div id=”top_main”
=================================================
可以看到,输出的是两个有DIV子Tag的Tag节点。(body有子节点DIV “top_main”,”top_main”有子节点”logoindex”。

注重HasChildFilter还有一个结构函数:
public HasChildFilter (NodeFilter filter, boolean recursive)
假如recursive是false,则只对第一级子节点进行过滤。好比前面的例子,body和top_main都是在第一级的子节点里就有DIV节点,所以匹配上了。假如我们用下面的要领挪用:
NodeFilter filter = new HasChildFilter( innerFilter, true );
输出结果:
getText:html xmlns=”http://www.w3.org/1999/xhtml
=================================================
getText:body
=================================================
getText:div id=”top_main”
=================================================
可以看到输出结果中多了一个html xmlns=”http://www.w3.org/1999/xhtml“,这个是整个HTML页面的节点(根节点),虽然这个节点下直接没有DIV节点,但是它的子节点body下面有DIV节点,所以它也被匹配上了。

2.3 HasAttributeFilter
HasAttributeFilter有3个结构函数:
public HasAttributeFilter ();
public HasAttributeFilter (String attribute);
public HasAttributeFilter (String attribute, String value);
这个Filter可以匹配出包括制命名字的属性,或者制定属性为指定值的节点。还是用例子说明比较轻易。

挪用要领1:
NodeFilter filter = new HasAttributeFilter();
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:

什么也没有输出。

挪用要领2:
NodeFilter filter = new HasAttributeFilter( “id” );
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:div id=”top_main”
=================================================
getText:div id=”logoindex”
=================================================

挪用要领3:
NodeFilter filter = new HasAttributeFilter( “id”, “logoindex” );
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:div id=”logoindex”
=================================================

很简单吧。呵呵

2.4 其他判定列Filter
HasParentFilter和HasSiblingFilter的效用与HasChildFilter类似,大众自己试一下就应该了解了。

IsEqualFilter的结构函数参数是一个Node:
public IsEqualFilter (Node node) {
mNode = node;
}
accept函数也很简单:
public boolean accept (Node node) {
return (mNode == node);
}
不需要过多说明了。
(三)逻辑运算Filter
前面介绍的都是简单的Filter,只能针对某种简单类型的条件进行过滤。HTMLParser支持对付简单类型的Filter进行组合,从而实现纷乱的条件。原理和一般编程语言的逻辑运算是一样的。
3.1 AndFilter
AndFilter可以把两种Filter进行组合,只有同时满足条件的Node才会被过滤。
测试源代码:
NodeFilter filterID = new HasAttributeFilter( “id” );
NodeFilter filterChild = new HasChildFilter(filterA);
NodeFilter filter = new AndFilter(filterID, filterChild);
输出结果:
getText:div id=”logoindex”
=================================================

3.2 OrFilter
把前面的AndFilter换成OrFilter
测试源代码:
NodeFilter filterID = new HasAttributeFilter( “id” );
NodeFilter filterChild = new HasChildFilter(filterA);
NodeFilter filter = new OrFilter(filterID, filterChild);
输出结果:
getText:div id=”top_main”
=================================================
getText:div id=”logoindex”
=================================================

3.3 NotFilter
把前面的AndFilter换成NotFilter
测试源代码:
NodeFilter filterID = new HasAttributeFilter( “id” );
NodeFilter filterChild = new HasChildFilter(filterA);
NodeFilter filter = new NotFilter(new OrFilter(filterID, filterChild));
输出结果:
getText:!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
=================================================
getText:

=================================================
getText:head
=================================================
getText:meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″
=================================================
getText:title
=================================================
getText:新灵感网站自动更新系统-www.xinlg.com
=================================================
getText:/title
=================================================
getText:/head
=================================================
getText:

=================================================
getText:html xmlns=”http://www.w3.org/1999/xhtml
=================================================
getText:

=================================================
getText:body
=================================================
getText:

=================================================
getText:

=================================================
getText:

=================================================
getText:这是注释
=================================================
getText:
新灵感网站自动更新系统-www.xinlg.com

=================================================
getText:a href=”http://www.xinlg.com
=================================================
getText:新灵感网站自动更新系统-www.xinlg.com
=================================================
getText:/a
=================================================
getText:

=================================================
getText:/div
=================================================
getText:
新灵感网站自动更新系统-www.xinlg.com

=================================================
getText:/div
=================================================
getText:

=================================================
getText:/body
=================================================
getText:

=================================================
getText:/html
=================================================
getText:

=================================================

除了前面3.2中输出的几个Tag,其余的Tag都在这里了。
3.4 XorFilter
把前面的AndFilter换成NotFilter
测试源代码:
NodeFilter filterID = new HasAttributeFilter( “id” );
NodeFilter filterChild = new HasChildFilter(filterA);
NodeFilter filter = new XorFilter(filterID, filterChild);
输出结果:
getText:div id=”top_main”
=================================================

(四)其他Filter:
4.1 NodeClassFilter
这个Filter用于判定节点类型是否是某个特定的Node类型。在HTMLParser使用入门(2)- Node内容中我们已经了解了Node的差别类型,这个Filter就可以针对类型进行过滤。
测试源代码:
NodeFilter filter = new NodeClassFilter(RemarkNode.class);
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:这是注释
=================================================
可以看到只有RemarkNode(注释)被输出了。

4.2 StringFilter
这个Filter用于过滤显示字符串中包括制定内容的Tag。注重是可显示的字符串,不可显示的字符串中的内容(例如注释,链接等等)不会被显示。
修改一下例子源代码:
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>
<head><meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″><title>新灵感网站自动更新系统-title-www.xinlg.com< /title>& lt;/head>
<html xmlns=”http://www.w3.org/1999/xhtml“>
<body >
<div id=”top_main”>
<div id=”logoindex”>
<!–这是注释 新灵感网站自动更新系统-www.xinlg.com –>
新灵感网站自动更新系统-字符串1-www.xinlg.com
<a href=”http://www.xinlg.com“>新灵感网站自动更新系统-链接文本-www.xinlg.com</a>
</div>
新灵感网站自动更新系统-字符串2-www.xinlg.com
</div>
</body>
</html>

测试源代码:
NodeFilter filter = new StringFilter(“www.xinlg.com“);
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:新灵感网站自动更新系统-title-www.xinlg.com

=================================================
getText:
新灵感网站自动更新系统-字符串1-www.xinlg.com

=================================================
getText:新灵感网站自动更新系统-链接文本-www.xinlg.com

=================================================
getText:
新灵感网站自动更新系统-字符串2-www.xinlg.com
=================================================
可以看到包括title,两个内容字符串和链接的文本字符串的Tag都被输出了,但是注释和链接Tag自己没有输出。

4.3 LinkStringFilter
这个Filter用于判定链接中是否包括某个特定的字符串,可以用来过滤出指向某个特定网站的链接。
测试源代码:
NodeFilter filter = new LinkStringFilter(“www.xinlg.com“);
NodeList nodes = parser.extractAllNodesThatMatch(filter);
输出结果:
getText:a href=”http://www.xinlg.com
=================================================

4.4 其他几个Filter
其他几个Filter也是凭据字符串对差别的域进行判定,与前面这些的区别主要就是支持正则表达式。这个不在本文的讨论范畴以内,大众可以自己实验一下。

请各位站长看看下面>>>

有网站的朋友注意了,我们正在开发一套网站数据自动更新系统. 支持网站信息自动更新,支持深度伪原创,自动网络信息抓取,自动执行计划任务,等任务. 于7月底正式上线,7月10号开始内测,该系统在8月10号之前免费发放200个授权号,有兴趣的朋友可以先加入QQ群:160579517,或关注我,到时免费获取一个注册号,详细请了解http://www.xinlg.com.

[转载].NET简谈脚本引擎系列(一:认识脚本引擎)

mikel阅读(1002)

[转载].NET简谈脚本引擎系列(一:认识脚本引擎) – 南京.王清培 – 博客园.

提到脚本,大家都耳熟能详但是默默无私奉献的脚本引擎都被大家所忽略,本人也是最近才开始接触脚本引擎的技术的,是我的恩师指点我去学习它, 真是不用不不知道,一用吓一跳;如果我们能熟练的使用脚本引擎,那么将大大增加我们系统的灵活性;一开始不太理解这个技术,脚本引擎听起来感觉很厉害,自 从了解了脚本引擎的技术后对一些脚本语言的执行也多了一步的认识,不管是我们B/S中常用的JavaScript、vbscript还是数据库中的 SQLscript我们都可以用类似的方式去理解,我们先从脚本这个名词进行分析,脚本百度定义:[王清培版权所有,转载请给出署名]

脚本(script)是使用一种特定的描述性语言,依据一定的格式编写的可执行文件,又称作批处理文件

脚本本身的定义是可执行体,而脚本语言是用来编写脚本的一种语言,脚本语言是要通过某种东西进行解析后形成可执行体的,这种东西我们暂且将它理解成 脚本引擎;我们就拿数据库来讲吧,我们通常会用SQL来编写一些数据库对象如:存储过程、触发器之类的对象;这些对象通过脚本来描述然后被解析成一个个实 实在在的可执行体,这些可执行体是通过一系列预处理、词法分析、语法分析等编译环节最终形成可执行体;当我们使用的时候能快速的进行调用,这样大大增加了 我们的运行效率;但是我们都忽视了脚本引擎的存在,都以为脚本就是脚本是可以运行的东西;其实有时候我们在学技术的过程中,往往会忽视很多问题,这个时候 真的希望有一些不嫌烦躁的恩师指点迷津,我们不要以自己会哪些技术而骄傲,我们要以自己认识多少恩师而感到幸运,他们的经验,他们在技术的道路上遇到的种 种问题,他们对技术的理解,他们能时刻知道你当前处于什么样的精神状态,当你为了某个技术难点而绞尽脑汁的时候他能无私的帮助你;在这里我感谢我的恩师[袁永福袁老师];

1:

脚本引擎我打算用两篇来讲解本篇只是一个初步的认识,让我们对它的概念有个了解;下面我们的一篇我们将拿示例来演示;

[转载]flex 中子窗口通过事件刷新父窗口中的数据

mikel阅读(1387)

[转载]flex 中子窗口通过事件刷新父窗口中的数据 – IT氧吧 – 博客园.

经常听到有人问子窗口操作完成之后,要刷新父窗口的数据怎么办??有人用过parentDocument;
有人使用过在子窗口中new一个父窗口的对象,然后通过这个对象访问父窗口的方法或属性;
。。。。。

第一种,也可以实现。但是第二种就没法理解了,严格来说子窗口是不能new父窗口的实例的。。。。最好的方法是用事件,今天就弄一个事件的例子吧,大牛们可以不看。新童鞋务必看看,有帮助的。。。。附件可直接下载

运行页面如下

代码如下:
总共3个文件,一个名为Parent的application,一个名为Child的titleWindow,还有一个是自定义的一个事件。
Parent.mxml

<!--?xml version="1.0" encoding="utf-8"?-->


<!&#91;CDATA&#91;                         import mx.collections.ArrayCollection;                         import mx.managers.PopUpManager;                                                  &#91;Bindable&#93;                         public var ac:ArrayCollection=new ArrayCollection(&#91;                                 {name:"周结",sex:"男",age:"23"},                                 {name:"小静",sex:"女",age:"19"},                                 {name:"小二",sex:"男",age:"20"},                                 {name:"大牛",sex:"男",age:"44"}                         &#93;);                          private var child:Child = new Child();                         protected function button1_clickHandler(event:MouseEvent):void                         {                                 PopUpManager.addPopUp(child,this,true);                                 PopUpManager.centerPopUp(child);                                 child.addEventListener(MyEvent.SAVE_OK,saveSuccess);                         }                                                  private function saveSuccess(e:MyEvent):void                         {                                 ac.addItem(e.data);                         }                 &#93;&#93;>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->








源码下载:http://www.ityangba.com/thread-302-1-1.html

IT氧吧-程序员的港湾 http://www.ityangba.com

[转载]一位老程序员的建议

mikel阅读(963)

[转载]一位老程序员的建议 – 职场博客 – 伯乐在线.

导读:原文作者Zed Shaw是一位作家、软件开发人员、音乐人(下文中提到吉他手),于2010年发布《Learn Python The Hard Way 第一版》一书,他也是 Mongrel Web 服务器系统的作者之一。本文是《Learn Python The Hard Way, 2nd Edition》的尾声部分。Zed还分享过《程序员的常见健康问题》一文。

看完了这本书,你决定继续做编程。也许它能成为你的一个职业,也许它能成为你的一项爱好。但你需要一些指导,确保自己不会走错了道路,或帮助你从这个新业余爱好中得到最大的乐趣。

我做了很久的编程。久的你都想象不出来,久的都让我苦恼。就在我写这本书的时候,我大概懂20种编程语言,而且我可以用一天或长点儿用一周的时间学会 一种新语言——要依这种语言有多奇怪而定。但这最终成为了我的苦恼,它们已经不能再吸引我的兴趣。我并不是说这些语言没有意思,或告诉你你会觉得它们很枯 燥。只是想说在我的职业旅程走到现在,我已不再对语言有兴趣。

经过这么多年的学习经历,我发现语言本身并不重要,重要的是你如何用它们。事实上,我一直知道这个道理,但我总是被语言吸引走,周期性的忘记这个道理。现在我不再忘记了,你也应该这样。

你会什么语言、你用什么语言,这并不重要。不要被围绕在编程语言周围的各种宗教宣传迷惑,那些只会遮蔽你的眼睛,让你看不出这些语言只是一种让你做有趣的事情的工具而已。这才是它们的真正属性。

编程作为一种智力活动,它是唯一的一种能让你创造出交互式艺术作品的艺术形式。你创造出来人们可以操作的软件,你是在间接的和人们交互。没有任何其它艺术形式有如此的交互性。电影是单向的向观众传输信息。绘画是静态的。而软件程序却是双向动态的。

编程只能算是一项一般有趣的工作。它可以成为一个不错的职业,但如果你既想多挣钱又要干的高兴,不如去开一家快餐馆。如果你把编程当做一种秘密武器在其它行业里使用,也许会有更好的效果。

科技界科技公司里会编程的人多如牛毛,没人会在意他们。而在生物界,医药界,政府,社会学界,物理界,历史界和数学界,如果你有这种技能,你能做出令人瞩目的事情。

当然,所有的这些话都是没有意义的。如果通过这本书,你喜欢上了编程,你应该尽你最大的努力,通过它来改善你的生活。去探索这神奇的精彩的智力活动,也只有近50年来的人有机会从事这种职业。如果你喜欢它,就尽情的热爱它吧。

最后我要说的是,学习开发软件会改变你,让你与众不同。不论是好的不同还是坏的,反正是不同。你会发现,因为你会开发软件,人们会对你很冷淡,会用 “书呆子”这样的词形容你。你会发现,由于你善于剖析逻辑,人们痛恨跟你辩论。你甚至会发现,只是简单的懂一些计算机原理都会给你带来很多烦恼,让你跟他 们比起来怪怪的。

对于这些问题,我只有一点小建议:让他们去死吧。这世界需要更多的能知道事情如何工作、喜欢去探索的人。当他们这样对待你时,你要记住,这是你的生活,不是他们的。与众不同不是罪恶,人们这样对你只是出于嫉妒,嫉妒你拥有一项他们在梦中都无法拥有的技能。

你会编程。他们不会。这真他/妈的酷毙了。

原文:Zed Shaw
译文:外刊IT评论

[转载]Android关于百度地图定位的使用

mikel阅读(1065)

[转载]关于百度地图的使用 – 网络渔夫 – 博客园.

Android手机上使用百度地图来定位的资料在网上很难找到,经过两天的折腾,终于搞出来了。下面的代码已经实现完整定位,需要注意的就是,如果你的 百度地图的底图未显示出来,请确保你手机能使用GPRS(以移动为例)或WIFI联网,要使用精确定位的话,也必须要打开GPS。下面我们直接上代码,代 码说明,百度里面有,一看就知道:

step1 AndroidManifest.xml文件

 <?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.studio.basf.mapdemo" android:versionCode="1"
     android:versionName="1.0">
     <application android:icon="@drawable/icon" android:label="@string/app_name"
         android:name="MapManagerApplication">
         <activity android:name=".MainActivity" android:label="@string/app_name">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
     </application>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>    
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
     <uses-permission android:name="android.permission.INTERNET"></uses-permission>    
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>    
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
     <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
     <supports-screens android:largeScreens="true"
         android:normalScreens="true" android:smallScreens="true"
         android:resizeable="true" android:anyDensity="true" />
     <uses-sdk android:minSdkVersion="4" />
 </manifest> 

step2 首先建立一个全局应用类,主要是创建一个BMapManager实例,为了方便管理

 package com.studio.basf.mapdemo;
 
 import android.app.Application;
 
 import com.baidu.mapapi.BMapManager;
 import com.baidu.mapapi.MKEvent;
 import com.baidu.mapapi.MKGeneralListener;
 
 public class MapManagerApplication extends Application {
     BMapManager bMapManager = null;
     
     static class MyGeneralListener implements MKGeneralListener {
 
         @Override
         public void onGetNetworkState(int iError) {
 
         }
 
         @Override
         public void onGetPermissionState(int iError) {
             if (iError ==  MKEvent.ERROR_PERMISSION_DENIED) {
                 
             }
         }
     }
 
     @Override
     public void onCreate() {
         // TODO Auto-generated method stub
         bMapManager = new BMapManager(this);
         bMapManager.init("你的key", new MyGeneralListener());
     }    
 }

step3 继承MapActivity,同时实现LocationListener接口

 package com.studio.basf.mapdemo;
 
 import android.location.Location;
 import android.os.Bundle;
 
 import com.baidu.mapapi.BMapManager;
 import com.baidu.mapapi.GeoPoint;
 import com.baidu.mapapi.LocationListener;
 import com.baidu.mapapi.MKLocationManager;
 import com.baidu.mapapi.MapActivity;
 import com.baidu.mapapi.MapController;
 import com.baidu.mapapi.MapView;
 import com.baidu.mapapi.MyLocationOverlay;
 
 public class MainActivity extends MapActivity implements LocationListener {
     private BMapManager mBMapMan = null;
     private MapView mMapView = null;
     private MapController mMapController = null;
     private MKLocationManager locationManager = null;
 
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
 
         mBMapMan = ((MapManagerApplication) getApplication()).bMapManager;
         if (mBMapMan == null) {
             ((MapManagerApplication) getApplication()).bMapManager = new BMapManager(
                     getApplication());
             ((MapManagerApplication) getApplication()).bMapManager.init(
                     "你的key",
                     new MapManagerApplication.MyGeneralListener());
             mBMapMan = ((MapManagerApplication) getApplication()).bMapManager;
         }
         super.initMapActivity(mBMapMan);
 
         locationManager = mBMapMan.getLocationManager();
         locationManager.requestLocationUpdates(this);
 
         mMapView = (MapView) findViewById(R.id.bmapsView);
         mMapView.setBuiltInZoomControls(true);// 设置启用默认的缩放控件
 
         mMapController = mMapView.getController();// 得到mMapView的控制权,可以用它控制和驱动平移和缩放
         mMapController.setZoom(12);// 设置地图zoom级别
 
         MyLocationOverlay mylocTest = new MyLocationOverlay(this, mMapView);
         mylocTest.enableMyLocation();
         mylocTest.enableCompass();
         mMapView.getOverlays().add(mylocTest);
     }
 
     @Override
     public void onLocationChanged(Location location) {
         // TODO Auto-generated method stub
 
         if (location != null) {
             mMapController.animateTo(new GeoPoint(
                     (int) (location.getLatitude() * 1E6), (int) (location
                             .getLongitude() * 1E6)));
         }
    }
 
     @Override
     protected void onDestroy() {
        // TODO Auto-generated method stub
         if (mBMapMan != null) {
             mBMapMan.destroy();
             ((MapManagerApplication) getApplication()).bMapManager = null;
             mBMapMan = null;
         }
         super.onDestroy();
     }
 
     @Override
     protected void onPause() {
        // TODO Auto-generated method stub
         if (mBMapMan != null) {
             mBMapMan.stop();
         }
         super.onPause();
     }
 
     @Override
     protected void onResume() {
         // TODO Auto-generated method stub
         if (mBMapMan != null) {
             mBMapMan.start();
         }
         super.onResume();
     }
 
     @Override
     protected boolean isRouteDisplayed() {
         // TODO Auto-generated method stub
         return false;
     }
 }

因为代码在需要在真机上运行才能看到效果,所以我这里就截图,上面的代码直接复制下来就可以使用。

[原创]万网域名注册和Whois信息查询API

mikel阅读(1191)

1域名check

接口采用HTTPPOSTGET协议:

调用URLhttp://panda.www.net.cn/cgi-bin/check.cgi

参数名称:area_domain 值为标准域名,例:hichina.com

调用举例:http://panda.www.net.cn/cgi-bin/check.cgi?area_domain=hichina.com

返回XML

<?xml version=”1.0″ encoding=”gb2312″?>

<property>

<returncode>200</returncode>

<key>2zher3r3r.com</key>

<original>210 : Domain name is available</original>

</property>

返回XML结果说明:
returncode=200
表示接口返回成功

key=***.com表示当前check的域名

original=210 : Domain name is available 表示域名可以注册

original=211 : Domain name is not available 表示域名已经注册

original=212 : Domain name is invalid 表示域名参数传输错误

2域名info

接口采用HTTPPOSTGET协议:

调用URLhttp://whois.hichina.com/whois/api_whois?host=hichina.com&oper=0

参数名称:host值为标准域名,例:hichina.com

oper为操作值 0=查询whois信息

调用举例:http://whois.hichina.com/whois/api_whois?host=hichina.com&oper=0

返回结果为Json类型:

{“exp_date”:” 24-apr-2019″,”name_server”:” NS3.HICHINA.COM, NS4.HICHINA.COM”,”status”:” clientDeleteProhibited, clientTransferProhibited, clientUpdateProhibited”,”name”:”hichina.com”,”registrar”:”HICHINA ZHICHENG TECHNOLOGY LTD.”,”reg_date”:” 23-apr-1996″,”total_infor”:”\nWhois Server Version 2.0\n\nDomain names in the .com and .net domains can now be registered\nwith many different competing registrars. Go to http://www.internic.net\nfor detailed information.\n\n Domain Name: HICHINA.COM\n Registrar: HICHINA ZHICHENG TECHNOLOGY LTD.\n Whois Server: grs-whois.hichina.com\n Referral URL: http://www.net.cn\n Name Server: NS3.HICHINA.COM\n Name Server: NS4.HICHINA.COM\n Status: clientDeleteProhibited\n Status: clientTransferProhibited\n Status: clientUpdateProhibited\n Updated Date: 25-mar-2010\n Creation Date: 23-apr-1996\n Expiration Date: 24-apr-2019\n\n>>> Last update of whois database: Mon, 20 Jun 2011 05:34:30 UTC <<<\n\nNOTICE: The expiration date displayed in this record is the date the \nregistrar’s sponsorship of the domain name registration in the registry is \ncurrently set to expire. This date does not necessarily reflect the expiration \ndate of the domain name registrant’s agreement with the sponsoring \nregistrar. Users may consult the sponsoring registrar’s Whois database to \nview the registrar’s reported date of expiration for this registration.\n\nTERMS OF USE: You are not authorized to access or query our Whois \ndatabase through the use of electronic processes that are high-volume and \nautomated except as reasonably necessary to register domain names or \nmodify existing registrations; the Data in VeriSign Global Registry \nServices’ (\”VeriSign\”) Whois database is provided by VeriSign for \ninformation purposes only, and to assist persons in obtaining information \nabout or related to a domain name registration record. VeriSign does not \nguarantee its accuracy. By submitting a Whois query, you agree to abide \nby the following terms of use: You agree that you may use this Data only \nfor lawful purposes and that under no circumstances will you use this Data \nto: (1) allow, enable, or otherwise support the transmission of mass \nunsolicited, commercial advertising or solicitations via e-mail, telephone, \nor facsimile; or (2) enable high volume, automated, electronic processes \nthat apply to VeriSign (or its computer systems). The compilation, \nrepackaging, dissemination or other use of this Data is expressly \nprohibited without the prior written consent of VeriSign. You agree not to \nuse electronic processes that are automated and high-volume to access or \nquery the Whois database except as reasonably necessary to register \ndomain names or modify existing registrations. VeriSign reserves the right \nto restrict your access to the Whois database in its sole discretion to ensure \noperational stability. VeriSign may restrict or terminate your access to the \nWhois database for failure to abide by these terms of use. VeriSign \nreserves the right to modify these terms at any time. \n\nThe Registry database contains ONLY .COM, .NET, .EDU domains and\nRegistrars.”,”whois_server”:”grs-whois.hichina.com”}

返回是通过JQuery异步获取的:

function whois_infor(f){
if(f==0 || f==2){
var whois_html = '<img src="/images/loading.gif" border="0" alt="正在查询更多.." width="32" height="32" />正在查询更多,请稍等';
$(".info_text").html(whois_html);
}
var tip_infor = '<span style="line-height: 24px;">域名注册信息为缓存信息,并非实时更新,不可做为该域名可否被注册的依据。
</span>
<div class="info_text_web2"><img style="float: left; padding: 2px 4px 0 0;" src="/images/icon01.jpg" alt="" /><span id="file"> </span> <a class="linkblue_query" style="cursor: pointer;" onclick="lock();">点击查询最新域名注册信息</a></div>
';
var whois_infor_html = "域名注册信息查询超时,请稍后重试或【<a style="cursor: pointer;" onclick="whois_infor(0)">刷新页面</a>】";
$.ajax({
type:"get",
url:"/whois/api_whois",
cache:false,
data:{host:domain_string,oper:f},
dataType: "json",
timeout: 10000,
success:function(data){
if(data){
if(data.hasOwnProperty("error") &amp;&amp; data.error =="hava no permission"){
$(".info_text").html(whois_infor_html);
}else if(data.hasOwnProperty("error") &amp;&amp; data.error =="read timeout"){
$(".info_text").html(whois_infor_html);
}else if(data.hasOwnProperty("space") &amp;&amp; data.space =="space"){
var whois_html="";
//data.hostname='whois.www.net.cn'
if(data.hostname=="whois.www.net.cn"){
whois_html ="<span style="line-height: 24px;">您查询的域名<span class="style1">mikel.cn</span>可能被注册局保留、正在审核或限制注册,暂无域名注册信息";
}else{
whois_html ="<span style="line-height: 24px;">您查询的域名<span class="style1">mikel.cn</span>可能未被注册, 暂无域名注册信息
";
whois_html +="<input checked="checked" type="checkbox" />mikel.cn </span>"+
"请【<a class="linkblue_query" href="http://pandavip.www.net.cn/cgi-bin/Check.cgi?domain=mikel&amp;cn=yes">尝试注册</a>】";
}
tip_infor ="
<span style="color: #ff6600;">友情提示:</span>"+'域名注册信息为缓存信息,并非实时更新,不可做为该域名可否被注册的依据。
</span>
<div class="info_text_web2"><img style="float: left; padding: 2px 4px 0 0;" src="/images/icon01.jpg" alt="" /> <a class="link_bluel" style="cursor: pointer;" onclick="lock();">点击查询最新域名注册信息</a></div>
';
whois_html += tip_infor;
$(".info_text").html(whois_html);
}else if(data.hasOwnProperty("audit") &amp;&amp; data.audit =="audit"){
var whois_html="";
whois_html ="<span style="line-height: 24px;">您查询的域名<span class="style1">mikel.cn</span>可能被注册局保留、正在审核或限制注册,暂无whois信息";
tip_infor ="
<span style="color: #ff6600;">友情提示:</span>"+'域名注册信息为缓存信息,并非实时更新,不可做为该域名可否被注册的依据。
</span>
<div class="info_text_web2"><img style="float: left; padding: 2px 4px 0 0;" src="/images/icon01.jpg" alt="" /> <a class="link_bluel" style="cursor: pointer;" onclick="lock();">点击查询最新域名注册信息</a></div>
';
whois_html += tip_infor;
$(".info_text").html(whois_html);
}else{
var arr = new Array;
arr = domain_string.split(".");
var type = arr[arr.length-1];
var whois_html = '
';
whois_html +='

';
whois_html += '

';
whois_html +='

';

if(data.hasOwnProperty("status")){
whois_html +='

';
}else{
whois_html +='

';
}
if(data.hasOwnProperty("registrar")){
var s = /HICHINA ZHICHENG|HiChinaZhicheng|HiChina Zhicheng|HichinaZhicheng/;
var res = s.exec(data.registrar);
if(res){
data.registrar = "北京万网志成科技有限公司";
}
whois_html +='

';
}else{
whois_html +='

';
}
if(type == "com" || type =="net" || type=="cc" || type=="tv" || type =="tel" || type=="so"){
document.getElementById("type").value = type;
document.getElementById("type_infor").value=data.whois_server;
}
else{
if(data.hasOwnProperty("Registrant_Organization")){
whois_html +='

';
}else{
whois_html +='

';
}
if(data.hasOwnProperty("Registrant_Name") &amp;&amp; data.hasOwnProperty("email")){
if(type == "cn"){
whois_html +='

';

}else{
whois_html +='

';
}
}else{
whois_html +='

';
}
}
if(data.hasOwnProperty("name_server")){
whois_html +='

';
}else{
whois_html +='

';
}
if(data.hasOwnProperty("reg_date")){
whois_html +='

';
}else{
whois_html +='

';
}
if(data.hasOwnProperty("exp_date")){
whois_html +='

';
}else{
whois_html +='

';
}
if(type == "com" || type =="net" || type=="cc" || type=="tv" ||type=="so"){
whois_html +='
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td class="info_text15" width="27%"><strong>域名</strong>
DomainName</td>
<td style="white-space: -o-pre-wrap; word-break: break-all;" width="73%">'+domain_string+'  <a class="linkblue_query" href="http://www." target="_blank">访问该网站</a></td>
</tr>
<tr bgcolor="#F3F3F3">
<td class="info_text15"><strong>域名状态</strong>(<a class="linkblue_query" href="http://www.net.cn/service/faq/yuming/ymzc/200708/2462.html" target="_blank">这是什么?</a>)
Domain Status</td>
<td style="cursor: pointer;">'+domain_status(data.status)+'</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td class="info_text15"><strong>注册商</strong>
Sponsoring Registrar</td>
<td>'+data.registrar+'</td>
</tr>
<tr>
<td class="info_text15"><strong>注册商</strong>
Sponsoring Registrar</td>
<td></td>
</tr>
<tr bgcolor="#F3F3F3">
<td class="info_text15"><strong>注册人公司</strong>
Company</td>
<td>'+data.Registrant_Organization+'</td>
</tr>
<tr bgcolor="#F3F3F3">
<td class="info_text15"><strong>注册人公司</strong>
Company</td>
<td></td>
</tr>
<tr>
<td class="info_text15"><strong>注册人/管理人Email</strong>
Registrant Name/Email</td>
<td>'+data.Registrant_Name+'/'+data.email+'</td>
</tr>
<tr>
<td class="info_text15"><strong>注册人/Email</strong>
Registrant Name/Email</td>
<td>'+data.Registrant_Name+'/'+data.email+'</td>
</tr>
<tr>
<td class="info_text15"><strong>注册人/Email</strong>
Registrant Name/Email</td>
<td></td>
</tr>
<tr bgcolor="#F3F3F3">
<td class="info_text15"><strong>DNS 服务器</strong>
Name Server</td>
<td>'+data.name_server+'</td>
</tr>
<tr bgcolor="#F3F3F3">
<td class="info_text15"><strong>DNS 服务器</strong>
Name Server</td>
<td></td>
</tr>
<tr>
<td class="info_text15"><strong>注册日期</strong>
Registration Date</td>
<td>'+data.reg_date+'</td>
</tr>
<tr>
<td class="info_text15"><strong>注册日期</strong>
Registration Date</td>
<td></td>
</tr>
<tr bgcolor="#F3F3F3">
<td class="info_text15"><strong>到期日期</strong>
Expiration Date</td>
<td>'+data.exp_date+'</td>
</tr>
<tr bgcolor="#F3F3F3">
<td class="info_text15"><strong>到期日期</strong>
Expiration Date</td>
<td></td>
</tr>
<tr>
<td colspan="2">
<div class="linkblue_query" style="cursor: pointer;" onclick="show_hide(1)"><img id="img1" src="http://www.net.cn/static/member/images/icon_open.gif" alt="" /> <strong>查看完整注册信息</strong></div>
<div id="tab1" style="display: none;">
<div class="dbody">
<pre><img src="/images/loading.gif" alt="" />正在查询</pre>
</div>
</div>
<span style="color: #ff6600;">友情提示:</span>按注册局要求,过期域名可能会处于注册商自动续费期阶段,您在此查询所看到的域名到期日仅供参考,
请您<a class="linkblue_query" href="http://www.net.cn/has_client/userlogon/user_logon1.asp" target="_blank">进入会员区</a>查看该域名的实际到期时间,并请及时进行续费,谢谢!
'+tip_infor+'</td>
</tr>
</tbody>
</table>
';
}else{
whois_html +='
<div class="linkblue_query" style="cursor: pointer;" onclick="show_hide(1)"><img id="img1" src="http://www.net.cn/static/member/images/icon_open.gif" alt="" /> <strong>查看完整注册信息</strong></div>
<div id="tab1" style="display: none;">
<div class="dbody">
<pre>'+data.total_infor+'</pre>
</div>
</div>
<span style="color: #ff6600;">友情提示:</span>按注册局要求,过期域名可能会处于注册商自动续费期阶段,您在此查询所看到的域名到期日仅供参考
请您<a class="linkblue_query" href="http://www.net.cn/has_client/userlogon/user_logon1.asp" target="_blank">进入会员区</a>查看该域名的实际到期时间,并请及时进行续费,谢谢!
'+tip_infor+'

';
}
$(".info_text").html(whois_html);
}
}
else{
$(".info_text").html(whois_infor_html);
}
file_date();
},
error:function(data){
$(".info_text").html(whois_infor_html);
file_date();
}}

);
//file_date();
}

[转载]Flex框架Cairngorm2 SequenceCommand用法封装

mikel阅读(1176)

[转载]Flex框架Cairngorm2 SequenceCommand用法封装 – God bless you – 博客园.

概述:

The SequenceCommand is provided as a “psuedo-abstract” (since ActionScript has no real concept of abstract classes) base-class that can be extended when you wish to chain commands together for a single user-gesture, or establish some simple form of decision-based workflow.

By extending SequenceCommand, you can specify the event that should be broadcast to the controller (causing another command execution without a further user-gesture) when the current command has completed execution.

For a command implementing the Responder interface, you may choose to sequence a subsequent command on successful completion of the command, in the onResult() handler, or on failure of the command in the onFault() method.

For commands that do not implement the Responder interface, you can simply chain commands by causing the sequenced command to be invoked as the last action in your command’s execute() method.

一般用法:

1. SequenceCommand实例构造函数中设置nextEvent

2. 对于实现IResponder的Command,在onResult()或onFault()中调用executeNextCommand()来执行下一chain command

3. 对于未实现IResponder的Command,在execute()方法的最后调用executeNextCommand()来执行下一chain command

对于复杂链式命令,封装ChainEvent后的实现:

1. 定义一个ChainEvent,所有需要按顺序执行的事件都继承自该事件。

package xxx.events
{
import com.adobe.cairngorm.control.CairngormEvent;
import flash.events.Event;
/**
*
* ChainEvent,所有需要按顺序执行的事件都继承自该事件
*
* @see com.adobe.cairngorm.control.CairngormEvent
*
*/
public class ChainEvent extends CairngormEvent
{
public static const CHAIN_EVENT:String = “xxx.events.ChainEvent”;
public var nextEvent:ChainEvent;
public var myValue:String;     //测试值
public function ChainEvent()
{
super( CHAIN_EVENT );
}
public override function clone():Event
{
var res:ChainEvent = new ChainEvent();
res.nextEvent = nextEvent;
res.myValue = myValue;
return res;
}
}
}

2. 建立ChainEvent工厂类

package xxx.events.utils
{
import xxx.events.ChainEvent;

/**
*
* ChainEventFactory,chainEvent静态工厂类
*
*/
public final class ChainEventFactory
{
public static function createChainEvent(evts:Array):ChainEvent
{
if ( evts.length < 1 )
return null;
var res:ChainEvent = evts[ 0 ] as ChainEvent;
for (var i:int=0; i<evts.length; i++ )
{
if (i<evts.length-1)
{
var event:ChainEvent = evts[ i ] as ChainEvent;
var nextEvent:ChainEvent = evts[ i+1 ] as ChainEvent;
event.nextEvent = nextEvent;
}
}
return res;
}
}
}

3. 实现Command

package xxx.command
{
import com.adobe.cairngorm.commands.SequenceCommand;
import com.adobe.cairngorm.control.CairngormEvent;
import xxx.events.ChainEvent;

public final class ChainCommand extends SequenceCommand
{
public override function execute(event:CairngormEvent):void
{
var chainEvent:ChainEvent = event as ChainEvent;
trace(chainEvent.myValue);
if (chainEvent.nextEvent != null)
{
this.nextEvent = chainEvent.nextEvent;
this.executeNextCommand();
}
}
}
}

4. 链式ChainEvent派发

var firstChainEvent:ChainEvent = new ChainEvent();
var secondChainEvent:ChainEvent = new ChainEvent();
var thirdChainEvent:ChainEvent = new ChainEvent();

firstChainEvent.myValue = “firstChainEvent”;
secondChainEvent.myValue = “secondChainEvent”;
thirdChainEvent.myValue = “thirdChainEvent”;

var chainEvent:ChainEvent = ChainEventFactory.createChainEvent([firstChainEvent,secondChainEvent,thirdChainEvent]);
chainEvent.dispatch();

最后结果输出:

firstChainEvent

secondChainEvent

thirdChainEvent