flex3.0新特性(2)---升级AIR应用程序, Flex 3.0中使用Ajax技术

23.3 升级AIR应用程序
AIR桌面应用程序可导出为air文件。双击此文件就能开始安装应用程序。若系统中已安装旧版的AIR应用程序,双击air文件时会提示更新AIR应用程序。这种方式是非程序性的方式。Flex 3.0中新增Update类,用以升级AIR应用程序。本小节将介绍使用Flex 3.0实现AIR应用程序的升级。

23.3.1 升级前的准备
升级前需要做些准备,包括导出最新版本的AIR应用程序和定义版本信息的文件。

1.导出AIR应用程序
导出的AIR应用程序得到的是一个安装包(.air格式),可双击打开并安装。导出AIR应用程序的步骤如下所示。

单击“File”|“Export…”命令,弹出导出类型对话框,如图23-4所示。

在树型号列表中选择“Adobe AIR”|“Adobe AIR Package”选项,单击“Next”按钮,弹出“设置AIR安装包”对话框,如图23-5所示。



图23-4 导出类型对话框 图23-5 设置AIR安装包对话框

在“Project”文本框中输入导出的工程名。在“Application”文本框中输入工程的启动页(MXML文件)。在“Include files”区域选择要导出的文件。在“Save as”文本框中输入导出的路径。单击“Finish”按钮,完成AIR应用程序的导出。

2.定义版本信息文件
用户可将当前AIR应用程序的版本信息手动存储于TXT文件中,用以判断AIR应用程序是否需要升级。

23.3.2 检查版本信息
用户可使用FileStream类加载版本信息文件,从而获得当前AIR应用程序的版本号。若当前的版本号小于最新的版本号,说明AIR应用程序需要更新。以下代码使用FileStream类加载“version.txt”文件,并判断是否需要更新AIR应用程序。

var theNewestVersion:Number=5; //定义最新的版本号



private function checkVersion():void //检查版本号信息

{

/*读取版本号*/

var stream:FileStream = new FileStream();

stream.open(new File("version.txt"), FileMode.READ);

var currVersion:String = stream.readUTFBytes(stream.bytesAvailable);

stream.close();

//若当前版本号小于最新版本号,需要下载最新的air文件

if (currVersion<theNewestVersion)

{

//升级AIR程序

}

}

23.3.3 使用FileStream类下载最新版本
在更新AIR应用程序前,需要下载最新版本的AIR安装包。使用FileStream类可下载任何格式的文件。其语法如下所示。

var FileStream变量:FileStream=new FileStream();

FileStream变量.open(下载文件路径,FileMode.WRITE);

FileStream变量.writeBytes(ByteArray变量,0,ByteArray变量.length);

ByteArray类型用以存储二进制的数据集。其length属性记录了ByteArray变量的长度。以下代码使用FileStream类下载最新版本安装包“p1.air”。

public var fileData:ByteArray = new ByteArray();



private function writeAirFile():void //下载air文件处理函数

{

var file1:File = File.desktopDirectory.resolve("p1.air");//下载路径为桌面

var fileStream:FileStream = new FileStream();

fileStream.openAsync(file1, FileMode.WRITE);

fileStream.writeBytes(fileData, 0, fileData.length);//开始写文件

fileStream.close();

}

23.3.4 使用Updater类升级AIR应用程序
在下载完成最新版本的AIR安装包后,可使用Updater类的update方法升级应用程序。其语法如下所示。

Updater变量.update(AIR路径,版本字符串);

版本字符串可自定义,如“1.2”,“1.3”等。以下代码使用Update类将应用程序升级至最新版本。

var ud:Updater=new Updater();

ud.update(new File("newest.air"),"1.3");

23.3.5 升级AIR应用程序实例
本实例中假设最新导出的AIR安装包为1.3版本,并放置于工程“bin”文件夹下。

升级AIR应用程序实例的步骤如下所示。

新建AIR工程。

在“bin”文件夹下的“Preferences”文件夹下创建“version.txt”文件。“version.txt”文件中存储当前应用程序的版本号,如“1.2”(小于最新版本号)。

编写检查版本号函数checkVersion。checkVersion函数的主要功能是读取“version.txt”中的版本号。判断是否需要升级AIR程序。以下代码定义了checkVersion函数。

private function checkVersion():void //检查版本号信息

