存档

‘Develop & Design’ 分类的存档

发布as-spring 2.4

2010年8月4日 ColorHook 没有评论

ActionScript作为一个编译型(解释+编译)语言,经常需要把一些变量存在外部文件中,如XML文档。但是经常去解析XML文件就不是一件令人愉快的事情,而且变化点不是String, Number等基本类型的话,解析完XML后还要做更多的事情,于是as-spring诞生了。

as-spring是我的一个基于Flash平台的类库,作为一个Ioc反射框架,它在平时工作中给我带来了很多便利。我以前有过几篇博客提到过它:

  1. 在ActionScript中使用简单的Spring框架来实现IOC
  2. 使用Spring来配置RemoteObject
  3. 发布as-spring 2.1

这次升级加入了部分新的特征,用来消除使用过程中遇到的一些不便之处。具体特征如下:

1. 简化基本类型的数据类型定义

以前定义一个Bean都是用<bean>标签来定义,如果我要定义一个String类型的Bean,需要这样来定义:

<bean class='String'>
    <constructor-arg value='This is a String'/>
</bean>

现在可以用<element>标签来定义:

<element value='This is a String' type='String'/>

2. 增加了数组定义

以前定义数组没有好的方法,特别是当数组的元素不是基本类型时。现在可以用<list>标签来定义:

<list id='arr'>
    <element value='true'/>
    <bean>
    </bean>
    <list>
    </list>
</list>
3. 增加了Hash Object的定义

这个功能其实在以前就可以很方便的实现,只是现在加入了一个更符合思维的定义方式:

<map>
    <key name='apple' value='[iPhone,iPad]'>
    <key name='google'>
        <value>android</value>
    </key>
    <key name='ms'>
        <list>
               <element value='XP'/>
               <element value='Vista'/>
               <element value='Win7'/>
        </list>
    </key>
</map>

本来打算加入对flash.utils.Dictionary的定义的,最后还是放弃了,主要是因为暂时没有遇到迫切需要Dictionary的应用场景,如果以后遇到了,可以考虑加入这个功能。

使用ActionScript更新{新浪微博}

2010年8月4日 ColorHook 没有评论

新浪微博作为一个微博应用在国内还是比较流行的,至少我周围的人就有很多是她的用户。由于新浪微博开放了类似twitter的API, 所以有一部分推友使用了twitter至新浪微博的同步脚本,这里我想使用ActionScript来更新一个新浪微博。

通过API来更新新浪微博有一个前提条件,就是需要注册成为sina的开发者,并创建一个应用还获得一个app key。这些不在详述,具体请参考新浪微博官方站点。获得app key后就可以开始使用ActionScript来正常调用相关API了。

这里我没有使用号称相对安全的OAuth方式登陆,而是使用更直接的Basic Authorization来通过验证,下面是完整代码:

//Define parameters
var username:String='新浪微博用户名';
var password:String='新浪微博密码';
var source:String='新浪微博app key';
var API_URL:String='http://api.t.sina.com.cn';  //新浪微博API domain
var status:String='需要更新的状态';
 
//define HTTP request
var encodedCredentials:String=Base64.encode(username + ":" + password);
var authHeader:URLRequestHeader=new URLRequestHeader("Authorization", 
                                               "Basic " + encodedCredentials);
var url:String = API_URL+ '/statuses/update.xml';
var request:URLRequest = new URLRequest(url);
var variables:URLVariables = new URLVariables();
variables.source = source;
variables.status = status;
request.data = variables;
request.requestHeaders.push(authHeader);
request.method = 'POST';
 
//send HTTP request.
var loader:URLLoader=new URLLoader();
loader.addEventListener(Event.COMPLETE, onLoaderComplete);
loader.load(request);
 
//HTTP response
function onLoaderComplete(e){
    trace (e.target.data);
}

这里只用到1个外部类Base64,用于HTTP请求中对用户名密码进行加密,该类可以从as3crypto类库中获得。

