<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>戈壁滩上的狗尾巴花 &#187; ActionScript</title>
	<atom:link href="http://liguoliang.com/category/flex/actionscript-flex/feed/" rel="self" type="application/rss+xml" />
	<link>http://liguoliang.com</link>
	<description>戈壁滩上盛开的一坨狗尾巴花</description>
	<lastBuildDate>Wed, 08 Sep 2010 13:03:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>[旧文存档]Flex: Alert 使用总结 Using Alert in Flex</title>
		<link>http://liguoliang.com/2010/%e6%97%a7%e6%96%87%e5%ad%98%e6%a1%a3flex-alert-%e4%bd%bf%e7%94%a8%e6%80%bb%e7%bb%93-using-alert-in-flex/</link>
		<comments>http://liguoliang.com/2010/%e6%97%a7%e6%96%87%e5%ad%98%e6%a1%a3flex-alert-%e4%bd%bf%e7%94%a8%e6%80%bb%e7%bb%93-using-alert-in-flex/#comments</comments>
		<pubDate>Sun, 29 Aug 2010 10:17:14 +0000</pubDate>
		<dc:creator>老李</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Alert]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2010/08/1475/</guid>
		<description><![CDATA[<p>1. 通过Alert强制用户选择.</p>
<p>2. 使用一个方法 Handle多个Alert.</p>


// 弹出Alert
			Alert.show(RM.getString(BUNDLE_ONLINE_TEST, &#34;olt.attempt.warn.remove&#34;), RM.getStr]]></description>
			<content:encoded><![CDATA[<p>1. 通过Alert强制用户选择.</p>
<p>2. 使用一个方法 Handle多个Alert.</p>
<pre class="java" name="code">

// 弹出Alert
			Alert.show(RM.getString(BUNDLE_ONLINE_TEST, &quot;olt.attempt.warn.remove&quot;), RM.getString(BUNDLE_ONLINE_TEST, &quot;olt.confirm.title&quot;),
				Alert.YES|Alert.CANCEL, null, onAlertClose).data = &quot;remove&quot;;
//----------------------统一响应---------------------------------

	// onWarning Close
	private function onAlertClose(e:CloseEvent):void {
		if((e.target as Alert).data == &quot;remove&quot;) {
			if(e.detail == Alert.YES) {
			...
			}else {
				// do nothing
			}
		}else if((e.target as Alert).data == ALERT_ATTEMPT) {
			if(e.detail == Alert.YES) {
				...
			}
		}else if((e.target as Alert).data == ALERT_GO_ON_ATTEMPT) {
			if(e.detail == Alert.YES) {
				...
			}
		}else {
			throw new Error(&quot;无法识别的Alert关闭类型: &quot; + e.toString());
		}
	}</pre>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2010/%e6%97%a7%e6%96%87%e5%ad%98%e6%a1%a3flex-alert-%e4%bd%bf%e7%94%a8%e6%80%bb%e7%bb%93-using-alert-in-flex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex: Setting Datagrid column percentWidth &#8211; 设置Datagrid 列宽度为百分比</title>
		<link>http://liguoliang.com/2010/flex-setting-datagrid-column-percentwidth-%e8%ae%be%e7%bd%aedatagrid-%e5%88%97%e5%ae%bd%e5%ba%a6%e4%b8%ba%e7%99%be%e5%88%86%e6%af%94/</link>
		<comments>http://liguoliang.com/2010/flex-setting-datagrid-column-percentwidth-%e8%ae%be%e7%bd%aedatagrid-%e5%88%97%e5%ae%bd%e5%ba%a6%e4%b8%ba%e7%99%be%e5%88%86%e6%af%94/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 14:31:18 +0000</pubDate>
		<dc:creator>老李</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[DataGrid]]></category>
		<category><![CDATA[DataGrid percentWidth]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2010/08/1447/</guid>
		<description><![CDATA[<p><strong>需求</strong>: 设置DatagridColumn的Percent width</p>
<p><strong>临时解决方法</strong>: 监听Datagrid的CREATION_COMPLETE事件, 在响应函数中重置Column的宽度.</p>
<p><strong>效果</strong>: 参见<a href="http://cutown.com/home/reg.php">http://cutown.com/home/reg.php</a>, 网页内嵌入的Datagrid中, 后两列宽度为首列之外的宽度均分.</p>
<p> </p>]]></description>
			<content:encoded><![CDATA[<p><strong>需求</strong>: 设置DatagridColumn的Percent width</p>
<p><strong>临时解决方法</strong>: 监听Datagrid的CREATION_COMPLETE事件, 在响应函数中重置Column的宽度.</p>
<p><strong>效果</strong>: 参见<a href="http://cutown.com/home/reg.php">http://cutown.com/home/reg.php</a>, 网页内嵌入的Datagrid中, 后两列宽度为首列之外的宽度均分.</p>
<p> <span id="more-1447"></span>
<p><strong>代码</strong>:</p>
<pre class="java" name="code">	/** Datagrid创建完毕后设定Column的宽度. */
	protected function onDGCreationComplte(e:Event):void {
		var columnServerID:DataGridColumn = columns[0] as DataGridColumn;

		for(var i:int = 0; i &lt; columns.length; i++) {
			var column:DataGridColumn = columns[i] as DataGridColumn;
			column.width = width/columns.length; // 重设宽度, 减去首列宽度, 其他列均分.
		}
	}</pre>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2010/flex-setting-datagrid-column-percentwidth-%e8%ae%be%e7%bd%aedatagrid-%e5%88%97%e5%ae%bd%e5%ba%a6%e4%b8%ba%e7%99%be%e5%88%86%e6%af%94/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using crossdomain.xml (Error #2048 Error #2170&#8230;) 使用crossdomain控制跨域访问</title>
		<link>http://liguoliang.com/2010/flex-security-sandbox-error-2048-and-error-2170/</link>
		<comments>http://liguoliang.com/2010/flex-security-sandbox-error-2048-and-error-2170/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 09:05:34 +0000</pubDate>
		<dc:creator>老李</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Error #2048]]></category>
		<category><![CDATA[Error #2170]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2010/08/1440/</guid>
		<description><![CDATA[<p>当试图与某站外URL的进行数据交互时 (如通过URLLoader), 如果目标站点无crossdomain.xml或该文件未允许当前站点的访问, 则会出现#2048, #2170等错误. </p>
<p><a href="http://liguoliang.com/wp-content/uploads/2010/08/image12.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb12.png" width="640" height="547" /></a>     <br /><a href="http://learn.adobe.com/wiki/download/attachments/64389123/CrossDomain_PolicyFile_Specification.pdf?version=1">Cross-domain policy file specification</a> (PDF, 129 KB)</p>
<p> </p>]]></description>
			<content:encoded><![CDATA[<p>当试图与某站外URL的进行数据交互时 (如通过URLLoader), 如果目标站点无crossdomain.xml或该文件未允许当前站点的访问, 则会出现#2048, #2170等错误. </p>
<p><a href="http://liguoliang.com/wp-content/uploads/2010/08/image12.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb12.png" width="640" height="547" /></a>     <br /><a href="http://learn.adobe.com/wiki/download/attachments/64389123/CrossDomain_PolicyFile_Specification.pdf?version=1">Cross-domain policy file specification</a> (PDF, 129 KB)</p>
<p> <span id="more-1440"></span>
<p>关于crossdomain.xml: <a href="http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html">http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html</a></p>
<p>具体的错误信息:    <br />Error #2048: Security sandbox violation: <a href="http://liguoliang.com/NetworkSpeedTest.swf">http://liguoliang.com/NetworkSpeedTest.swf</a> cannot load data from&#8230;. , Or:     <br />Error #2170 : Security sandbox violation: <a href="http://liguoliang.com/NetworkSpeedTest.swf">http://liguoliang.com/NetworkSpeedTest.swf</a> cannot send HTTP headers to <a href="http://api.myspace.com/v1/users/**/mood.xml">http://api.myspace.com/v1/users/<font color="#ff4b33">**</font>/mood.xml</a></p>
<p><strong>解决方法</strong>: 在目标站点根目录下放置crossdomain.xml 跨域访问文件. 最简单的一个, 允许所有:</p>
<pre class="xml" name="code">&lt;?xml version=&quot;1.0&quot;?&gt;

<cross-domain-policy>
  <site-control permitted-cross-domain-policies="master-only" />
  <allow-access-from domain="*" />
  <allow-http-request-headers-from domain="*" headers="*" secure="false" />
</cross-domain-policy></pre>
<p>&#160;</p>
<p><a href="http://api.myspace.com/crossdomain.xml" target="_blank">如: MySpace的API的crossdomain.xml</a>&#160;</p>
<p>另: crossdomain.xml不必一定置于根目录下，参见: Security.loadPolicyFile.</p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2010/flex-security-sandbox-error-2048-and-error-2170/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ActionScript中呼叫JavaScript方法 &#8211; Call JavaScript Function In ActionScript</title>
		<link>http://liguoliang.com/2010/flex%e4%b8%ad%e5%91%bc%e5%8f%abjs%e6%96%b9%e6%b3%95-call-javascript-function-in-flex/</link>
		<comments>http://liguoliang.com/2010/flex%e4%b8%ad%e5%91%bc%e5%8f%abjs%e6%96%b9%e6%b3%95-call-javascript-function-in-flex/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 09:12:59 +0000</pubDate>
		<dc:creator>老李</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Error #1502]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JS]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2010/08/1430/</guid>
		<description><![CDATA[<p><strong>需求:</strong> 在某些情况时, 如某Event响应后, 需要呼叫外部的JS代码以进行有关操作.    <br /><a href="http://liguoliang.com/wp-content/uploads/2010/08/image9.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb9.png" width="584" height="272" /></a> </p>
<p> </p>]]></description>
			<content:encoded><![CDATA[<p><strong>需求:</strong> 在某些情况时, 如某Event响应后, 需要呼叫外部的JS代码以进行有关操作.    <br /><a href="http://liguoliang.com/wp-content/uploads/2010/08/image9.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb9.png" width="584" height="272" /></a> </p>
<p> <span id="more-1430"></span>
<p><strong>步骤:</strong>     <br />1. 在JavaScript中创建JS函数, 用于等待被Flex呼叫     <br />2. 在必要时, AS中可通过ExternalInterface呼叫步骤1中创建的函数.</p>
<p><strong>代码举例:</strong></p>
<p>1. JavaScript代码(放置在Flash所在Html中)</p>
<pre class="java" name="code">/** 当测试结束后会被Flex呼叫到. */
function testCompleted(serverID, speedDownload) {
	alert(&quot;Server: &quot; + serverID  + &quot;, SpeedDownload:&quot; + speedDownload);
}</pre>
<p>2. ActionScript内呼叫JS方法. </p>
<p>呼叫代码为: ExternalInterface.call(&quot;js函数名称&quot;, 参数1, 参数2&#8230;); </p>
<pre class="java" name="code">	/** 当所有网速测试都进行完毕后响应. */
		protected function onMultiSppedTestComplete(e:Event):void {
			log.info(&quot;全部测试完毕&quot;);

			var bestSpeedTester:SpeedTester = multiSpeedTester.getBestServer(); // 测试中发现的最佳服务器

			// 呼叫外部JS函数.
			if(ExternalInterface.available &amp;&amp; !StringUtils.isEmptyString(jsFuncOnComplete)) {
				ExternalInterface.call(&quot;jsFuncOnComplete&quot;, bestSpeedTester.name, bestSpeedTester.downloadSpeed);
			}
		}</pre>
<p><strong>其他:</strong></p>
<p>1. 亦可通过JS配置Flex参数, 使用var jsFuncOnComplete:String = Application.application.parameters[&quot;funcOnComplete&quot;] as String; 取得flashvars中配置的函数名称, 更加便于配置.</p>
<p>2. Flex慎重使用JS的Alert &#8211; Alert弹出后, 等待用户操作, Flex中的相应Method可能也会处于等待状态. 在用户点击&quot;OK&quot;后, Flex继续工作, 此时(超过15秒后), 很容易出现错误:Error #1502</p>
<p>Error #1502: A script has executed for longer than the default timeout period of 15 seconds. </p>
<p><strong>其他资料:<br />
    <br /></strong></p>
<p>0. <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=passingarguments_4.html" target="_blank">Accessing JavaScript functions from Flex</a></p>
<p>1. <a href="http://ieniac.javaeye.com/blog/403133">使用 ExternalInterface 类</a>(AS&lt;-&gt;JS双向)</p>
<p>2. <a href="http://www.javaeye.com/topic/433831">Flex与Javascript互相通信</a>(AS&lt;-&gt;JS双向)</p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2010/flex%e4%b8%ad%e5%91%bc%e5%8f%abjs%e6%96%b9%e6%b3%95-call-javascript-function-in-flex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex:自定义ItemRender重写set data时低级错误一例(附Box作ItemRender代码)</title>
		<link>http://liguoliang.com/2010/flex%e8%87%aa%e5%ae%9a%e4%b9%89itemrender%e9%87%8d%e5%86%99set-data%e6%97%b6%e4%bd%8e%e7%ba%a7%e9%94%99%e8%af%af%e4%b8%80%e4%be%8b%e9%99%84box%e4%bd%9citemrender%e4%bb%a3%e7%a0%81/</link>
		<comments>http://liguoliang.com/2010/flex%e8%87%aa%e5%ae%9a%e4%b9%89itemrender%e9%87%8d%e5%86%99set-data%e6%97%b6%e4%bd%8e%e7%ba%a7%e9%94%99%e8%af%af%e4%b8%80%e4%be%8b%e9%99%84box%e4%bd%9citemrender%e4%bb%a3%e7%a0%81/#comments</comments>
		<pubDate>Sun, 15 Aug 2010 15:15:46 +0000</pubDate>
		<dc:creator>老李</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[ItemRenderer]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2010/08/1423/</guid>
		<description><![CDATA[<p>使用ActionScript做Render时一般都会重写set data以实现具体效果, 洒家每次犯过多次低级错误, 那便是忘记set data时super之.</p>
<p>忘记super的后果是数据可能不会正常显示, Datagrid可能在浮动/点击 Render时 所在行没反应.</p>
<p> </p>]]></description>
			<content:encoded><![CDATA[<p>使用ActionScript做Render时一般都会重写set data以实现具体效果, 洒家每次犯过多次低级错误, 那便是忘记set data时super之.</p>
<p>忘记super的后果是数据可能不会正常显示, Datagrid可能在浮动/点击 Render时 所在行没反应.</p>
<p> <span id="more-1423"></span>
<p>显示不正常的, 如: <a href="http://liguoliang.com/2009/10/1071/">http://liguoliang.com/2009/10/1071/</a></p>
<p>附: 重写Box作为ItemRender代码(该类作为一个抽象出来专用于重写的Abstract类, 所以并未实现具体效果):</p>
<pre class="java" name="code">/*
* $Id$
* Copyright (c) 2008-2010 Insprise Software (Shanghai) Co. Ltd.
* All Rights Reserved
* Changelog:
*   LiGuoliang.com - Aug 15, 2010: Initial version
*/

package com.insprise.util.speedtest.lib
{

/**
 * SpeedTester的速度Render.
 */
[ResourceBundle('canvas_main')]
public class AbstractRenderForSpeed extends Box implements IDropInListItemRenderer, IListItemRenderer
{
	public static const RM:IResourceManager = ResourceManager.getInstance();
	public static const BUNDLE_CANVAS_MAIN:String = &quot;canvas_main&quot;;

	/** Data */
	protected var _speedTester:SpeedTester; // 当前数据

	/** UI */
	protected var _progressBar:ProgressBar;

	protected var numberFormatter:NumberFormatter = SpeedTesterUtils.getNumFormatterForSpped();

	private var _listData:BaseListData; // 为实现IDropInListItemRenderer而创建.

	// Constructor
	public function AbstractRenderForSpeed() {
		super();
		direction = BoxDirection.HORIZONTAL; // 设置Box方向
	}

	/** @inheritDoc */
	public function get listData():BaseListData {
		return _listData;
	}

	/** @inheritDoc */
	public function set listData(value:BaseListData):void {
		_listData = value;
	}

	/** @inheritDoc */
	override protected function createChildren():void {
		_progressBar = new ProgressBar();
		_progressBar.mode = ProgressBarMode.MANUAL; // 设置Mode为手动, 以手动设置进度
		_progressBar.labelPlacement = ProgressBarLabelPlacement.CENTER; // 设置Label位置
		addChild(_progressBar);
	}

	/** @inheritDoc */
	override public function set data(value:Object):void {
		super.data = value; // 不能忘啊不能忘!
		if(_speedTester == value) {
			return;
		}

		_speedTester = value as SpeedTester;

		updateUI....; // 更新UI等操作
	}

} // end class
} // end package

</pre>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2010/flex%e8%87%aa%e5%ae%9a%e4%b9%89itemrender%e9%87%8d%e5%86%99set-data%e6%97%b6%e4%bd%8e%e7%ba%a7%e9%94%99%e8%af%af%e4%b8%80%e4%be%8b%e9%99%84box%e4%bd%9citemrender%e4%bb%a3%e7%a0%81/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex 中使用ProgressBar / Using ProgressBar in Flex</title>
		<link>http://liguoliang.com/2010/flex-%e4%b8%ad%e4%bd%bf%e7%94%a8progressbar-using-progressbar-in-flex/</link>
		<comments>http://liguoliang.com/2010/flex-%e4%b8%ad%e4%bd%bf%e7%94%a8progressbar-using-progressbar-in-flex/#comments</comments>
		<pubDate>Sun, 15 Aug 2010 14:42:26 +0000</pubDate>
		<dc:creator>老李</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Flex 进度条]]></category>
		<category><![CDATA[ProgressBar]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2010/08/1417/</guid>
		<description><![CDATA[<p>在表示进度(如上传/下载)时, 可使用ProgressBar进行直观显示.<br />
<a href="http://liguoliang.com/wp-content/uploads/2010/08/image7.png"><img style="display: inline; border-width: 0px;" title="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb7.png" border="0" alt="image" width="619" height="146" /></a></p>
<p></p>]]></description>
			<content:encoded><![CDATA[<p>在表示进度(如上传/下载)时, 可使用ProgressBar进行直观显示.<br />
<a href="http://liguoliang.com/wp-content/uploads/2010/08/image7.png"><img style="display: inline; border-width: 0px;" title="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb7.png" border="0" alt="image" width="619" height="146" /></a></p>
<p><span id="more-1417"></span></p>
<p>具体使用:</p>
<p><strong>1. 创建ProgressBar并设置基本样式:<br />
</strong></p>
<pre name="code" class="java">		_progressBar = new ProgressBar();
		_progressBar.mode = ProgressBarMode.MANUAL; // 设置Mode为手动, 以手动设置进度
		_progressBar.labelPlacement = ProgressBarLabelPlacement.CENTER; // 设置Label位置
		addChild(_progressBar);</pre>
<p><strong>注意:</strong></p>
<p><strong> </strong></p>
<p>设置Mode: 如要手动设置ProgressBar状态, 要设置mode为Manual, 更多Mode参见API.</p>
<p>设置Label位置: 默认显示为Bottom, 还有top, left/right/center可设置. 上图左侧为默认的bottom, 右侧为center.</p>
<p><strong>2. 设置ProgressBar进度: 设置ProgressBar的初始状态:</strong></p>
<pre name="code" class="java">	/** 重置Progress, 设置ProgressBar初始状态. */
	protected function resetProgressBar():void {
		if(_progressBar != null) {
			_progressBar.label = "准备操作...";
			_progressBar.setProgress(0, 1);
		}
	}</pre>
<p>对于明确进度的事件, 可随着具体事件的进度, 如上传/下载 设置具体进度:</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2010/08/image8.png"><img style="display: inline; border-width: 0px;" title="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb8.png" border="0" alt="image" width="532" height="207" /></a></p>
<pre name="code" class="java">	/** 下载过程中响应. */
	protected function onDownloadProgress(e:Event):void {
		if(_progressBar != null) {
			_progressBar.label = numberFormatter.format(_speedTester.currentDownloadPercent) + "%"; // 设置Label显示百
			_progressBar.setProgress(_speedTester.currentBytesDownloaded, _speedTester.fileDownloadSize); // 设置进度
		}
	}</pre>
<p>对于未知具体进度的事件, 可设置ProgressBar仅滚动显示, 而不显示具体进度, 如第一张图片右侧内容:</p>
<pre class="java">_progressBar.indeterminate = true; // 设置滚动显示, 无具体进度.</pre>
<p>API:<br />
<a href="http://livedocs.adobe.com/flex/3/langref/mx/controls/ProgressBar.html#includeExamplesSummary" target="_blank">Flex 3.0 ENProgressBar </a> <a href="http://help.adobe.com/zh_CN/AS3LCR/Flex_4.0/mx/controls/ProgressBar.html" target="_blank">Flex 4.0中文ProgressBar</a></p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2010/flex-%e4%b8%ad%e4%bd%bf%e7%94%a8progressbar-using-progressbar-in-flex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一个涉及Flex,Keep-Alive, PHP的bug排除实录</title>
		<link>http://liguoliang.com/2010/%e4%b8%80%e4%b8%aa%e6%b6%89%e5%8f%8aflexfirefoxkeep-alive-php%e7%9a%84bug%e6%8e%92%e9%99%a4%e5%ae%9e%e5%bd%95/</link>
		<comments>http://liguoliang.com/2010/%e4%b8%80%e4%b8%aa%e6%b6%89%e5%8f%8aflexfirefoxkeep-alive-php%e7%9a%84bug%e6%8e%92%e9%99%a4%e5%ae%9e%e5%bd%95/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 15:41:44 +0000</pubDate>
		<dc:creator>老李</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Http Header]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2010/08/1404/</guid>
		<description><![CDATA[<p>Flex端依次向PHP客户端发送两个Request, 由于php端处理第一个Request时存在bug, 由于Keep-Alive, 第二个Request会先接收第一个Request的残局, 造成第二个Request在FireFox下出现异常.</p>
<p>涉及到的内容: PHP, Http Header, Flex URLLoader URLRequest, Keep-Alive, Apache AccessLog, FireFox, Firebug(除了Flex我比较熟之外其他基本上都是懂一点, 所以下面说辞可能会与具体语言/工具有所出入).</p>
<p>起因非常简单: php端一个while的condition没有随着循环而++.</p>
<p><strong>详细描述</strong>: </p>
<p>为了测试服务器速度, 我们用Flex + PHP写了一个测试程序, 测试一组服务器的上传下载速度, Debug时很稳定, 如图:    <br /><a href="http://liguoliang.com/wp-content/uploads/2010/08/image4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb4.png" width="589" height="484" /></a> </p>
<p>IE下测试效果很好, 但在Build后放在FireFox上测试, Firefox的pulugin-container就占到若干G内存. 以前我只写过卡死浏览器的程序, 还不曾写过直接死机的程序, 结果昨晚dubug时竟然搞死我的电脑一次. </p>
<p> </p>]]></description>
			<content:encoded><![CDATA[<p>Flex端依次向PHP客户端发送两个Request, 由于php端处理第一个Request时存在bug, 由于Keep-Alive, 第二个Request会先接收第一个Request的残局, 造成第二个Request在FireFox下出现异常.</p>
<p>涉及到的内容: PHP, Http Header, Flex URLLoader URLRequest, Keep-Alive, Apache AccessLog, FireFox, Firebug(除了Flex我比较熟之外其他基本上都是懂一点, 所以下面说辞可能会与具体语言/工具有所出入).</p>
<p>起因非常简单: php端一个while的condition没有随着循环而++.</p>
<p><strong>详细描述</strong>: </p>
<p>为了测试服务器速度, 我们用Flex + PHP写了一个测试程序, 测试一组服务器的上传下载速度, Debug时很稳定, 如图:    <br /><a href="http://liguoliang.com/wp-content/uploads/2010/08/image4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb4.png" width="589" height="484" /></a> </p>
<p>IE下测试效果很好, 但在Build后放在FireFox上测试, Firefox的pulugin-container就占到若干G内存. 以前我只写过卡死浏览器的程序, 还不曾写过直接死机的程序, 结果昨晚dubug时竟然搞死我的电脑一次. </p>
<p> <span id="more-1404"></span>
<p></p>
<p>Flex端会通过URLLoader及URLRequest与PHP进行交互, 我们先从服务器读取1M的数据, 计算速度, 然后将数据发送到php端保存. 整个客户端的过程就是: Download, Report.</p>
<p>PHP端收到Download请求后, 会生成一个1M的文件返回到Flex端; 收到Report请求后会保存速度等参数, 并会返回ip所在地.</p>
<p>在使用FireFox进行测速时, 发现在Report后进入假死状态, 直到flash crash或浏览器死掉, 于是使用Firebug查看Request情况, 如图:   <br /><a href="http://liguoliang.com/wp-content/uploads/2010/08/image5.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb5.png" width="754" height="236" /></a> </p>
<p>非常不可思议的是发现Report中返回的数据竟然超大, 而且越来越大, 毫无停止的迹象. (后来该用FireFox浏览器进行Debug, 在监听Report.ProgressEvent时发现 bytesTotal也在不断的长大)</p>
<p>费解啊费解, 后来发现在Flex端如果在Download结束后, 暂停上2秒(及以上), 再进行report就会正常report并返回ip所在地.</p>
<p>怀疑可能是Report Action处理有问题? 于是查看了Apahce的AccessLog, 发现只有Download的Access记录, 而无Report的Access记录. 我干啊..</p>
<p><strong>于是猜想:&#160; 可能是跟浏览器的Keep-Alive有关</strong></p>
<p>仔细排查了PHP端代码, 发现在生成文件的一个while中, 参数没有++, 导致在Download时, 虽然打算创建1M的文件, 但实际上while停不下一直会增大文件&#8230;</p>
<p>但Download的Header里明确了文件大小信息:    </p>
<p><em>header(&quot;Content-Length: &quot;.(string)($downloadSize));</em></p>
<p>所以浏览器跟URLRequest都只会下载1M的数据,&#160; 但服务器仍在while循环, 文件仍在不断变大&#8230;.</p>
<p>猜想可能是由于FireFox的keep-alive, 在Report请求时, 发现TCP连接中仍有活动的connection,&#160; 于是先继续接受TCP已接收的数据, 也就是Download的1M数据之外的数据, 于是Report开始后实际上还是在下载1M之外未完的数据.&#160; 由于1M之外的数据读不完, 下了大量数据, 于是关掉FireFox或plugin-container进程, Firebug中看到的Report Request实际仍没有发送到服务器端, 于是造成了Report收拾Download残局的现状.</p>
<p><strong>如此折腾下来, 看来只需修复php端bug就好, 果然搞定.</strong></p>
<p><strong>重复验证:</strong></p>
<p>php端处理DownloadAction代码中, 创建完毕1M数据后, echo &#8216;liguoliang.com’;</p>
<p>也就是这个几个字符会继续发送到客户机, 但不会被浏览器处理(Header中定义了文件下载大小为1M),&#160; 因此多余的&#8217;liguoliang.com&#8217; 会在第二次Request后首先从客户机读取, 然后再向服务器端请求(由于此前文件不断变大, 所以等不到收拾完Download Request残局就crash了).</p>
<p>果然, 查看Apache的Access log, 正常, 有两个记录, 再看Firebug:</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2010/08/image6.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb6.png" width="728" height="239" /></a> </p>
<p>果然,&#160; 先收拾了上一把的残局, 搞的下一把都异常了.</p>
<p>这个bug出现的条件:</p>
<p>测试服务器在本机, 所以操作都很快, 眨眼就下完1M数据, 然后会keep-alive,&#160; report Request会收拾前一个有问题的Request的残局. 如果测试服务器在外部, 或两个Request间隔大于2秒(前一个结束到后一个开始)第二个Request会直接去请求服务器, 而不是先吃剩饭, 造成异常.&#160; </p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2010/%e4%b8%80%e4%b8%aa%e6%b6%89%e5%8f%8aflexfirefoxkeep-alive-php%e7%9a%84bug%e6%8e%92%e9%99%a4%e5%ae%9e%e5%bd%95/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex3.5 bug: 改变ComboBox DataProvider后UI不更新的初步解决</title>
		<link>http://liguoliang.com/2010/flex3-5-bug-%e6%94%b9%e5%8f%98combobox-dataprovider%e5%90%8eui%e4%b8%8d%e6%9b%b4%e6%96%b0%e7%9a%84%e5%88%9d%e6%ad%a5%e8%a7%a3%e5%86%b3/</link>
		<comments>http://liguoliang.com/2010/flex3-5-bug-%e6%94%b9%e5%8f%98combobox-dataprovider%e5%90%8eui%e4%b8%8d%e6%9b%b4%e6%96%b0%e7%9a%84%e5%88%9d%e6%ad%a5%e8%a7%a3%e5%86%b3/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 06:12:18 +0000</pubDate>
		<dc:creator>老李</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[ComboBox]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Flex 3.5]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2010/08/1378/</guid>
		<description><![CDATA[<p><b>基本信息描述:</b></p>
<p>在SDK升级到3.5后, 突然发现很多ComboBox(多数都是好多级联动)无法继续正常工作. </p>
<p>直接表现为: 联动菜单:</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2010/08/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb.png" width="244" height="184" /></a>&#160; <a href="http://liguoliang.com/wp-content/uploads/2010/08/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb1.png" width="219" height="186" /></a>     <br />左图: 正常工作的级联ComboBox&#160;&#160;&#160;&#160;&#160; <br />右图: 未正常工作,&#160; <br />先选择教育类型为高级中学,&#160; 年级显示初中数据, 只有一个年级初一.     <br />然后切换<strong>教育类型为高中, 此时年级DP已经更新为高中年级数组, 但仍显示前一次的初中年级</strong>; </p>
<p> </p>]]></description>
			<content:encoded><![CDATA[<p><b>基本信息描述:</b></p>
<p>在SDK升级到3.5后, 突然发现很多ComboBox(多数都是好多级联动)无法继续正常工作. </p>
<p>直接表现为: 联动菜单:</p>
<p><a href="http://liguoliang.com/wp-content/uploads/2010/08/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb.png" width="244" height="184" /></a>&#160; <a href="http://liguoliang.com/wp-content/uploads/2010/08/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb1.png" width="219" height="186" /></a>     <br />左图: 正常工作的级联ComboBox&#160;&#160;&#160;&#160;&#160; <br />右图: 未正常工作,&#160; <br />先选择教育类型为高级中学,&#160; 年级显示初中数据, 只有一个年级初一.     <br />然后切换<strong>教育类型为高中, 此时年级DP已经更新为高中年级数组, 但仍显示前一次的初中年级</strong>; </p>
<p> <span id="more-1378"></span>
<p>下拉框高度有四个单位, 可见高度准确, 但数据未更新.也无法选定. </p>
<p><b>解决方法:</b></p>
<p>在Set ComboBox DataProvider后, 再set 该ComboBox.listdown.dataprovider, 具体代码: </p>
<pre class="java" name="code">		combo.dataProvider = dp;
		if(combo.dropdown != null) {
			combo.dropdown.dataProvider = dp;
		}</pre>
<p><b>遗留问题:</b></p>
<p>在使用时, 初次选定comboBox数据之前, comboBox的listdown宽度/高度可能会发生异常.&#160; 如:<br />
  <br /><a href="http://liguoliang.com/wp-content/uploads/2010/08/image2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://liguoliang.com/wp-content/uploads/2010/08/image_thumb2.png" width="244" height="185" /></a>&#160; 注意: listdown的宽度, 跟第一个图正常工作时的对比 -(在首次选定前)宽度没有自动更新. </p>
<p></p>
<p> 尝试在Set DP后validateNow, invalidateDisplayList等方法, 无效; </p>
<p><b>其他尝试:</b></p>
<p>1. 尝试在set dp时 先Rmove dp内数据, 再逐个将新数据加入到原DP内, 可行 &#8211; 但ComboBox的宽度不会自动调整(可能是因为DP没有改变, 未激发Event一类的) </p>
<p>2. 尝试在set dp后由dp主动派发: CollectionEventKind.RESET事件, 无效. </p>
<p>参考: </p>
<h5>Changing DataProvider in a Flex ComboBox Problem Fix <a title="http://www.newtriks.com/?p=935" href="http://www.newtriks.com/?p=935">http://www.newtriks.com/?p=935</a></h5>
<p><b>附录 代码</b></p>
<pre class="java" name="code">	/**
	 * 解决Flex3.5中ComboBox的bug - Combobox不能及时显示数据 - 尤其在外部设定了DP后, combo下拉后只能通过DP长度计算Dropdown的高度, 但不能显示数据.
	 * 解决方案有基本有两个:
	 * 		1. (不推荐)保持ComboBox的DP对象不变, 如ArrayCollection, 不直接Set而是将现有数据源情况后将新的逐个add.
	 * 		2. 在set dp时, 同时set给combo.dropdown.dataprovider
	 * 但仍旧存在一个问题: comboBox下拉框的宽度:
	 * 		使用1时, comboBox跟下拉框宽度都不会根据数据源中最大长度项目而改变;
	 * 		使用2时, 在首次选定前, 仅下拉框的宽度不能随之改变. (暂时不妨碍使用)
	 * 虽然在改变dp后立即使用了validateNow,
	 *  @see http://www.newtriks.com/?p=935
	 */
	protected static function setComboDataProvider(combo:ComboBox, dp:ArrayCollection):void {

		// 1. 方法一: 保持数据源不变, 仅改变期中数据.
//		var dpAC:ArrayCollection = combo.dataProvider as ArrayCollection;
//		if(dpAC != null) {
//			dpAC.removeAll();
//		}else {
//			dpAC = new ArrayCollection();
//			combo.dataProvider = dpAC;
//		}
//		ArrayUtils.addAllElements(dp, dpAC);

		// 2. 方法二: 同时设置dropdown的dataProvider
		combo.dataProvider = dp;
		if(combo.dropdown != null) {
			combo.dropdown.dataProvider = dp;
		}
//
//		// 试图通过validate等方法 及时的更新dropdown的宽度, 但扔无济于事. 使用1时combo/dropdown的宽度都不会更新, 使用2时, 在首次选定数据前, dropdown的宽度不更新.
//		combo.validateNow();
//		combo.invalidateDisplayList();
//
//		combo.dropdown.validateNow();
//		combo.dropdown.validateDisplayList();
//		combo.dropdown.invalidateDisplayList();
	}</pre>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2010/flex3-5-bug-%e6%94%b9%e5%8f%98combobox-dataprovider%e5%90%8eui%e4%b8%8d%e6%9b%b4%e6%96%b0%e7%9a%84%e5%88%9d%e6%ad%a5%e8%a7%a3%e5%86%b3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Red5视频服务器统计信息生成方法</title>
		<link>http://liguoliang.com/2010/red5%e8%a7%86%e9%a2%91%e6%9c%8d%e5%8a%a1%e5%99%a8%e7%bb%9f%e8%ae%a1%e4%bf%a1%e6%81%af%e7%94%9f%e6%88%90%e6%96%b9%e6%b3%95/</link>
		<comments>http://liguoliang.com/2010/red5%e8%a7%86%e9%a2%91%e6%9c%8d%e5%8a%a1%e5%99%a8%e7%bb%9f%e8%ae%a1%e4%bf%a1%e6%81%af%e7%94%9f%e6%88%90%e6%96%b9%e6%b3%95/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 13:27:18 +0000</pubDate>
		<dc:creator>老李</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Red5]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2010/07/1343/</guid>
		<description><![CDATA[<p>对于一个Red5服务器, 在应用中可能需要随时获取以下信息:</p>
<p>1. 当前正在Broadcast的Stream有多少个? 每个Stream有多少个subscriber?   <br />2. 每个Broadcast的Stream主持人, 每个subscriber的IP, 持续时间, 流量    <br />3. 其他的, 如服务器的CPU, 内存等信息.    </p>
<p> </p>]]></description>
			<content:encoded><![CDATA[<p>对于一个Red5服务器, 在应用中可能需要随时获取以下信息:</p>
<p>1. 当前正在Broadcast的Stream有多少个? 每个Stream有多少个subscriber?   <br />2. 每个Broadcast的Stream主持人, 每个subscriber的IP, 持续时间, 流量    <br />3. 其他的, 如服务器的CPU, 内存等信息.    </p>
<p> <span id="more-1343"></span>
<p>为了应对以上需求, 可能需重写ApplicationAdapter类, 重写   <br />1。 重写streamPublishStart/Close方法, 以便及时的记录BroadcastStream的信息, 通过stream.getConnection()获得Connection, 进而获得主持人的IP, 流量, 持续时间等信息;</p>
<p>2。 重写streamPlaylistItemPlay/Stop方法, 及时获得playlistSubscriberStream信息, 同时可通过IPlayItem获得对应BroadcatStream的publicName, 从而可统计处每个BroadcastStream的subscriber列表, 进而获具体客户的连接信息.</p>
<p>可通过创建Servlet的方法获取到这些信息, 从而为Flex等客户端提供参考信息.   </p>
<p>PS: 初次使用Red5，可能重写的方法都不准确,&#160; 恳请各位不吝赐教~   </p>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2010/red5%e8%a7%86%e9%a2%91%e6%9c%8d%e5%8a%a1%e5%99%a8%e7%bb%9f%e8%ae%a1%e4%bf%a1%e6%81%af%e7%94%9f%e6%88%90%e6%96%b9%e6%b3%95/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex:Error #2176 解决</title>
		<link>http://liguoliang.com/2010/flexerror-2176-%e8%a7%a3%e5%86%b3/</link>
		<comments>http://liguoliang.com/2010/flexerror-2176-%e8%a7%a3%e5%86%b3/#comments</comments>
		<pubDate>Sat, 15 May 2010 06:00:06 +0000</pubDate>
		<dc:creator>老李</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Erro #2176]]></category>

		<guid isPermaLink="false">http://liguoliang.com/2010/05/1259/</guid>
		<description><![CDATA[<p>Error: Error #2176: Certain actions, such as those that display a pop-up window, may only be invoked upon user interaction, for example by a mouse cli</p>]]></description>
			<content:encoded><![CDATA[<p>Error: Error #2176: Certain actions, such as those that display a pop-up window, may only be invoked upon user interaction, for example by a mouse click or button press.</p>
<p>&#160;</p>
<p>做AIR开发时经常会忘记浏览器版本的安全限制, 导致在build为swf之后出现此类问题.</p>
<p>为了保持AIR上的UI, 同时支持浏览器版本, 可预先根据运行环境进行分类处理.</p>
<p>如下, 描述通过点击按钮, 直接下载某文件的解决方案:</p>
<p>AIR中可直接使用, 但浏览器版本会有安全错误.</p>
<p> 在浏览器版本时, 点击按钮后不会立即激发下载,而是显示label,用户点击后再进行下载. AIR中点击按钮直接下载:</p>
<pre name="code" class="java">

// onAction 处理...
		if(SystemUtils.isAirEnvironment()) { // AIR下直接下载
			labelDownloadLink.visible = false;
			downloadReportFile(); // 直接下载.
		}else if(SystemUtils.isBrowserEnvironment()) { // 浏览器环境下, 因安全策略限制, 显示Label, 通过点击label进行下载.
			labelDownloadLink.visible = true;
			labelDownloadLink.text = RM.getString(BUNDLE_ATHENA, "download");
		}else {
			// donothing.
		}

	/** 在浏览器版本中使用Label进行下载. */
	protected function onDownlinkClicked(e:MouseEvent):void {
		if(!StringUtils.isEmptyString(_pathReportFile)){
			downloadReportFile();
		}
	}

	/** 开始现在报表文件, Air/Broswer 共用. */
	protected function downloadReportFile():void {
		var fileRef:FileReference = new FileReference();
		var urlReq:URLRequest = new URLRequest(_pathReportFile);
....
		fileRef.download(urlReq, (dgRecReportPlans.selectedItem as AssessReportPlan).nameFull + ".xls");
	}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://liguoliang.com/2010/flexerror-2176-%e8%a7%a3%e5%86%b3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