{

/*读取版本号*/

var stream:FileStream = new FileStream();

stream.open(file, FileMode.READ); //file变量指向“version.txt”

var prevVersion:String = stream.readUTFBytes(stream.bytesAvailable);

stream.close();

//记录的版本小于当前最新版本号时,需要下载最新的air文件

if (prevVersion < currentVersion)

{

urlStream.addEventListener(Event.COMPLETE, loaded); //添加对加载完成的监听

urlStream.load(urlReq); //加载air文件

}

}

编写下载最新版本函数loaded。loaded函数使用FileStream类获得AIR应用程序的二进制数据,并将二进制数据写入到本地的AIR文件中。以下代码定义了loaded函数和writeAirFile函数。

private function loaded(event:Event):void //加载完成后,下载air文件

{

urlStream.readBytes(fileData, 0, urlStream.bytesAvailable); //数据读取到fileData数组中

writeAirFile(); //下载air文件

}

private function writeAirFile():void //写入新的air文件

{

var file1:File = File.desktopDirectory.resolve("p1.air"); //路径为桌面

var fileStream:FileStream = new FileStream();

fileStream.addEventListener(Event.CLOSE, fileClosed); //添加写文件完成的监听

fileStream.openAsync(file1, FileMode.WRITE);

fileStream.writeBytes(fileData, 0, fileData.length); //开始写文件

fileStream.close();

}

编写更新AIR应用程序代码。将最新版本AIR应用程序写入本地路径后,使用update方法更新原程序,同时修改“version.txt”文件。以下代码更新AIR应用程序,并修改“version.txt”文件内的版本号。

private function fileClosed(event:Event):void //下载文件完成处理函数

{

Alert.show("下载文件完成");

/*升级版本*/

var updater:Updater = new Updater();

var airFile:File = File.desktopDirectory.resolve("p1.air");

var version:String = currentVersion;

updater.update(airFile, version); //开始升级版本

saveFile(); //存储当前版本信息

}

private function saveFile():void //存储最新版本号

{

var stream:FileStream = new FileStream();

stream.open(file, FileMode.WRITE); //file变量指向“version.txt”

stream.writeUTFBytes(currentVersion);

stream.close();

}

完成剩余代码。剩余代码包括程序初始化函数、变量定义、类的引用等。

以下代码是完整的应用程序代码。

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

<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"

layout="absolute"

applicationComplete="init()">

<mx:Script>

<![CDATA[

import flash.filesystem.*; //引用flash.filesystem下的类

import mx.controls.Alert; //引用Alert类

public var file:File; //定义File实例

[Bindable]

public var currentVersion:String = "1.3"; //定义最新版本号

public var urlString:String ="p1.air"; //最新版本air的路径

//定义URLRequest实例

public var urlReq:URLRequest = new URLRequest(urlString);

public var urlStream:URLStream = new URLStream(); //定义URLStream实例

public var fileData:ByteArray = new ByteArray(); //定义ByteArray实例

public function init():void //应用程序初始化处理函数

{

//“version.txt”存储版本信息

file = File.applicationResourceDirectory.resolve ("Preferences /version.txt");

if(file.exists) //若文件存在时,检查版本号

{

checkVersion();

}

else //若文件不存在时,创建文件

{

firstRun();

}

}

private function checkVersion():void //检查版本号信息

{

/*读取版本号*/

var stream:FileStream = new FileStream();

stream.open(file, FileMode.READ);

var prevVersion:String = stream.readUTFBytes(stream. bytes Available);

stream.close();

//记录的版本小于当前最新版本号时,需要下载最新的air文件

if (prevVersion < currentVersion)

{

//添加对加载完成的监听

urlStream.addEventListener(Event.COMPLETE, loaded);

urlStream.load(urlReq); //加载air文件

}

}

private function firstRun():void

{

saveFile(); //存储当前版本号

}

private function saveFile():void //存储当前版本处理函数

{

var stream:FileStream = new FileStream();

stream.open(file, FileMode.WRITE);

stream.writeUTFBytes(currentVersion);

stream.close();

}

private function loaded(event:Event):void //加载完成后,下载air文件

{

//数据读取到fileData数组中

urlStream.readBytes(fileData, 0, urlStream.bytesAvailable);

writeAirFile(); //下载air文件

}

private function writeAirFile():void //下载air文件处理函数

{

//下载路径为桌面

var file1:File = File.desktopDirectory.resolve("p1.air");

var fileStream:FileStream = new FileStream();

//添加写文件完成的监听

fileStream.addEventListener(Event.CLOSE, fileClosed);

fileStream.openAsync(file1, FileMode.WRITE);

fileStream.writeBytes(fileData, 0, fileData.length); //开始写文件

fileStream.close();

}

private function fileClosed(event:Event):void //下载文件完成处理函数

{

Alert.show("下载文件完成");

/*升级版本*/

var updater:Updater = new Updater();

var airFile:File = File.desktopDirectory.resolve("p1.air");

var version:String = currentVersion;

updater.update(airFile, version); //开始升级版本

saveFile(); //存储当前版本信息

}

]]>

