首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

Flex 3.0中最大的变化在于新增AIR工程。AIR应用程序是一种桌面应用程序。因为要支持对本地资源的操作,所以Flex 3.0中新增许多对本地资源的操作,如本地文件、PDF文件等。另外,AIR应用程序支持版本升级、集成网页、使用Ajax技术等。本章将介绍Flex 3.0这些新特性的具体应用。

23.1  加载PDF文件

在Flex 3.0中的AIR工程中新增HTMLControl类和HTMLPDFCapability类。通过这两个类可实现加载PDF文件,丰富了AIR应用程序的效果和功能。本小节将为读者介绍如何在AIR工程中加载PDF文件。

 23.1.1  加载PDF文件前的准备

加载PDF文件需要有两个条件:第一是必须为AIR工程,第二是系统已安装Adobe Reader 8.1以上版本。前者是因为Flex 3.0中只有在AIR工程中可引用HTMLControl类和HTMLPDFCapability类。究其深层原因是Adobe公司只允许桌面应用程序(AIR)访问本地资源。其他Web工程出于安全性考虑,不可直接访问本地资源。

 23.1.2  使用HTMLControl类加载PDF文件

HTMLControl类是AIR中新增的类,用于加载PDF。使用HTMLControl类加载PDF文件的语法如下所示。

HTMLControl变量.load(URLRequest变量);

以下代码使用HTMLControl类加载“123.pdf”文件。

var t:URLRequest=new URLRequest("123.pdf");

var hc:HTMLControl=new HTMLControl();

hc.load(t);

HTMLControl类中只有一个属性pdfCapability。此属性存储了PDF文件与Adobe Reader版本间的关系。在HTMLControl类的load方法执行后,自动得到版本信息。

 23.1.3  使用HTMLPDFCapability类检测Adobe Reader版本

HTMLPDFCapability类定义了加载的PDF文件与Adobe Reader版本间的关系,使用状态字符串表示,如“ERROR_INSTALLED_READER_NOT_FOUND”。HTMLPDFCapability类的状态字符串如表23-1所示。

表23-1  HTMLPDFCapability类的状态字符串

  

   

HTMLPDFCapability.STATUS_OK

系统中已安装Adobe Reader 8.1以上版本

HTMLPDFCapability.ERROR_INSTALLED_READER_NOT_FOUND

系统中未安装Adobe Reader

HTMLPDFCapability.ERROR_INSTALLED_READER_TOO_OLD

系统中Adobe Reader版本太旧

HTMLPDFCapability.ERROR_PREFERRED_READER_TOO_OLD

当前有旧的Adobe Reader版本正在读取PDF

使用HTMLControl类的pdfCapability属性和HTMLPDFCapability类的状态字符串就能确定PDF文件与Adobe Reader版本间的关系。

以下代码表示系统中已安装Adobe Reader 8.1以上版本,可正常加载的PDF文件。

if(ht.pdfCapability==HTMLPDFCapability.STATUS_OK)

{

    Alert.show("加载PDF正常");

}

 23.1.4  加载PDF文件实例

加载PDF文件的步骤如下所示。

* 新建AIR工程。

 确定系统中已安装Adobe Reader 8.1以上版本。

 编写MXML文件。

MXML程序中主要处理是在初始化应用程序时加载PDF文件,并将结果添加到<mx:HTML>组件。以下代码加载PDF文件“1.pdf”并显示于<mx:HTML>组件上。

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

<mx:WindowedApplicationxmlns:mx="http://www.adobe.com/2006/mxml"layout="absolute"creationComplete="initApp()">

    <mx:Script>

        <![CDATA[

            import flash.html.HTMLPDFCapability;    //引用HTMLPDFCapability类

            import flash.html.HTMLControl;          //引用HTMLControl类

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

            //应用程序初始化函数

            private function initApp():void

            {

                //Adobe Reader 8.1版本以上已安装时,加载pdf

                if(HTMLControl.pdfCapability==HTMLPDFCapability.STATUS_OK)

                {

                    var request:URLRequest = new URLRequest("1.pdf");//定义URLRequest实例

                    var pdf:HTMLControl = new HTMLControl();        //定义HTML

Control实例

                    pdf.height = 800;               //设置pdf高度

                    pdf.width = 600;                //设置pdf宽度  

                    pdf.load(request);              //加载pdf

                    container.addChild(pdf);        //将pdf添加到HTML组件上

                }

                else

                    Alert.show("pdf不能显示,请安装Adobe Reader 8.1以上版本");

            }

        ]]>

    </mx:Script>

    <mx:HTML id="container"/>

</mx:WindowedApplication>