下载Base64外部库后,设置好正确的classpath,然后替换相关参数,执行代码来更新你的新浪微博吧。

have fun!

Windows下配置gedit笔记

2010年7月18日 ColorHook 没有评论
下载gedit for Windows

gedit作为Ubuntu默认的编辑器轻便快捷,简单易用,得益于插件机制,扩展起来也很方便。加上Zen Coding的支持,把它作为前端开发的IDE是十分合适的。Windows下的binary版本可以这个网址找到:http://live.gnome.org/Gedit/Windows.

安装Zen Coding插件

Zen Coding是快速开发HTML/CSS的一种方式,如果没听过Zen Coding?这里有介绍,还有Google Code上的wiki。为gedit准备的插件zen-coding-gedit可以从github下载。

安装ActionScript, MXML和GLSL语法高亮插件

gedit集成了很多语言的高亮显示,但是默认没有支持ActionScript,打开as文件或mxml文件却看不到花花绿绿的颜色,这是很难令作为Flash开发者接受的,如果有Flash方面的开发需求,相关的高亮插件可以在 http://conic.se/blog/posts/8/下载。

有待增强的地方
  • 文件关联需要去安装路径浏览exe文件
  • 许多插件无法使用
分类: Develop & Design 标签: ,

辞职之工作杂感

2010年7月11日 ColorHook 3 条评论

这周拿到了离职证明,离开了呆了近21个月的公司BrightCreek, 一家以人为本,以创造力为盈利筹码的高新企业。在过去的1年多,我见证了公司的发展和变更,参与了各种各样的软件项目,写过各种各样的程序语言。

想当初在20世纪五六十年代,那时候的程序被记录在打孔卡片上,我从来没有见过这种卡片,但是听说那时候的程序非常严谨,不仅精简,而且优美,出错极少。因为当时运行程序的代价十分昂贵,有限的主机时间需要预约,所以程序的返工和修改都是不应该发生的。那时候的软件开发如同神话一样充满了传奇色彩。

反观今日,程序的编写不再那么难以进行,打开电脑就可以轻易地进行软件开发,Windows,Mac OS, GUN/Linux各种操作系统下都有成熟的IEDIDE, 软件开发不再那么遥不可及,甚至任何人都可以通过简单的拖拽动作来完成了一个软件界面。但是如今软件的质量不再那么可靠,软件崩溃愈演愈烈,软件垃圾愈来愈多,项目经常被延期,挂起和终止,而造成这一现象的原因却着实令人费解。

我开始回忆在所做项目中自己有用到的语言,印象中有ActionScript, HTML, CSS, JavaScript, PHP, ColdFusion, Java, C#, SQL, 其中JavaScript这块用到的Ajax库有jQuery, Ext, Mootools, Dojo. 想到这里,我也略微知道项目经常失败的原因了:当项目中重要的部分由不称职的人担当着是极其危险的

某种语言出身的程序员会被投入到另一种语言相关的项目中去,这种情况经常会发生,不是发生在别人身上,就是发生在自己身上。刚开始该程序员会本着依赖于原有程序的思维模式去写新的语言,加上不熟悉新语言的API,写出惨不忍睹的程序真是太容易了,更加杯具的是,这个时候要是没有一个老鸟在旁边指正指导,对于该程序员和项目都是一种灾难。从成本价值的角度去分析,这是一次失败的投资战略,程序员花了时间和精力去越过一条陡峭的学习曲线,得到的只是三流的经验;项目在前期表面上进行的顺利,中后期将越来越杂乱,最后变得难以维护。

如果不幸你成为了上面那个程序员,我想说的是:请寻找正确的学习途径,切忌盲目操刀,不求甚解。

项目遇到缺少专业人员的情况时,最有效的对策应该是找一个合适的人。招人简单吗?很不简单。至少从实际效果上看是这样。招一个自己满意甚至准满意的人都是十分困难的。我面过6、7个前端的职位(是能立马做事的那种),却发现没一个合格的,那时候觉得HR真是神了,每次电话请过来面试的人都是服务器端的程序员。而且从招聘网站上,我也发现很多小公司会对某个职位持续地招聘2、3年,这显然是招人难的侧面表现。