</mx:Script>

<mx:Label fontSize="35" text="版本{currentVersion}" horizontalCenter="0" verticalCenter="0"/>

</mx:WindowedApplication>

按下Ctrl+F11键,编译运行程序。运行效果如图23-6所示。


图23-7 升级AIR应用程序实例的运行效果

23.4 Flex 3.0中使用Ajax技术
在前面章节里曾介绍过Flex 3.0中如何使用其他Web开发技术,但未涉及Ajax技术。Ajax技术是一种非常流行的Web开发技术,其主要特点是无刷新性。本章将介绍Ajax技术的基础知识及如何在Flex 3.0中使用Ajax技术。

23.4.1 Ajax技术简介
Ajax是“Asynchronous JavaScript and XML”(异步JavaScript和XML)的简称。Ajax技术是一组技术的结合。Ajax利用通信技术(以SOAP和XML为代表)向服务器发送和接收异步请求和响应,然后使用JavaScript、DOM、HTML、CSS技术来处理响应。

Ajax技术通过JavaScript语言调用服务器端的方法,而不需要刷新浏览器,从而减轻了服务器端的负担,也更快捷地响应用户交互。另外,Ajax不需要任何浏览器插件,但浏览器需要允许运行JavaScript。

Ajax技术具体包括如下五种技术:

(47) 使用XHTML+CSS的表示样式。

(48) 使用DOM(Document Object Model)进行动态显示及交互。

(49) 使用XML和XSLT进行数据交换及相关操作。

(50) 使用XMLHttpRequest类进行异步数据查询、检索。

(51) 使用JavaScript整合所有技术。

使用Ajax开发Web应用程序最关键的技术是JavaScript语言和XMLHttpRequest类。本书中不展开详解Ajax技术开发,着重介绍如何在Flex 3.0中调用Ajax技术。

23.4.2 使用<mx:HTML>组件调用Ajax技术
在Flex 3.0中使用<mx:HTML>组件可加载包含Ajax技术的网页,其语法如下所示。

<mx:HTML id="HTML组件id"… location="网页路径"/>

以下代码使用<mx:HTML>组件加载了“www.google.cn”网页。

<mx:HTML id="html" location="www.google.cn"/>

<mx:HTML>组件在加载网页时,加载网页中的全部内容,包括JavaScript(JavaScript是Ajax技术实现的关键)。Flex 3.0中调用JavaScript函数的语法如下所示。

HTML组件id.htmlControl.window.javascript函数(参数列表);

以下代码在单击“OK”按钮时,调用“test.html”网页中的javascript函数init。

<mx:HTML id="html" location="test.html"/>

<mx:Button label="OK" click="html.htmlControl.window.init();"/>

23.4.3 Flex应用程序结合Ajax技术实例
Ajax技术已广泛应用于互联网的开发。许多无刷新的网页或有动态效果网页都使用了Ajax技术。其中,应用Ajax技术最成功的例子是Google的地图搜索。本小节中将调用Google公司免费提供的包含Ajax技术的测试网页来实现地图搜索功能。Flex 3.0结合Ajax技术实例的步骤如下所示。

新建AIR工程。

编写“yahoo.html”文件。

“yahoo.html”文件是HTML网页,包含了自定义的javascript函数来完成地图搜索功能。以下代码是“yahoo.html”文件的源代码。

<!DOCTYPEhtml

PUBLIC"-//W3C//DTDXHTML1.0Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<script src="http://api.maps.yahoo.com/ajaxymap?v=3.4&appid=mapsnap0" type="text/javascript"/>

<script type="text/javascript">

var Imap; //定义变量Imap

function init()//初始化函数

{

Imap = new YMap(document.getElementById('map')); //使用YMap类初始化Imap变量

Imap.addTypeControl(); //添加类型面板

Imap.addPanControl(); //添加方向面板

Imap.addZoomLong(); //添加缩放长条

Imap.addZoomShort(); //添加缩入短条

//绘制地图

Imap.drawZoomAndCenter('601 Townsend St. San Francisco, CA 94103', 5);

}

function lookupAddress(address) //搜索地址函数