(33)       “if(HTMLControl.pdfCapability==HTMLPDFCapability.STATUS_OK)”语句用以判断系统中是否安装Adobe Reader 8.1以上版本。若未安装,则加载PDF文件不能完成。

(34)       PDF文件只能显示于<mx:HTML>组件中。“container.addChild(pdf);”语句表示在<mx:HTML>组件中添加PDF文件数据。

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

图23-1  加载PDF文件效果

23.2  使用本地SQL数据库

SQL数据库是指可使用标准的SQL语句进行操作的数据库。本地SQL数据库是指操作系统支持的SQL数据库,如“.db”格式的数据库。AIR应用程序中新增了一些类(在“flash.data.*”包中),用以支持对本地SQL数据库的操作。对SQL数据库的基本操作包括Select(读取数据)、Insert(插入数据)、Update(修改数据)、Delete(删除数据)。本章将介绍对SQL数据库操作的基本语句及如何使用新增类操作数据库。

 23.2.1  使用Select语句读取数据

Select语句用以读取表中的数据,其语法如下所示。

Select 列名1[as 别名1],列名2[as 别名2],…,列名n[as 别名n] from表名 where 条件

(35)       列名是指表中的列的名称。

(36)       用户可为列名取别名。此项默认与列名相同。

(37)       条件是指对数据的约束。例如,取表中考试成绩不及格的学生信息。

以下代码从学生成绩表“StudentScore”中读取不及格学生的学号、姓名、班级、成绩。

Select studentId as 学号,studentName as 姓名,studentClass as 班级,score as 成绩 from StudentScore where score<60

若读取表中的全部数据列,可使用“*”符。

若上述“StudentScore”表中只有学号、姓名、班级、成绩四列,读取数据的代码可如下所示。

Select * from StudentScore where score<60

 23.2.2  使用Insert语句添加数据

Insert语句用以向表中添加数据,其语法如下所示。

Insert into 表名(列名1,列名2,...,列名n) values (数值1,数值2,…数值n)

(38)       列名必须是表中存在的列的名称。

(39)       数值顺序对应列名顺序,如数值1赋值给列名1。

以下代码向学生成绩表“StudentScore”中添加一条数据。

Insert into StudentScore(studentId,studentName,score) values (‘08’,’小明’,77)

对于字符串数据使用单引号封闭,数值不需要单引号封闭。

上述语法可选择性地添加列数据。例如,表中有四列,但只添加其中三列的数据。若对全部列添加数据可省略列名,其语法如下所示。

Insert into 表名 values (数值1,数值2,…数值n)

数值顺序必须严格遵循表中列的顺序。数值个数必须与列的个数相同。

以下代码向学生成绩表“StudentScore”中添加一条完整数据。

Insert into StudentScore values (‘08’,’小明’,’高三5班’,77)

 23.2.3  使用Update语句修改数据

Update语句用以修改表中的数据,其语法如下所示。

Update 表名 set 列名1=修改值1,列名2=修改值2,…,列名n=修改值n where 条件

Update可修改表中的单条记录或多条记录。使用条件语句来控制修改范围。

以下代码使用Update语句将成绩59分修改为60分(及格)。

Update StudentScore set score=60 where score=59

需要注意的是,SQL语句中判断相等的操作符为“=”,而不是“==”。赋值语句使用Set子句或Select子句(Select语句的另外一种用法)。

若用户只想修改单条记录,可定义更加严格的条件。以下代码将小明同学的成绩59分提高到60分。

Update StudentScore set score=60 where score=59 and studentName=’小明’

 23.2.4  使用Delete语句删除数据

Delete语句用以删除表中的数据,其语法如下所示。

Delete from表名 where 条件

Delete语句可删除单条记录或多条记录,方法是控制条件范围。以下代码使用Delete语句删除“高三5班”学生信息。

Delete from StudentScore where studentClass=’高三5班’

以下代码删除学号为“08”的学生信息。

Delete from StudentScore where studentId=’08’

 23.2.5  使用SQLConnection类连接数据库

SQLConnection类用于连接数据库。对于要操作的数据库都应新建SQLConnection类实例。其语法如下所示。

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

以下代码定义了一个SQLConnection实例conn。

var conn:SQLConnection=new SQLConnection();

使用SQLConnection类的“open”方法打开数据库连接。其语法如下所示。

SQLConnection变量.open(File变量);

以下代码使用open方法打开本地SQL数据库“School.db”。

var conn:SQLConnection=new SQLConnection();

var dbFile:File =File.applicationResourceDirectory.resolve("School.db");

conn.open(dbFile);

