programming Flex2 学习笔记-客户端数据通信
时间:2007-12-02 来源:stone5
15章客户端数据通信
本地连接:同时在同一机子上,几个运行的swf之间的通信
共享对象:存取客户机上保存的数据
外接接口:与主机环境通信,让flex应用作为整个应用一部分
一、本地连接
可让几个SWF之间互相通信,即使它们运行在分离的FLASH PLAYER实例中,可让FLASH9与以前版本的.SWF之间通信。本地连接使用AMF,一种二进制消息格式。用于本地连接的AMF包的最大尺寸是40kb,本地连接只用AMF0,而不是象其他AS类使用AMF0和AMF3.使用AMF0可以老版本的Flash内容通信。
技术上,也可在一个swf文件内部使用本地连接,但一般是两个swf之间的通信。
Example 15-1. Local connection send example <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script>
<![CDATA[ import flash.net.LocalConnection;
private var _localConnection:LocalConnection = new LocalConnection(); private function sendMessage(event:MouseEvent):void {
_localConnection.send("dataChannel", "displayMessage", message.text);
} ]]>
</mx:Script> <mx:VBox id="vbox">
<mx:TextArea id="message" />
<mx:Button click="sendMessage(event)" />
</mx:VBox> </mx:Application>
Example 15-2. Local connection receive example <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
initialize="initializeHander(event)"> <mx:Script>
<![CDATA[ import flash.net.LocalConnection; private var _localConnection:LocalConnection; private function initializeHandler(event:Event):void {
_localConnection = new LocalConnection();
_localConnection.connect("dataChannel");
_localConnection.client = this; //指定接收消息的对象
} // Note that this method is declared as public because it is
// exposed as a method to a local connection.
public function displayMessage(message:String):void {
output.text += message + "\n";
} ]]>
</mx:Script> <mx:TextArea id="output" width="539" height="589"/> </mx:Application> 跨域通信
默认的,不允许本地连接在从不同域载入的swf间通信.除非显示地指定跨域通信。分为
已知域间的通信
var localConnection:LocalConnection = new LocalConnection();
localConnection.send("www.b.com:channel", "exampleMethod"); //向b.com发送 var receivingLocalConnection:LocalConnection = new LocalConnection();
receivingLocalConnection.allowDomain("www.a.com"); //接收a.com的
receivingLocalConnection.connect("channel");
receivingLocalConnection.client = this;
未知域间的通信
// Sending .swf
var localConnection:LocalConnection = new LocalConnection();
localConnection.send("_channel", "exampleMethod"); //channel要加前缀 // Receiving .swf
var receivingLocalConnection:LocalConnection = new LocalConnection();
receivingLocalConnection.allowDomain("*"); //使用*来表示未定域
receivingLocalConnection.connect("channel");
receivingLocalConnection.client = this;
二、持续的数据
Flasp Player不能随意地在客户机上写文件,但Flash Player有一个客户机上被设计的区域,能写入非常特定的文件,叫做Local shared object本地共享对象,能用AS来读写这些文件。使用flash.net.SharedObject类管理访问这些,通过SharedObject接口。
注意:SharedObject类也被用于远程共享对象,所以SharedObject类的API很多特性在这里并没有讨论。远程共享对象允许实时的同步许多客户端,但也需要服务端软件如Flash Media Server。
创建共享对象:
不象许多AS类,不能直接使用ShareObject构造器。而是使用工厂化方法getLocal():
var sharedObject:SharedObject = SharedObject.getLocal("example");参数对应客户机上的文件,有则打开,没有则创建。
sharedObject.data.hideStartScreen = true;使用点句法访问其中保存hideStartScreen的数据
sharedObject.data["First Name"] = "Bob"; 或者使用数组方式
这些数据只是写入了shareObject对象,在swf文件关闭时才写入文件,如果要明确写入:
try {
sharedObject.flush();
}
catch {
Alert.show("You must allow local data storage.");
}
下面的例子,是对flush的更详细的介绍,包括它返回的值,具体如何处理返回的结果等。没完全看明白。 <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
initialize="initializeHandler(event)"> <mx:Script>
<![CDATA[ import flash.net.SharedObject;
import mx.controls.Alert; private var _sharedObject:SharedObject; 。。。。。。 默认,存储共享对象的空间,缺省的分配是100KB,如果超过,Flash Player提示用户分配更多的空间,或者你可事先指定:
sharedObject.flush(512000);
控制范围
默认,每一个本地共享对象特定于它的源.swf。若要允许几个.swf访问相同的共享对象,需要在调用getLocal()时指定路径参数。
如:
http://www.example.com/flex/client/a.swf默认创建的共享对象:
var sharedObject:SharedObject = ShareObject.getLocal("example");
与http://www.example.com/flex/client/b.swf默认创建的同名共享对象
var sharedObject:SharedObject = ShareObject.getLocal("example");
并不相同,若要它们访问相同的共享对象,必须指定路径参数为它们的相同部分:
var sharedObject:SharedObject = ShareObject.getLocal("exmaple","/flex/client");
同理:如果要这个域下的所有.swf都要访问相同的共享对象,则只能指定路径参数为"/"了。
在不同域的swf文件是不能访问相同的本地共享对象的。
接着是一个例子,使用本地共享对象,进行用户验证,在原书P366,是个好例子,看得不是完全明白。 定制的序列化
许多内建的数据类型能够被自动地序列化和反序列化,对于定制类型,Flash Player也能自动地序列化所有的public属性(包括getter和setter),但,Flash Player不自动地存储类型,当从共享对象中取回数据时,默认的,它将不能反序列化定制的类型。
以下一大段例子,讲解问题及解决的方法P368。。。。。
三、与主机应用通信
使用flash.external.ExternalInterface可在flex应用与主机应用间互相通信。
ExternalInterface.call("alert","Test message from Flex");在flex里调用javascript的alert方法
var option:Boolean = ExternalInterface.call("confirm","Do yo really want to close the application?");还可从中返回值。
在javascript里调用flex的函数
在flex中为被调用的方法指定别名:
ExternalInterface.addCallback("showAlert",Alert.show);
在javascript中,先要获得要调用swf的引用,使用如下的函数:
function getFlexApplicationReference() {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window.Example; //对于IE浏览器,Example指的是<object>标签的id参数
} else {
return document.Example; //对于非IE浏览器,Example指的是<embed>标签的name属性。
}
}
然后使用该引用和方法别名就可调用这个方法了:
getFlexApplicationReference().showAlert("Alert message from host application");
例子:设置web浏览器的状态条
(本例可能不适用于firefox的缺省配置,因为firefox默认不允许javascript访问window.status)
在MXML中:
private function rollOverHandler(event:MouseEvent):void {
ExternalInterface.call("setStatus", event.currentTarget.label);
} //将当前组件的label值放到浏览器状态条上
在javascript中:
function setStatus(value) {
window.status = value;
}
例子:在HTML和Flex表单间交互
本例很实用,在html的表单中使用flex的组件,
下面是HTML部分
Example 15-14. ExternalInterface example HTML page <html>
<input name="checkbox" type="checkbox" onChange="getFlexApplicationReference().
setEnabled(this.checked)" /> //用一个框来决定是否启用flex的日期选择器
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
id="Flex2" width="175" height="180"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.
cab">
<param name="movie" value="Flex2.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#FFFFFF" />
<param name="allowScriptAccess" value="sameDomain" />
<embed src="Flex2.swf" quality="high" bgcolor="#FFFFFF"
width="175" height="180" name="Flex2" align="middle"
play="true"
loop="false"
quality="high"
allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflashplayer">
</embed>
</object>
</body>
</html> Example 15-15. ExternalInterface example MXML Flex2.mxml <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
initialize="initializeHandler(event)" width="175" height="180"> <mx:Script>
<![CDATA[ private function initializeHandler(event:Event):void {
var disallowedDates:Array = ExternalInterface.call("getDisallowedDates"); //由javascript中获得日期组件的初始参数
calendar.disabledRanges = disallowedDates;
ExternalInterface.addCallback("setEnabled", setEnabled); //注册一下可被javascript调用的函数
} public function setEnabled(value:Boolean):void {
calendar.enabled = value;
} ]]>
</mx:Script>
<mx:DateChooser id="calendar" enabled="false" /> </mx:Application>
本章结束
本地连接:同时在同一机子上,几个运行的swf之间的通信
共享对象:存取客户机上保存的数据
外接接口:与主机环境通信,让flex应用作为整个应用一部分
一、本地连接
可让几个SWF之间互相通信,即使它们运行在分离的FLASH PLAYER实例中,可让FLASH9与以前版本的.SWF之间通信。本地连接使用AMF,一种二进制消息格式。用于本地连接的AMF包的最大尺寸是40kb,本地连接只用AMF0,而不是象其他AS类使用AMF0和AMF3.使用AMF0可以老版本的Flash内容通信。
技术上,也可在一个swf文件内部使用本地连接,但一般是两个swf之间的通信。
Example 15-1. Local connection send example <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script>
<![CDATA[ import flash.net.LocalConnection;
private var _localConnection:LocalConnection = new LocalConnection(); private function sendMessage(event:MouseEvent):void {
_localConnection.send("dataChannel", "displayMessage", message.text);
} ]]>
</mx:Script> <mx:VBox id="vbox">
<mx:TextArea id="message" />
<mx:Button click="sendMessage(event)" />
</mx:VBox> </mx:Application>
Example 15-2. Local connection receive example <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
initialize="initializeHander(event)"> <mx:Script>
<![CDATA[ import flash.net.LocalConnection; private var _localConnection:LocalConnection; private function initializeHandler(event:Event):void {
_localConnection = new LocalConnection();
_localConnection.connect("dataChannel");
_localConnection.client = this; //指定接收消息的对象
} // Note that this method is declared as public because it is
// exposed as a method to a local connection.
public function displayMessage(message:String):void {
output.text += message + "\n";
} ]]>
</mx:Script> <mx:TextArea id="output" width="539" height="589"/> </mx:Application> 跨域通信
默认的,不允许本地连接在从不同域载入的swf间通信.除非显示地指定跨域通信。分为
已知域间的通信
var localConnection:LocalConnection = new LocalConnection();
localConnection.send("www.b.com:channel", "exampleMethod"); //向b.com发送 var receivingLocalConnection:LocalConnection = new LocalConnection();
receivingLocalConnection.allowDomain("www.a.com"); //接收a.com的
receivingLocalConnection.connect("channel");
receivingLocalConnection.client = this;
未知域间的通信
// Sending .swf
var localConnection:LocalConnection = new LocalConnection();
localConnection.send("_channel", "exampleMethod"); //channel要加前缀 // Receiving .swf
var receivingLocalConnection:LocalConnection = new LocalConnection();
receivingLocalConnection.allowDomain("*"); //使用*来表示未定域
receivingLocalConnection.connect("channel");
receivingLocalConnection.client = this;
二、持续的数据
Flasp Player不能随意地在客户机上写文件,但Flash Player有一个客户机上被设计的区域,能写入非常特定的文件,叫做Local shared object本地共享对象,能用AS来读写这些文件。使用flash.net.SharedObject类管理访问这些,通过SharedObject接口。
注意:SharedObject类也被用于远程共享对象,所以SharedObject类的API很多特性在这里并没有讨论。远程共享对象允许实时的同步许多客户端,但也需要服务端软件如Flash Media Server。
创建共享对象:
不象许多AS类,不能直接使用ShareObject构造器。而是使用工厂化方法getLocal():
var sharedObject:SharedObject = SharedObject.getLocal("example");参数对应客户机上的文件,有则打开,没有则创建。
sharedObject.data.hideStartScreen = true;使用点句法访问其中保存hideStartScreen的数据
sharedObject.data["First Name"] = "Bob"; 或者使用数组方式
这些数据只是写入了shareObject对象,在swf文件关闭时才写入文件,如果要明确写入:
try {
sharedObject.flush();
}
catch {
Alert.show("You must allow local data storage.");
}
下面的例子,是对flush的更详细的介绍,包括它返回的值,具体如何处理返回的结果等。没完全看明白。 <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
initialize="initializeHandler(event)"> <mx:Script>
<![CDATA[ import flash.net.SharedObject;
import mx.controls.Alert; private var _sharedObject:SharedObject; 。。。。。。 默认,存储共享对象的空间,缺省的分配是100KB,如果超过,Flash Player提示用户分配更多的空间,或者你可事先指定:
sharedObject.flush(512000);
控制范围
默认,每一个本地共享对象特定于它的源.swf。若要允许几个.swf访问相同的共享对象,需要在调用getLocal()时指定路径参数。
如:
http://www.example.com/flex/client/a.swf默认创建的共享对象:
var sharedObject:SharedObject = ShareObject.getLocal("example");
与http://www.example.com/flex/client/b.swf默认创建的同名共享对象
var sharedObject:SharedObject = ShareObject.getLocal("example");
并不相同,若要它们访问相同的共享对象,必须指定路径参数为它们的相同部分:
var sharedObject:SharedObject = ShareObject.getLocal("exmaple","/flex/client");
同理:如果要这个域下的所有.swf都要访问相同的共享对象,则只能指定路径参数为"/"了。
在不同域的swf文件是不能访问相同的本地共享对象的。
接着是一个例子,使用本地共享对象,进行用户验证,在原书P366,是个好例子,看得不是完全明白。 定制的序列化
许多内建的数据类型能够被自动地序列化和反序列化,对于定制类型,Flash Player也能自动地序列化所有的public属性(包括getter和setter),但,Flash Player不自动地存储类型,当从共享对象中取回数据时,默认的,它将不能反序列化定制的类型。
以下一大段例子,讲解问题及解决的方法P368。。。。。
三、与主机应用通信
使用flash.external.ExternalInterface可在flex应用与主机应用间互相通信。
ExternalInterface.call("alert","Test message from Flex");在flex里调用javascript的alert方法
var option:Boolean = ExternalInterface.call("confirm","Do yo really want to close the application?");还可从中返回值。
在javascript里调用flex的函数
在flex中为被调用的方法指定别名:
ExternalInterface.addCallback("showAlert",Alert.show);
在javascript中,先要获得要调用swf的引用,使用如下的函数:
function getFlexApplicationReference() {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window.Example; //对于IE浏览器,Example指的是<object>标签的id参数
} else {
return document.Example; //对于非IE浏览器,Example指的是<embed>标签的name属性。
}
}
然后使用该引用和方法别名就可调用这个方法了:
getFlexApplicationReference().showAlert("Alert message from host application");
例子:设置web浏览器的状态条
(本例可能不适用于firefox的缺省配置,因为firefox默认不允许javascript访问window.status)
在MXML中:
private function rollOverHandler(event:MouseEvent):void {
ExternalInterface.call("setStatus", event.currentTarget.label);
} //将当前组件的label值放到浏览器状态条上
在javascript中:
function setStatus(value) {
window.status = value;
}
例子:在HTML和Flex表单间交互
本例很实用,在html的表单中使用flex的组件,
下面是HTML部分
Example 15-14. ExternalInterface example HTML page <html>
<input name="checkbox" type="checkbox" onChange="getFlexApplicationReference().
setEnabled(this.checked)" /> //用一个框来决定是否启用flex的日期选择器
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
id="Flex2" width="175" height="180"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.
cab">
<param name="movie" value="Flex2.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#FFFFFF" />
<param name="allowScriptAccess" value="sameDomain" />
<embed src="Flex2.swf" quality="high" bgcolor="#FFFFFF"
width="175" height="180" name="Flex2" align="middle"
play="true"
loop="false"
quality="high"
allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflashplayer">
</embed>
</object>
</body>
</html> Example 15-15. ExternalInterface example MXML Flex2.mxml <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
initialize="initializeHandler(event)" width="175" height="180"> <mx:Script>
<![CDATA[ private function initializeHandler(event:Event):void {
var disallowedDates:Array = ExternalInterface.call("getDisallowedDates"); //由javascript中获得日期组件的初始参数
calendar.disabledRanges = disallowedDates;
ExternalInterface.addCallback("setEnabled", setEnabled); //注册一下可被javascript调用的函数
} public function setEnabled(value:Boolean):void {
calendar.enabled = value;
} ]]>
</mx:Script>
<mx:DateChooser id="calendar" enabled="false" /> </mx:Application>
本章结束
相关阅读 更多 +