{

//根据地址绘制地图

YEvent.Capture(Imap,

EventsList.onEndGeoCode,

function (result)

{

if (!result.success)

{

alert('This address could not be geo-coded.');

return;

}

Imap.drawZoomAndCenter(result.GeoPoint, 2);

});

Imap.geoCodeAddress(address);

}

window.onload =init; //在网页加载时调用init函数

</script>

</head>

<body>

<div id="map"/>

</body>

</html>

(52) javascript代码定义于<head>标签下的<script>标签下。

(53) “<scriptsrc="http://api.maps.yahoo.com/ajaxymap?v=3.4&appid=mapsnap0" type="text/ javascript"/>”表示引用该地址下的javascript类文件。程序中出现的YMap和YEvent类均在此类文件中定义,但对用户不可见。用户可查看Google Maps官方的使用说明。

(54) HTML网页不会自动执行javascript函数。“window.οnlοad=init;”表示在网页加载时调用init函数。

编写Flex应用程序的外观模型。Flex应用程序的外观模型包括<mx:HTML>组件、输入框组件、按钮组件等。以下代码是外观模型的MXML代码。

<mx:VBox paddingTop="0" paddingLeft="0" width="100%" height="100%">

<mx:HBox width="100%">

<mx:Label text="位置:" color="#ffffff" width="5%"/>

<mx:TextInput width="55%" id="address"/>

<mx:Button label="加载中..." enabled="false" id="mapButton" width="10%"/>

<mx:Button label="保存" width="10%"/>

<mx:Button label="复制" width="10%"/>

</mx:HBox>

<mx:HTML id="map" width="800" height="600"/><!--HTML组件,用以加载网页-->

</mx:VBox>

外观模型效果如图23-8所示。


图23-8 Flex结合Ajax实例的外观效果

添加搜索地图的ActionScript 3.0代码。ActionScript 3.0代码中调用“yahoo.html”文件中的lookupAddress函数来完成搜索功能。实例中有两处需要添加搜索地图的ActionScript 3.0代码:输入框组件的enter事件和“开始搜索”按钮的click事件。enter事件在用户输入数据并按下回车键时触发。以下代码是添加处理后的输入框组件和按钮组件。

<mx:TextInput width="55%" id="address" enter="map.htmlControl.window. lookup Address(address.text);"/>

<mx:Button label="加载中..." enabled="false" id="mapButton" width="10%" click="map.htmlControl.window.lookupAddress(address.text);"/>

按钮mapButton用以搜索地图。先是显示“加载中…”,在网页加载完成后显示“开始搜索”。

编写函数takeSnapshot。takeSnapshot函数用以截图并保存图片。以下代码定义了takeSnapshot函数。

private function takeSnapshot():void //保存图片处理函数

{

var home:File = File.desktopDirectory.resolve("map.png"); //设置保存路径

//添加对选择路径事件的监听,并定义其处理代码

home.addEventListener(Event.SELECT,

function (e:Event):void

{

var img:ByteArray = getImage(); //获得图片资源

/*使用FileStream类保存图片*/

var stream:FileStream = new FileStream();

stream.openAsync(File(e.target), FileMode.WRITE);

stream.addEventListener(Event.CLOSE,

function(ee:Event):void

{

Alert.show("图片保存成功!", "提示", Alert.OK);

});

stream.writeBytes(img);

stream.close();

});

home.browseForSave("图片保存路径?"); //打开选择路径窗口

}

private function getImage():ByteArray //获得图片资源

{

var bd:BitmapData = getBitmapData(map.width, map.height); //获得图片数据

var pnge:PNGEncoder=new PNGEncoder(); //定义PNGEncoder类型变量

var img:ByteArray = pnge.encode(bd); //对图片数据进行编码

return img;

}

private function getBitmapData(width:uint, height:uint):BitmapData //获得图片数据

{

var bd:BitmapData = new BitmapData(width, height);

bd.draw(map);

return bd;

}

(55) “bd.draw(map);”语句表示对<mx:HTML>组件截图。

(56) addEventListenner方法的第二个参数一般为处理函数名,但也可直接定义处理代码,此时不需要函数名。

编写函数copyToClipboard。copyToClipboard函数用于将截图复制到剪切板中。以下代码定义了copyToClipboard函数。

private function copyToClipboard():void //复制图片资源至剪切板

{

var mapFile:File = getMapFile(); //获得图片文件

//复制至剪切板

ClipboardManager.accessClipboard()

function ():void

{

var td:TransferableData = new TransferableData(); //定义TransferableData类型变量

//数据处理

td.addData([mapFile], TransferableFormats.FILE_LIST_FORMAT);

ClipboardManager.data = td; //复制至剪切板

Alert.show("图片已复制至剪切板!", "提示", Alert.OK); //提示复制成功

});

}