(40)       “File.applicationResourceDirectory”语句表示工程资源路径,即“bin”文件夹路径。

(41)       resolve方法用以扩展文件路径,可看作是“\”符。

 23.2.6  使用SQLStatement类执行SQL语句

SQLStatement类用于执行SQL语句,是操作SQL数据库的重要类。使用SQLStatement类的步骤如下。

* 定义SQLStatement类实例,其语法如下所示。

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

以下代码定义了一个SQLStatement类实例sqlcmd。

var sqlcmd:SQLStatement=new SQLStatement();

 指向其使用的数据库。SQLStatement实例必须指明应用的数据库,即指向SQLConnection实例。SQLStatement实例指向数据库的语法如下所示。

SQLStatement变量.sqlConnection=SQLConnection变量;

sqlConnection属性类型为SQLConnection,表示指向的数据库实例。以下代码中SQLStatement实例stmt指向数据库实例conn。

var conn:SQLConnection=new Connection();

var dbFile:File = File.applicationResourceDirectory.resolve("School.db");

conn.open(dbFile);

var stmt:SQLStatement=new SQLStatement();

stmt.sqlConnection=conn;

 为SQLStatement实例定义SQL语句。其语法如下所示。

SQLStatement变量.text="SQL语句";

text属性类型为String,用于定义SQL语句。以下代码为SQLStatement实例stmt定义SQL语句“select * from table”。

var stmt:SQLStatement=new SQLStatement();

stmt.text="select * from table";

 执行SQLStatement实例。执行SQLStatement实例的结果是执行SQL语句。使用SQLStatement类的excute方法开始执行SQL语句。其语法如下所示。

SQLStatement变量.excute();

以下代码使用excute方法开始执行SQL语句“select * from table”。

var stmt:SQLStatement=new SQLStatement();

stmt.text="select * from table";

stmt.excute();

 为SQLStatement实例添加监听。执行SQLStatement实例后的状态有很多,常用的是正常返回结果和运行异常两种。需要对两个状态都添加监听。为SQLStatement实例添加监听的语法如下所示。

SQLStatement变量.addEventListener(监听状态,处理函数);

以下代码为“SQLEvent.RESULT”(正常返回结果)和“SQLErrorEvent.ERROR”(运行异常)状态添加监听。

stmt.addEventListener(SQLEvent.RESULT,showDataResult);

stmt.addEventListener(SQLErrorEvent.ERROR, errorHandle);

(42)       SQLEvent.RESULT状态表示SQLStatement实例执行成功并返回结果。

(43)       SQLErrorEvent.ERROR状态表示SQLStatement实例执行异常。

 获取返回数据集。执行有返回数据的SQL语句,数据集存储于SQLStatement实例中。使用SQLStatement类的getResult方法可得到数据集。其语法如下所示。

SQLStatement变量.getResult().data;

以下代码使用getResult方法获得SQL语句“select * from table”的执行结果。

var stmt:SQLStatement=new SQLStatement();

stmt.text="select * from table";

stmt.excute();                                              //执行SQL语句

stmt.addEventListener(SQLEvent.RESULT,showDataResult);

function showDataResult(e:SQLEvent):void

{

    var t:Array=stmt.getResult().data as Array;         //获得结果集

}

 23.2.7  操作本地SQL数据库实例

本小节以实例为读者讲解如何使用SQL语句操作数据库,其步骤如下所示。

* 设计数据库“School”。“School”数据库中只有一张表“Notes”,用以存储通知信息。“Notes”表的列设计如表23-2所示。

表23-2 “Notes”表的设计说明

   

   

   

是否为主码

noteId

integer

通知id

title

text

标题

 

content

text

内容

 

publisher

text

发布者

 

以下代码是创建表的SQL语句。

CREATE TABLE IF NOT EXISTS Notes

(

    noteId INTEGER PRIMARY KEY AUTOINCREMENT,

    title TEXT,

    content TEXT,

    publisher TEXT,

)

(44)       此SQL语句在应用程序中定义并执行。

(45)       “IF NOT EXISTS Notes”语句表示创建表“Notes”前先判断是否已存在此表。若已存在“Notes”表,不执行此创建语句。

(46)       “noteId INTEGER PRIMARY KEY AUTOINCREMENT”表示“noteId”列为interger型(整型)、主码、新增记录时自动增1。

 新建AIR工程。

 设计应用程序的外观模型。

此实例包括一个DataGrid组件,用以绑定数据。一些输入框及按钮,为数据插入数据库作准备。以下代码是外观模型生成的MXML代码。