如果觉得招人困难的时候就要花时间去培养了。培养简单吗?也不简单。特别是对于小公司来讲,具备软件技能培养能力的人少之又少,,而且这种人都被拉去做事了,哪有时间去培养其他人。而且软件领域里各个层面都充斥着领域专家。要一个Java程序员心甘情愿地去受一个JavaScript程序员的培训很可能就不是一样很顺利的事情。

如果公司缺少优秀的人才就去赶紧招聘,猎头很多时候是不靠谱的,我这么说可能引起了猎头们的不满,那换一种说法,猎头极少时候是靠谱的。如果没有资金和条件吸引优秀的人才,就花时间和能力去培养,如果连培养的时间和能力也不具备,那就等着杯具吧。

分类: Develop & Design 标签:

AIR2对HTML5的支持力度

2010年6月20日 ColorHook 没有评论

html5test是一个测试浏览器对HTML5支持情况的一个web应用。在github上可以看到作者公布的一些测试结果。Adobe AIR2对HTML5, CSS3都提供了增强,我记得用html5test对AIR1.5的测试结果在20分左右,今天再用它测试一个AIR2。demo代码如下:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
					   xmlns:s="library://ns.adobe.com/flex/spark" 
					   xmlns:mx="library://ns.adobe.com/flex/mx"
					   creationComplete="init()">
	<fx:Script>
		<![CDATA[
			import spark.components.Group;
			import spark.core.SpriteVisualElement;
 
			protected var htmlLoader:HTMLLoader;
			protected var htmlUI:SpriteVisualElement;
 
			private function init():void{
				htmlLoader=new HTMLLoader();
				htmlLoader.width=800;
				htmlLoader.height=this.height;
				htmlLoader.load(new URLRequest('http://html5test.com'));
				htmlUI=new SpriteVisualElement();
				htmlUI.addChild(htmlLoader);
				this.addElement(htmlUI);
			}
		]]>
	</fx:Script>
</s:WindowedApplication>

运行后发现得分依然是很低——46分,跟Android 1.6的得分42分差不多,不过跟iPhone, iPod touch的120多的得分来比真是差的很远。Adobe官方有一篇文章讲到了AIR2对HTML, CSS, JavasScript的支持情况以及不支持的个中缘由。

分类: Develop & Design 标签: , ,

使用AIR2录制音频

2010年6月20日 ColorHook 没有评论

AIR2的正式版总算是出来了,前些天SDK也放出来了,于是就鼓捣一下它的一些新特性,其中一个特性就是录制Microphone,本地录制,本地存储,不需要FMS的协助。

为了完成这个录制Microphone的功能,我们需要先做如下事情:

  1. 下载AIR2 SDK并覆盖到Flash Builder的SDK中。
  2. 下载adobe官方用于保存WAV音频的开源库WAVWriter

接下来,新建一个AIR2工程,为了力求简单,本例中只用一个按钮,用于开始录制和停止录制。UI代码大致如下:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
				xmlns:s="library://ns.adobe.com/flex/spark" 
				xmlns:mx="library://ns.adobe.com/flex/mx"
			        creationComplete="init()">
        <fx:Script>
		<![CDATA[
                ]]>
	</fx:Script>
	<s:layout>
		<s:VerticalLayout paddingTop="10" horizontalAlign="center"/>
	</s:layout>
	<s:Button id='controlBtn' label="{controlBtnLabel}" click="clickHandler()"/>
</s:WindowedApplication>

下面开始编写逻辑代码,程序启动后,初始化Microphone, 设置音频文件保存路径。

import com.adobe.audio.format.WAVWriter;
import mx.controls.Alert;
 
protected var targetFile:File;
protected var microphone:Microphone;
protected var recordedData:ByteArray;
 