ClipboardManager类中的accessClipboard方法用以传递数据至剪切板。

完成剩余代码。剩余代码包括初始化处理函数、变量定义、类的引用等。

以下代码是完整的应用程序代码。

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

<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"

title="结合Ajax实例"

creationComplete="init();"

width="805" maxWidth="805" height="675"

fontSize="13"

maxHeight="675" paddingTop="2"

paddingLeft="2" verticalScrollPolicy="off"

horizontalScrollPolicy="off"

showStatusBar="false">

<mx:Script>

<![CDATA[

import flash.filesystem.*; //引用"flash.filesystem"下的全部类

import mx.controls.Alert; //引用Alert类

import flash.desktop.*; //引用"flash.desktop"下的全部类

import mx.graphics.codec.PNGEncoder; //引用PNGEncoder类

private const WIN_WIDTH:uint = 820; //定义宽度

private const WIN_HEIGHT:uint = 670; //定义高度

private function init():void //应用程序初始化处理函数

{

//HTML组件map加载完成时的处理代码

map.addEventListener(Event.COMPLETE,

function():void

{

mapButton.label = "开始搜索";

mapButton.enabled = true;

});

map.location = "app-resource:/yahoo.html"; //HTML组件map的URL地址

window.visible = true;

}



private function takeSnapshot():void //保存图片处理函数

{

//设置保存路径

var home:File = File.desktopDirectory.resolve("map.png");

//添加对选择路径事件的监听,并定义其处理代码

home.addEventListener(Event.SELECT,

function (e:Event):void

{

var img:ByteArray = getImage(); //获得图片资源

/*使用FileStream类保存图片*/

var stream:FileStream = new FileStream();

stream.openAsync(File(e.target), FileMode.WRITE);

stream.addEventListener(Event.CLOSE,

function(ee:Event):void

{

Alert.show("图片保存成功!", "提示", Alert.OK);

});

stream.writeBytes(img);

stream.close();

});

home.browseForSave("图片保存路径?"); //打开选择路径窗口

}

private function copyToClipboard():void //复制图片资源至剪切板

{

var mapFile:File = getMapFile(); //获得图片文件

//复制至剪切板

ClipboardManager.accessClipboard(

function ():void

{

//定义TransferableData类型变量

var td:TransferableData = new TransferableData();

//数据处理

td.addData([mapFile], TransferableFormats.FILE_ LIST_FORMAT);

ClipboardManager.data = td; //复制至剪切板

//提示复制成功

Alert.show("图片已复制至剪切板!", "提示", Alert.OK);

});

}

private function getImage():ByteArray //获得图片资源

{

//获得图片数据

var bd:BitmapData = getBitmapData(map.width, map.height);

var pnge:PNGEncoder=new PNGEncoder(); //定义PNGEncoder类型变量

var img:ByteArray = pnge.encode(bd); //对图片数据进行编码

return img;

}

//获得图片数据

private function getBitmapData(width:uint, height:uint):BitmapData

{

var bd:BitmapData = new BitmapData(width, height);

bd.draw(map);

return bd;

}

private function getMapFile():File //获得图片文件

{

//创建"map.png"文件

var mapFile:File = File.createTempDirectory().resolve("map.png");

var img:ByteArray = getImage(); //获得图片数据

//将图片数据写入到"map.png"文件中

var stream:FileStream = new FileStream();

stream.open(mapFile, FileMode.WRITE);

stream.writeBytes(img);

stream.close();

return mapFile;

}

]]>

</mx:Script>

<mx:VBox paddingTop="0" paddingLeft="0" width="100%" height="100%">

<mx:HBox width="100%">

<mx:Label text="位置:" color="#ffffff" width="5%"/>

<mx:TextInputwidth="55%"id="address" enter="map.htmlControl.window.lookupAddress(address.text);"/>

<mx:Buttonlabel="加载中..."enabled="false"id="mapButton" width="10%" click="map.htmlControl.window.lookupAddress(address.text);"/>

<mx:Button label="保存" width="10%" click="takeSnapshot();"/>

<mx:Button label="拷贝" width="10%" click="copyToClipboard();"/>

</mx:HBox>

<mx:HTML id="map" width="800" height="600"/> <!--HTML组件,用以加载网页-->

</mx:VBox>

</mx:WindowedApplication>

按下Ctrl+F11快捷键,编译运行程序。运行效果如图23-9所示。


图23-9 Flex结合Ajax实例的运行效果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值