<mx:Panel >

    <mx:DataGrid id="dg" verticalScrollPolicy="auto">

        <mx:columns>

            <mx:DataGridColumn headerText="编号" dataField="noteId"/>

            <mx:DataGridColumn headerText="标题" dataField="title"/>

            <mx:DataGridColumn headerText="内容" dataField="content"/>

            <mx:DataGridColumn headerText="发布者" dataField="publisher"/>

        </mx:columns>

    </mx:DataGrid>

    <mx:Canvas height="259" width="401">   

        <mx:Label text="标题" x="10" y="12"/>

        <mx:TextInput x="69" y="10" width="296" id="txtTitle"/>

        <mx:Label text="内容" x="10" y="51"/>

        <mx:TextArea x="69" y="50" width="296" height="110" id="txtContent"/>

        <mx:Label text="发布者" x="10" y="171"/>

        <mx:TextInput  width="92" id="txtPublisher" x="69" y="169"/>

        <mx:Button  label="确定" id="btnOk" click="insertDataHandle();" x="69" y="218"/>

    </mx:Canvas>

</mx:Panel>

设计模式下的外观模型效果如图23-2所示。

图23-2  操作SQL数据库实例的外观效果

 连接“School”数据库。本实例中在工程“bin”文件夹下创建“School.db”数据库,并使用SQLConnection类连接数据库。以下代码创建“School.db”数据库,并使用SQLConnection类连接。

private var conn:SQLConnection = new SQLConnection();   //定义SQLConnection实例

private var dbFile:File = File.applicationResourceDirectory.resolve ("School.db");                                              //定义数据库文件路径

conn.open(dbFile);                                      //打开数据库文件

File类中的resolve方法用以定位文件。若指定路径下的文件不存在将自动创建。

 创建“Notes”表。在连接数据库“School.db”后,创建“Notes”表。方法是使用SQL语句创建。以下代码使用SQLStatement类执行SQL语句,从而创建“Notes”表。

private var createStmt:SQLStatement=new SQLStatement();//定义SQLStatement实例

//数据库文件打开后的处理函数

private function openHandler(e:SQLEvent):void

{

    createStmt.sqlConnection = conn;                    //定义语句连接的数据库

    //sql语句创建表Notes

    var sql:String ="CREATE TABLE IF NOT EXISTS Notes ("

        +"noteId INTEGER PRIMARY KEY AUTOINCREMENT,"

        +"title TEXT,"

        +"content TEXT,"

        +"publisher TEXT"

        +")";

    createStmt.text = sql;

    createStmt.execute();                               //执行sql语句

}

 获得数据集并显示于DataGrid组件中。在执行完创建表的SQL语句后,使用Select语句获取“Notes”表中的全部数据,并绑定至DataGrid组件上。以下代码使用SQLStatement实例createStmt执行Select语句,从而获得“Notes”表中的数据,并显示于DataGrid组件。

//创建完表或已存在表时显示表中的数据

private function createTableResult(e:SQLEvent):void

{

    createStmt.sqlConnection = conn;                    //定义语句连接的数据库

    createStmt.text ="select * from Notes";

    //添加对SQLEvent.RESULT状态的监听

    createStmt.addEventListener(SQLEvent.RESULT,showDataResult);

    createStmt.execute();                                   //执行sql语句

}

//显示数据处理函数

private function showDataResult(event:SQLEvent):void

{

    dg.dataProvider=createStmt.getResult().data;            //绑定数据集

}

 向数据库中插入数据。当单击“确定”按钮时,使用Insert语句将数据插入到数据库中。以下代码使用SQLStatement实例stmt执行Insert语句,从而向“Notes”表中插入新数据。

//插入数据处理函数

private function insertDataHandle():void

{

    var stmt:SQLStatement=new SQLStatement();

    stmt.sqlConnection = conn;                          //定义语句连接的数据库

    stmt.text ="insert into Notes(title,content,publisher) values('"

            +txtTitle.text+"','"

            +txtContent.text+"','"

            +txtPublisher.text+"')";

    stmt.execute();                                     //执行sql语句

}

 完成剩余代码。应用程序剩余的代码包括初始化函数initApp、运行异常处理函数errorHandle、引用不同类等。

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

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

<mx:WindowedApplication width="600"

    fontSize="13" height="500"

xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete ="initApp()">

    <mx:Script>

        <![CDATA[

            import flash.data.SQLConnection;        //引用SQLConnection类

            import flash.data.SQLStatement;         //引用SQLStatement类

            import flash.events.SQLErrorEvent;      //引用SQLErrorEvent类

            import flash.events.SQLEvent;           //引用SQLEvent类

            import flash.filesystem.File;           //引用File类

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

            private var conn:SQLConnection = new SQLConnection();                                                                   //定义SQLConnection实例

private var createStmt:SQLStatement=new SQLStatement();                                                                         //定义SQLStatement实例

            //定义数据库文件路径

            private var dbFile:File = File.applicationResourceDirectory. resolve("School.db");

            //应用程序初始化处理函数

            public function initApp():void

            {

                conn.addEventListener(SQLEvent.OPEN, openHandler);                                                             //监听SQLEvent.OPEN状态

                //监听SQLErrorEvent.ERROR状态

                conn.addEventListener(SQLErrorEvent.ERROR, errorHandle);

                conn.open(dbFile);                  //打开数据库文件

            }

            //数据库文件打开后的处理函数

            private function openHandler(e:SQLEvent):void

            {

                createStmt.sqlConnection = conn;    //定义语句连接的数据库

                //sql语句创建表Notes

                var sql:String ="CREATE TABLE IF NOT EXISTS Notes ("

                    + "noteId INTEGER PRIMARY KEY AUTOINCREMENT,"

                    + "title TEXT,"

                    + "content TEXT,"

                    + "publisher TEXT"

                    + ")";

                createStmt.text = sql;

                //添加对SQLEvent.RESULT状态的监听

                   createStmt.addEventListener(SQLEvent.RESULT,createTableResult);

                //监听SQLErrorEvent.ERROR状态

                   createStmt.addEventListener(SQLErrorEvent.ERROR, errorHandle);

                createStmt.execute();               //执行sql语句

            }

            //创建完表或已存在表时显示表中的数据

            private function createTableResult(e:SQLEvent):void

            {

                createStmt.sqlConnection = conn;    //定义语句连接的数据库

                createStmt.text ="select * from Notes";

                //添加对SQLEvent.RESULT状态的监听

                   createStmt.addEventListener(SQLEvent.RESULT,showDataResult);

                //监听SQLErrorEvent.ERROR状态

                   createStmt.addEventListener(SQLErrorEvent.ERROR, errorHandle);

                createStmt.execute();                           //执行sql语句

            }

            //显示数据处理函数

            private function showDataResult(event:SQLEvent):void

            {

                dg.dataProvider=createStmt.getResult().data;    //绑定数据集

            }

            //插入数据处理函数

            private function insertDataHandle():void

            {

                var stmt:SQLStatement=new SQLStatement();

                stmt.sqlConnection = conn;              //定义语句连接的数据库

                stmt.text ="insert into Notes(title,content,publisher) values('"

                    +txtTitle.text+"','"

                    +txtContent.text+"','"

                    +txtPublisher.text+"')";

                //添加对SQLEvent.RESULT状态的监听

                createStmt.addEventListener(SQLEvent.RESULT,showDataResult);

                //监听SQLErrorEvent.ERROR状态

                stmt.addEventListener(SQLErrorEvent.ERROR, errorHandle);

                stmt.execute();                         //执行sql语句

            }

            //对数据库操作出错时的处理函数

            private function errorHandle(event:SQLErrorEvent):void

            {

                Alert.show("Details:", event.error.message);

            }

        ]]>

    </mx:Script>

    <mx:Panel >

        <!--DataGrid组件,用以显示数据-->

        <mx:DataGrid id="dg" verticalScrollPolicy="auto">

            <mx:columns>

                <mx:DataGridColumn headerText="编号" dataField="noteId"/>

                <mx:DataGridColumn headerText="标题" dataField="title"/>

                <mx:DataGridColumn headerText="内容" dataField="content"/>

                <mx:DataGridColumn headerText="发布者" dataField="publisher"/>

            </mx:columns>

        </mx:DataGrid>

        <mx:Canvas height="259" width="401">   

            <mx:Label text="标题" x="10" y="12"/>

            <mx:TextInput x="69" y="10" width="296" id="txtTitle"/>                                                                 <!--“标题”输入框-->

            <mx:Label text="内容" x="10" y="51"/>

            <!--“内容”输入框-->

              <mx:TextArea x="69" y="50" width="296" height="110" id="txtContent"/>

            <mx:Label text="发布者" x="10" y="171"/>

            <mx:TextInput  width="92" id="txtPublisher" x="69" y="169"/>                                                            <!--"发布者"输入框-->

            <!--按钮组件,用以添加数据-->

            <mx:Button  label="确定" id="btnOk" click="insertDataHandle();" x="69" y="218"/>

        </mx:Canvas>

    </mx:Panel>

</mx:WindowedApplication>

文本框:  
图23-3  操作SQL数据库实例的运行效果

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

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" style="width:800px;height:600px"/>

</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.onload=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" wi