private var recordFlag:Boolean=false;
private static const START_RECORD:String='start recording';
private static const STOP_RECORD:String='stop recording';
[Bindable]public var controlBtnLabel:String=START_RECORD;
 
private function init():void{
	if(!Microphone.isSupported){
		Alert.show("Cannot find a Microphone");
		controlBtn.enabled=false;
		return;
	}
	targetFile = new File(File.desktopDirectory.nativePath+"/sound.mp3");
	microphone = Microphone.getMicrophone(0);
	microphone.setSilenceLevel(0);
	microphone.rate = 44;
}

然后处理按钮的动作,执行开始录制或停止录制操作。

private function clickHandler():void{
	if(recordFlag){
		controlBtnLabel=START_RECORD;
		recordFlag=false;
		this.stopRecording();
	}else{
		controlBtnLabel=STOP_RECORD;
		recordFlag=true;
		this.startRecording();
	}
}

开始录制时,先删除原有的音频文件,然后监听Microphone的SampleDataEvent.SAMPLE_DATA事件。

public function startRecording():void{
	if(targetFile.exists){
		targetFile.deleteFile();
	}
	recordedData=new ByteArray();
	microphone.addEventListener(SampleDataEvent.SAMPLE_DATA, onMicData);
}
 
private function onMicData(event:SampleDataEvent):void {
	recordedData.writeBytes(event.data);
}

当点击了停止录制时,移除Microphone的事件监听,并使用WAVWriter来生成一个音频文件。

public function stopRecording():void{
	microphone.removeEventListener(SampleDataEvent.SAMPLE_DATA, onMicData);
	saveWAV();
}
 
public function saveWAV():void{
	var wavWriter:WAVWriter = new WAVWriter();
	var stream:FileStream = new FileStream();
 
	recordedData.position = 0;
	wavWriter.numOfChannels = 1;
	wavWriter.sampleBitRate = 16;
	wavWriter.samplingRate = 44100;               
 
	stream.open( targetFile, FileMode.WRITE );
 
	wavWriter.processSamples( stream, recordedData, 44100, 1 );
	stream.close();
}
分类: Develop & Design 标签: ,

控制反转之引导用户

2010年6月18日 ColorHook 没有评论

软件项目为何总是延期,为何总是超出预算,最后产生的却还是烂产品?因素应该是多方面的,但是管理上肯定出了问题。管理是什么?一位朋友跟我说过无非就是三个词:计划、组织、控制。我们有计划吗?有。有组织吗?有。有控制吗?也有。但是控制明显不够。在“客户为王”的大背景下,软件从业者长期受到客户们的间接残害,疲于奔命于客户喜好和需求变化之间,然后还要高喊“拥抱变化”的积极口号。用户的控制太多了。

蔡學鏞老师在一篇博客一流的产品中把产品分成了一流、二流、三流3个等级,从文中可以发现跟着用户的想法来做产品反而只能作出三流的产品,做出一流产品却需要先于用户发现需求。另一位博友的东拉西扯:不要听用户的更是引用了多个例子来说明“听用户的”是多么的危险和有害。

但是,不听用户的又不行,毕竟最终由他们为产品买单。既然付了钱,他们也当然要跟踪产品的进度,于是各自的麻烦就来了,这种麻烦和痛苦在外包公司体现的尤为明显。软件行业是一个知识密集、劳动密集的行业,大大小小的分支领域都存在专家,也都需要专家。所以我觉得要想做好产品,需要和客户达成共同的目标,而具体怎么做不能让用户说了算。因为视觉上我们有专业的视觉设计师,交互上我们有专业的交互设计师,程序上有专业的架构师、前端工程师、后端工程师,即使某些专业人员有缺失,那也有准专业的人可以替代,至少比用户“专业”。所以我们要做的应该是引导用户,以完成高质量的产品为共同目标,而不是让客户牵着鼻子走。

分类: Develop & Design 标签: