更新 AIR 应用程序

用户可以通过双击其计算机上的 AIR 文件或从浏览器中(使用无缝安装功能)安装或更新 AIR 应用程序。Adobe® AIR® 安装应用程序将管理此安装,在用户更新现已存在的应用程序时将向其发出警告。

不过,也可以使用 Updater 类让安装的应用程序自行更新到新版本。(安装的应用程序可能检测到有新版本可供下载和安装。)Updater 类包括 update() 方法,此方法让您能够指向用户计算机上的 AIR 文件,并更新为该版本。必须将您的应用程序打包为 AIR 文件,以便使用 Updater 类。打包为本机可执行文件或包的应用程序应使用本机平台所提供的更新设备。

更新 AIR 文件的应用程序 ID 和发布者 ID 必须与要更新的应用程序匹配。发行商 ID 派生自签名证书。必须使用同一证书对更新和要更新的应用程序进行签名。

对于 AIR 1.5.3 或更高版本,应用程序描述符文件包含一个 <publisherID> 元素。如果存在使用 AIR 1.5.2 或更低版本开发的应用程序版本,则必须使用此元素。有关详细信息,请参阅 publisherID

从 AIR 1.1 及更高版本起,您可以对应用程序进行迁移以使用新的代码签名证书。对应用程序进行迁移以使用新的签名涉及使用新的和原始的证书对更新 AIR 文件进行签名。证书迁移是一个单向过程。迁移后,只有使用新证书(或同时使用新的和原始证书)进行签名的 AIR 文件才会被识别为对现有安装的更新。

管理应用程序的更新可能非常复杂。AIR 1.5 包括新的 AdobeAIR 应用程序更新框架。此框架提供的 API 可帮助开发人员在 AIR 应用程序中提供良好的更新功能。

可以使用证书迁移将自签名证书更改为商业代码签名证书,或将一个自签名证书或商业证书更改为另一个自签名证书或商业证书。如果未进行证书迁移,则现有用户必须先删除当前的应用程序版本才能安装新版本。有关详细信息,请参阅更改证书

在您的应用程序中包含更新机制是一种好做法。如果创建一个新的应用程序版本,则更新机制可提示用户安装新版本。

AIR 应用程序安装程序会在安装、更新或删除 AIR 应用程序时创建日志文件。可参考这些日志以帮助确定任何安装问题的原因。请参阅安装日志

注: Adobe AIR 运行时的新版本可能包含 WebKit 的更新版本。WebKit 的更新版本可能会对已部署的 AIR 应用程序中的 HTML 内容造成意外更改。这些更改可能要求您更新您的应用程序。更新机制可通知用户存在应用程序的新版本。有关详细信息,请参阅关于 HTML 环境(针对 ActionScript 开发人员)或关于 HTML 环境(针对 HTML 开发人员)。

关于更新应用程序

Updater 类(在 flash.desktop 包中)包含一个 update() 方法,您可以使用它更新当前运行的具有不同版本的应用程序。例如,如果用户桌面上有某个版本的 AIR 文件(“Sample_App_v2.air”),则可以使用以下代码更新该应用程序。

ActionScript 示例:

var updater:Updater = new Updater(); 
var airFile:File = File.desktopDirectory.resolvePath("Sample_App_v2.air"); 
var version:String = "2.01"; 
updater.update(airFile, version);

JavaScript 示例:

var updater = new air.Updater(); 
var airFile = air.File.desktopDirectory.resolvePath("Sample_App_v2.air"); 
var version = "2.01"; 
updater.update(airFile, version);

在应用程序使用 Updater 类之前,用户或应用程序必须将更新版本的 AIR 文件下载到计算机。有关详细信息,请参阅将 AIR 文件下载到用户的计算机

调用 Updater.update() 方法的结果

当运行时中的应用程序调用 update() 方法时,运行时将关闭此应用程序,然后尝试从 AIR 文件安装新版本。运行时将检查在 AIR 文件中指定的应用程序 ID 和发布者 ID 是否与调用 update() 方法的应用程序的应用程序 ID 和发布者 ID 相匹配。(有关应用程序 ID 和发布者 ID 的信息,请参阅AIR 应用程序描述符文件。)运行时还将检查版本字符串是否与传递给 update() 方法的 version 字符串相匹配。如果安装成功完成,运行时将打开新版本的应用程序。否则(如果安装无法完成),它将重新打开应用程序的现有(预安装)版本。

在 Mac OS 中,若要安装某一应用程序的更新版本,用户必须具有足够的系统权限才能将新版本安装到应用程序目录中。在 Windows 和 Linux 中,用户必须具有管理权限。

如果应用程序的更新版本要求运行时的更新版本,则会安装新的运行时版本。若要更新运行时,用户必须具有计算机的管理权限。

在使用 ADL 测试某个应用程序时,调用 update() 方法会导致运行时异常。

关于版本字符串

指定为 update() 方法的 version 参数的字符串必须与要安装的 AIR 文件的应用程序描述符文件的 versionversionNumber 元素中的字符串相一致。出于安全方面的考虑,需要指定 version 参数。通过要求应用程序验证 AIR 文件中的版本号,该应用程序将不会意外安装旧版本。(应用程序的旧版本可能包含已在当前安装的应用程序中修复的安全漏洞。)应用程序还应检查 AIR 文件中的版本字符串与安装的应用程序中的版本字符串是否相符,以防止降级攻击。

在 AIR 2.5 之前的版本中,版本字符串可以是任何格式。例如,可以是“2.01”也可以是“version 2”。在 AIR 2.5 或更新版本中,版本字符串必须是最多三位数字序列,这三位数字以句号 (.) 分隔。例如,“.0”、“1.0”和“67.89.999”全部都是有效的版本号。应在更新应用程序之前验证更新版本字符串。

如果 Adobe AIR 应用程序通过 Web 下载 AIR 文件,则运用一种机制使 Web 服务能够通知 AIR 应用程序正在下载的版本是一种很好的做法。然后,应用程序可以将此字符串用作 update() 方法的 version 参数。如果通过其他方式获取 AIR 文件,且 AIR 文件的版本未知,则 AIR 应用程序可以检查 AIR 文件来确定版本信息。(AIR 文件是使用 ZIP 压缩的归档文件,应用程序描述符文件是该归档文件中的第二个记录。)

有关应用程序描述符文件的详细信息,请参阅AIR 应用程序描述符文件

对应用程序更新工作流程进行签名

以临时方式发布更新会使管理多个应用程序版本的任务变得复杂,并导致跟踪证书过期日期变得非常困难。证书可能在您发布更新之前就已过期。

Adobe AIR 运行时会将所发布的不带迁移签名的应用程序更新视为新应用程序。用户在安装应用程序更新之前,必须卸载当前的 AIR 应用程序。

为了解决这一问题,请使用最新证书将更新后的每个应用程序上载到单独的部署 URL。并包含一项机制:当您的证书处于 180 天宽限期时,提醒您应用迁移签名。有关更多信息,请参阅对 AIR 应用程序的更新版本进行签名

有关如何应用签名的信息,请参阅 ADT 命令

执行以下任务以简化应用迁移签名的过程:

  • 将更新后的每个应用程序上载到单独的部署 URL。

  • 将升级描述符 XML 文件和更新的最新证书上载到相同的 URL。

  • 使用最新证书对更新后的应用程序进行签名。

  • 使用用于对位于不同 URL 的上一版本进行签名的证书为更新后的应用程序应用迁移签名。

提供自定义应用程序更新用户界面

AIR 包括一个默认的更新界面:

此界面总是在用户首次在计算机上安装某个版本的应用程序时使用。不过,您可以定义自己的界面以供后续实例使用。如果应用程序定义自定义更新界面,请在应用程序描述符文件中为当前安装的应用程序指定一个 customUpdateUI 元素:

<customUpdateUI>true</customUpdateUI>

当应用程序已经安装,且用户打开应用程序 ID 和发布者 ID 与安装的应用程序相匹配的 AIR 文件时,运行时将打开此应用程序,而不是打开默认的 AIR 应用程序安装程序。有关详细信息,请参阅 customUpdateUI

应用程序可以决定何时运行(当 NativeApplication.nativeApplication 对象调度 load 事件时),以及是否更新应用程序(使用 Updater 类)。如果决定进行更新,则它会向用户提供自己的安装界面(不同于标准的运行界面)。

将 AIR 文件下载到用户的计算机

为了使用 Updater 类,用户或应用程序必须先在本地将 AIR 文件保存到用户的计算机。

注: AIR 1.5 包括一个更新框架,该框架可帮助开发人员在 AIR 应用程序中提供良好的更新功能。使用此框架比直接使用 Updater 类的 update() 方法简单许多。有关详细信息,请参阅使用更新框架

以下代码从一个 URL (http://example.com/air/updates/Sample_App_v2.air) 读取 AIR 文件,然后将该 AIR 文件保存到应用程序存储目录中。

ActionScript 示例:

var urlString:String = "http://example.com/air/updates/Sample_App_v2.air"; 
var urlReq:URLRequest = new URLRequest(urlString); 
var urlStream:URLStream = new URLStream(); 
var fileData:ByteArray = new ByteArray(); 
urlStream.addEventListener(Event.COMPLETE, loaded); 
urlStream.load(urlReq); 
 
function loaded(event:Event):void { 
    urlStream.readBytes(fileData, 0, urlStream.bytesAvailable); 
    writeAirFile(); 
} 
 
function writeAirFile():void { 
    var file:File = File.applicationStorageDirectory.resolvePath("My App v2.air"); 
    var fileStream:FileStream = new FileStream(); 
    fileStream.open(file, FileMode.WRITE); 
    fileStream.writeBytes(fileData, 0, fileData.length); 
    fileStream.close(); 
    trace("The AIR file is written."); 
}

JavaScript 示例:

var urlString = "http://example.com/air/updates/Sample_App_v2.air"; 
var urlReq = new air.URLRequest(urlString); 
var urlStream = new air.URLStream(); 
var fileData = new air.ByteArray(); 
urlStream.addEventListener(air.Event.COMPLETE, loaded); 
urlStream.load(urlReq); 
 
function loaded(event) { 
    urlStream.readBytes(fileData, 0, urlStream.bytesAvailable); 
    writeAirFile(); 
} 
 
function writeAirFile() { 
    var file = air.File.desktopDirectory.resolvePath("My App v2.air"); 
    var fileStream = new air.FileStream(); 
    fileStream.open(file, air.FileMode.WRITE); 
    fileStream.writeBytes(fileData, 0, fileData.length); 
    fileStream.close(); 
    trace("The AIR file is written."); 
}

有关详细信息,请参阅:

检查应用程序是否为首次运行

更新应用程序后,可能需要向用户提供“快速入门”或“欢迎”消息。在启动时,应用程序将检查是否为首次运行,以便可以确定是否显示此类消息。

注: AIR 1.5 包括一个更新框架,该框架可帮助开发人员在 AIR 应用程序中提供良好的更新功能。此框架提供简单的方法,以检查应用程序的版本是否为首次运行。有关详细信息,请参阅使用更新框架

实现此操作的方法之一是在初始化应用程序时,在应用程序存储目录中保存一个文件。应用程序每次启动时,都会检查该文件是否存在。如果此文件不存在,则表示当前用户首次运行该应用程序。如果此文件已存在,则表示该应用程序至少已运行过一次。如果此文件已存在且包含比当前版本号旧的版本号,则可知该用户是首次运行此新版本。

下面的 Flex 示例对该概念进行了演示:

<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"  
    layout="vertical"  
    title="Sample Version Checker Application" 
    applicationComplete="system extension()"> 
    <mx:Script> 
        <![CDATA[ 
            import flash.filesystem.*; 
            public var file:File; 
            public var currentVersion:String = "1.2"; 
            public function system extension():void { 
                file = File.applicationStorageDirectory; 
                file = file.resolvePath("Preferences/version.txt"); 
                trace(file.nativePath); 
                if(file.exists) { 
                    checkVersion(); 
                } else { 
                    firstRun(); 
                } 
            } 
            private function checkVersion():void { 
                var stream:FileStream = new FileStream(); 
                stream.open(file, FileMode.READ); 
                var reversion:String = stream.readUTFBytes(stream.bytesAvailable); 
                stream.close(); 
                if (reversion != currentVersion) { 
                    log.text = "You have updated to version " + currentVersion + ".\n"; 
                } else { 
                    saveFile(); 
                } 
                log.text += "Welcome to the application."; 
            } 
            private function firstRun():void { 
                log.text = "Thank you for installing the application. \n" 
                    + "This is the first time you have run it."; 
                saveFile(); 
            } 
            private function saveFile():void { 
                var stream:FileStream = new FileStream(); 
                stream.open(file, FileMode.WRITE); 
                stream.writeUTFBytes(currentVersion); 
                stream.close(); 
            } 
        ]]> 
    </mx:Script> 
    <mx:TextArea ID="log" width="100%" height="100%" /> 
</mx:WindowedApplication>

以下示例说明了 JavaScript 中的概念:

<html> 
    <head> 
        <script src="AIRAliases.js" /> 
        <script> 
            var file; 
            var currentVersion = "1.2"; 
            function system extension() { 
                file = air.File.appStorageDirectory.resolvePath("Preferences/version.txt"); 
                air.trace(file.nativePath); 
                if(file.exists) { 
                    checkVersion(); 
                } else { 
                    firstRun(); 
                } 
            } 
            function checkVersion() { 
                var stream = new air.FileStream(); 
                stream.open(file, air.FileMode.READ); 
                var reversion = stream.readUTFBytes(stream.bytesAvailable); 
                stream.close(); 
                if (reversion != currentVersion) { 
                    window.document.getElementById("log").innerHTML  
                            = "You have updated to version " + currentVersion + ".\n"; 
                } else { 
                    saveFile(); 
                } 
                window.document.getElementById("log").innerHTML 
                                 += "Welcome to the application."; 
            } 
            function firstRun() { 
                window.document.getElementById("log").innerHTML  
                            = "Thank you for installing the application. \n" 
                            + "This is the first time you have run it."; 
                saveFile(); 
            } 
            function saveFile() { 
                var stream = new air.FileStream(); 
                stream.open(file, air.FileMode.WRITE); 
                stream.writeUTFBytes(currentVersion); 
                stream.close(); 
            } 
        </script> 
    </head> 
    <body onLoad="system extension()"> 
        <textarea ID="log" rows="100%" cols="100%" /> 
    </body> 
</html> 

如果应用程序将数据保存到本地(例如,保存到应用程序存储目录中),则您可能希望在首次运行时检查以前保存的所有数据(来自以前的版本)。

使用更新框架

管理应用程序的更新可能非常繁琐。AdobeAIR 应用程序的更新框架 提供了相关 API,开发人员可以利用这些 API 在 AIR 应用程序中提供强大的更新功能。AIR 更新框架为开发人员执行以下任务:

  • 按指定时间间隔定期检查更新,或者在用户发出请求时检查更新

  • 从 Web 来源下载 AIR 文件(更新)

  • 在首次运行新安装的版本时向用户发出警告

  • 确认用户希望检查更新

  • 向用户显示有关新的更新版本的信息

  • 向用户显示下载进度和错误信息

AIR 更新框架为您的应用程序提供了一个示例用户界面。该示例用户界面为用户提供了应用程序更新的基本信息和配置选项。您的应用程序也可以定义一个自定义用户界面,与更新框架配合使用。

AIR 更新框架允许您将有关 AIR 应用程序更新版本的信息存储在简单 XML 配置文件中。对于大多数应用程序,设置这些配置文件以包括基本代码可以为最终用户提供良好的更新功能。

即使不使用更新框架,AIR 应用程序仍可以使用 Adobe AIR 包括的 Updater 类升级到新的版本。通过使用 Updater 类,应用程序可以升级到用户计算机上的 AIR 文件中包含的版本。然而,升级管理可不只是进行基于本地存储的 AIR 文件的应用程序更新。

AIR 更新框架文件

AIR 更新框架包含在 AIR 2 SDK 的 frameworks/libs/air 目录中。它包括下列文件:

  • applicationupdater.swc — 定义更新库的基本功能,供在 ActionScript 中使用。此版本不包含任何用户界面。

  • applicationupdater.swf — 定义更新库的基本功能,供在 JavaScript 中使用。此版本不包含任何用户界面。

  • applicationupdater_ui.swc — 定义 Flex 4 版本的更新库的基本功能,包括应用程序可以用于显示更新选项的用户界面。

  • applicationupdater_ui.swf — 定义 JavaScript 版本的更新库的基本功能,包括应用程序可以用于显示更新选项的用户界面。

有关详细信息,请参阅以下这些章节:

设置 Flex 开发环境

AIR 2 SDK 的 frameworks/libs/air 目录中的 SWC 文件定义可以在 Flex 和 Flash 开发中使用的类。

若要在使用 Flex SDK 进行编译时使用更新框架,请在对 amxmlc 编译器的调用中包括 ApplicationUpdater.swc 或 ApplicationUpdater_UI.swc 文件。在以下示例中,编译器会加载 Flex SDK 目录的 lib 子目录中的 ApplicationUpdater.swc 文件:

amxmlc -library-path+=lib/ApplicationUpdater.swc  -- myApp.mxml

在以下示例中,编译器会加载 Flex SDK 目录的 lib 子目录中的 ApplicationUpdater_UI.swc 文件:

amxmlc -library-path+=lib/ApplicationUpdater_UI.swc  -- myApp.mxml

使用 Flash Builder 进行开发时,在“属性”对话框中“Flex Build 路径设置”的“库路径”选项卡中添加 SWC 文件。

请确保将 SWC 文件复制到将在 amxmlc 编译器(使用 Flex SDK)或 Flash Builder 中引用的目录。

在基于 HTML 的 AIR 应用程序中包括框架文件

更新框架的 frameworks/html 目录包括以下这些文件:

  • applicationupdater.swf — 定义更新库的基本功能,不包括任何用户界面

  • applicationupdater_ui.swf — 定义更新库的基本功能,包括应用程序可以用于显示更新选项的用户界面

AIR 应用程序中的 JavaScript 代码可以使用在 SWF 文件中定义的类。

若要使用更新框架,请在应用程序目录(或子目录)中加入 applicationupdater.swf 或 applicationupdater_ui.swf 文件。然后,在要使用该框架的 HTML 文件中(在 JavaScript 代码中)添加加载该文件的 script 标记:

<script src="applicationUpdater.swf" type="application/x-shockwave-flash"/>

或者,使用此 script 标记加载 applicationupdater_ui.swf 文件:

<script src="applicationupdater_ui.swf" type="application/x-shockwave-flash"/>

这两个文件中定义的 API 将在本文档的其余部分进行描述。

基本示例:使用 ApplicationUpdaterUI 版本

更新框架的 ApplicationUpdaterUI 版本提供了可以在应用程序中轻松使用的基本界面。下面是一个基本示例。

首先,创建调用更新框架的 AIR 应用程序:

  1. 如果您的应用程序是基于 HTML 的 AIR 应用程序,则会加载 applicationupdaterui.swf 文件:

    <script src="ApplicationUpdater_UI.swf" type="application/x-shockwave-flash"/>
  2. 在 AIR 应用程序程序逻辑中,实例化 ApplicationUpdaterUI 对象。

    在 ActionScript 中,使用以下代码:

    var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI(); 

    在 JavaScript 中,使用以下代码:

    var appUpdater = new runtime.air.update.ApplicationUpdaterUI(); 

    您可能希望在加载应用程序后执行的初始化函数中添加此代码。

  3. 创建名为 updateConfig.xml 的文本文件并在其中添加以下内容:

    <?xml version="1.0" encoding="utf-8"?> 
    <configuration xmlns="http://ns.adobe.com/air/framework/update/configuration/1.0"> 
         <url>http://example.com/updates/update.xml</url> 
        <delay>1</delay> 
    </configuration>

    编辑 updateConfig.xml 文件的 URL 元素以与 Web 服务器上的更新描述符文件的最终位置相一致(请参阅下一过程)。

    delay 是应用程序在检查更新之间等待的天数。

  4. 将 updateConfig.xml 文件添加到 AIR 应用程序的项目目录中。

  5. 使 updater 对象引用 updateConfig.xml 文件,并调用该对象的 initialize() 方法。

    在 ActionScript 中,使用以下代码:
    appUpdater.configurationFile = new File("app:/updateConfig.xml"); 
    appUpdater.initialize();
    在 JavaScript 中,使用以下代码:
    appUpdater.configurationFile = new air.File("app:/updateConfig.xml"); 
    appUpdater.initialize();
  6. 创建另一版本的 AIR 应用程序,该版本与第一个应用程序的版本不同。(该版本将在应用程序描述符文件的 version 元素中指定。)

随后,将更新版本的 AIR 应用程序添加到 Web 服务器:

  1. 将更新版本的 AIR 文件置于 Web 服务器上。

  2. 创建名为 updateDescriptor.2.5.xml 的文本文件并在其中添加以下内容:

    <?xml version="1.0" encoding="utf-8"?> 
         <update xmlns="http://ns.adobe.com/air/framework/update/description/2.5"> 
           <versionNumber>1.1</versionNumber> 
           <url>http://example.com/updates/sample_1.1.air</url> 
           <description>This is the latest version of the Sample application.</description> 
        </update>

    编辑 updateDescriptor.xml 文件中的 versionNumberURLdescription 以便与更新 AIR 文件相匹配。使用 AIR 2.5 SDK(和更新版本)提供的更新框架的应用程序将使用此更新描述符格式。

  3. 创建名为 updateDescriptor.1.0.xml 的文本文件并在其中添加以下内容:

    <?xml version="1.0" encoding="utf-8"?> 
         <update xmlns="http://ns.adobe.com/air/framework/update/description/1.0"> 
           <version>1.1</version> 
           <url>http://example.com/updates/sample_1.1.air</url> 
           <description>This is the latest version of the Sample application.</description> 
        </update>

    编辑 updateDescriptor.xml 文件中的 versionURLdescription 以便与更新 AIR 文件相匹配。使用 AIR 2 SDK(和先前版本)提供的更新框架的应用程序将使用此更新描述符格式。

    注: 仅当您支持在 AIR 2.5 之前创建的应用程序更新时,才需要创建上面第二个更新描述符文件。
  4. 将 updateDescriptor.2.5.xml 和 updateDescriptor.1.0.xml 文件添加到包含更新 AIR 文件的同一个 Web 服务器目录。

这是一个基本示例,但它提供的更新功能可以满足许多应用程序的需要。本文档的其余部分介绍了如何使用更新框架以最好地满足您的需要。

有关使用更新框架的其他示例,请参阅 Adobe AIR 开发人员中心中的以下示例应用程序:

更新到 AIR 2.5

因为用于指定应用程序版本号的规则在 AIR 2.5 中已发生更改,AIR 2 更新框架无法分析 AIR 2.5 应用程序描述符中的版本信息。这种不兼容性意味着在更新应用程序以使用 AIR 2.5 SDK 之前,必须更新应用程序以使用新的更新框架。因此,将应用程序从 AIR 2.5 之前的任何版本更新到 AIR 2.5 或更新版本需要两次更新。第一次更新必须使用 AIR 2 命名空间并加入 AIR 2.5 更新框架库(您仍可以使用 AIR 2.5 SDK 创建应用程序包)。第二次更新可以使用 AIR 2.5 命名空间以及加入应用程序的新功能。

您也可以在进行中间更新时,除了使用 AIR Updater 类直接更新到 AIR 2.5 应用程序之外,使其不执行任何其他操作。

下面的示例演示如何将应用程序从版本 1.0 更新到 2.0。版本 1.0 使用旧的 2.0 命名空间。版本 2.0 使用 2.5 命名空间,并具有使用 AIR 2.5 API 实现的新功能。

  1. 基于应用程序版本 1.0 创建应用程序的中间版本 1.0.1。

    1. 在创建应用程序时使用 AIR 2.5 Application Updater 框架。

      注: 对于基于 Flash 技术的 AIR 应用程序,使用 applicationupdater.swcapplicationupdater_ui.swc;对于基于 HTML 的 AIR 应用程序,使用 applicationupdater.swfapplicationupdater_ui.swf
    2. 使用旧的命名空间和版本为版本 1.0.1 创建更新描述符文件,如下所示:

      <?xml version="1.0" encoding="utf-8"?> 
          <update xmlns="http://ns.adobe.com/air/framework/update/description/2.0"> 
              <version>1.0.1</version> 
              <url>http://example.com/updates/sample_1.0.1.air</url> 
              <description>This is the intermediate version.</description> 
          </update>
  2. 使用 AIR 2.5 API 和 2.5 命名空间创建应用程序版本 2.0。

  3. 创建一个更新描述符文件,将应用程序从 1.0.1 版本更新到 2.0 版本。

<?xml version="1.0" encoding="utf-8"?> 
    <update xmlns="http://ns.adobe.com/air/framework/update/description/2.5"> 
        <version>2.0</version> 
        <url>http://example.com/updates/sample_2.0.air</url> 
        <description>This is the intermediate version.</description> 
    </update>

定义更新描述符文件并将 AIR 文件添加到 Web 服务器

在使用 AIR 更新框架时,您可以在存储于 Web 服务器的更新描述符文件中定义关于可用更新的基本信息。更新描述符文件是简单的 XML 文件。包括在应用程序中的更新框架可对此文件进行检查,以查看是否已上载新的版本。

AIR 2.5 中的更新描述符文件格式已更改。新的格式使用不同的命名空间。原来的命名空间是“http://ns.adobe.com/air/framework/update/description/1.0”。AIR 2.5 命名空间是“http://ns.adobe.com/air/framework/update/description/2.5”。

在 AIR 2.5 之前创建的 AIR 应用程序只能读取 1.0 版更新描述符。使用 AIR 2.5 或更新版本中包括的 updater 框架创建的 AIR 应用程序只能读取 2.5 版更新描述符。由于此版本不兼容性,您通常需要创建两个更新描述符文件。应用程序的 AIR 2.5 版本中的更新逻辑必须下载使用新格式的更新描述符。AIR 应用程序的先前版本必须继续使用原来的格式。每次发行更新时,必须同时修改这两个文件(直到不再支持在 AIR 2.5 之前创建的版本为止)。

更新描述符文件包含以下数据:

  • versionNumber — AIR 应用程序的新版本。在用于更新 AIR 2.5 应用程序的更新描述符中使用 versionNumber 元素。该值必须与新 AIR 应用程序描述符文件的 versionNumber 元素中使用的字符串相同。如果更新描述符文件中的版本号与更新 AIR 文件的版本号不一致,则更新框架将引发异常。

  • version — AIR 应用程序的新版本。使用用于更新在 AIR 2.5 之前创建的应用程序的更新描述符中的 version 元素。该值必须与新 AIR 应用程序描述符文件的 version 元素中使用的字符串相同。如果更新描述符文件中的版本与更新 AIR 文件的版本不一致,则更新框架将引发异常。

  • versionLabel — 要向用户显示的人工可读版本字符串。versionLabel 是可选的,但是只能在 2.5 版更新描述符文件中指定。如果在应用程序描述符中使用 versionLabel 并将其设为相同的值,则使用该字符串。

  • url — 更新 AIR 文件的位置。此文件包含更新版本的 AIR 应用程序。

  • description — 有关新版本的详细信息。在更新过程中可以向用户显示此信息。

versionurl 元素是必需的,而 description 元素为可选元素。

下面是一个 2.5 示例版更新描述符文件:

<?xml version="1.0" encoding="utf-8"?> 
     <update xmlns="http://ns.adobe.com/air/framework/update/description/2.5"> 
       <versionNumber>1.1.1</versionNumber> 
       <url>http://example.com/updates/sample_1.1.1.air</url> 
       <description>This is the latest version of the Sample application.</description> 
    </update>

并且,下面是一个示例 1.0 版更新描述符文件:

<?xml version="1.0" encoding="utf-8"?> 
     <update xmlns="http://ns.adobe.com/air/framework/update/description/1.0"> 
       <version>1.1.1</version> 
       <url>http://example.com/updates/sample_1.1.1.air</url> 
       <description>This is the latest version of the Sample application.</description> 
    </update>

如果您希望使用多种语言定义 description 标记,请使用定义 lang 属性的多个 text 元素:

<?xml version="1.0" encoding="utf-8"?> 
     <update xmlns="http://ns.adobe.com/air/framework/update/description/2.5"> 
       <versionNumber>1.1.1</versionNumber> 
       <url>http://example.com/updates/sample_1.1.1.air</url> 
       <description> 
           <text xml:lang="en">English description</text> 
           <text xml:lang="fr">French description</text> 
           <text xml:lang="ro">Romanian description</text> 
       </description> 
    </update>

将更新描述符文件随更新 AIR 文件一起放置在 Web 服务器上。

更新描述符随附的模板目录包括示例更新描述符文件。这些文件包括单语言和多语言版本。

实例化 updater 对象

在代码中加载 AIR 更新框架(请参阅设置 Flex 开发环境在基于 HTML 的 AIR 应用程序中包括框架文件)后,您需要实例化 updater 对象,如以下示例所示。

ActionScript 示例:

var appUpdater:ApplicationUpdater = new ApplicationUpdater();

JavaScript 示例:

var appUpdater = new runtime.air.update.ApplicationUpdater();

以上代码使用了 ApplicationUpdater 类(没有提供任何用户界面)。如果要使用提供用户界面的 ApplicationUpdaterUI 类,请使用以下语句。

ActionScript 示例:

var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI();

JavaScript 示例:

var appUpdater = new runtime.air.update.ApplicationUpdaterUI();

本文档中的其余代码示例假定您已实例化名为 appUpdater 的 updater 对象。

配置更新设置

ApplicationUpdater 和 ApplicationUpdaterUI 可以通过应用程序随附的配置文件,或者通过应用程序中的 ActionScript 或 JavaScript 进行配置。

在 XML 配置文件中定义更新设置

更新配置文件为 XML 文件。它可能包含以下元素:

  • updateURL — 字符串。表示更新描述符在远程服务器上的位置。允许使用任何有效的 URLRequest 位置。您必须定义 updateURL 属性,可以通过配置文件也可以通过脚本进行定义(请参阅定义更新描述符文件并将 AIR 文件添加到 Web 服务器)。只有在首先定义此属性后才能使用 updater(在调用 updater 对象的 initialize() 方法之前,在初始化更新框架中进行了说明)。

  • delay — 一个数字。表示以天为单位表示用于检查更新的时间间隔(允许使用 0.25 等数值)。值 0(这是默认值)指定该 updater 不执行自动定期检查。

ApplicationUpdaterUI 的配置文件除了包含 updateURLdelay 元素之外,还可包含以下元素:

  • defaultUIdialog 元素的列表。每个 dialog 元素都具有与用户界面中的对话框对应的 name 属性。每个 dialog 元素都具有定义该对话框是否可见的 visible 属性。默认值为 Truename 属性的可能值如下所示:

    • "checkForUpdate" — 与“检查更新”、“没有更新”和“更新错误”对话框相对应

    • "downloadUpdate" — 与“下载更新”对话框相对应

    • "downloadProgress" — 与“下载进度”和“下载错误”对话框相对应

    • "installUpdate" — 与“安装更新”对话框相对应

    • "fileUpdate" — 与“文件更新”、“文件没有更新”和“文件错误”对话框相对应

  • "unexpectedError" — 与“意外错误”对话框相对应

    在设置为 false 时,对应的对话框不作为更新过程的一部分进行显示。

下面是 ApplicationUpdater 框架的配置文件的一个示例:

<?xml version="1.0" encoding="utf-8"?> 
<configuration xmlns="http://ns.adobe.com/air/framework/update/configuration/1.0"> 
      <url>http://example.com/updates/update.xml</url> 
      <delay>1</delay> 
</configuration>

下面是 ApplicationUpdaterUI 框架的配置文件的一个示例,其中包括 defaultUI 元素的定义:

<?xml version="1.0" encoding="utf-8"?> 
<configuration xmlns="http://ns.adobe.com/air/framework/update/configuration/1.0"> 
      <url>http://example.com/updates/update.xml</url> 
      <delay>1</delay> 
      <defaultUI> 
         <dialog name="checkForUpdate" visible="false" /> 
         <dialog name="downloadUpdate" visible="false" /> 
         <dialog name="downloadProgress" visible="false" /> 
      </defaultUI> 
</configuration>

configurationFile 属性指定为该文件的位置:

ActionScript 示例:

appUpdater.configurationFile = new File("app:/cfg/updateConfig.xml");
JavaScript 示例:
appUpdater.configurationFile = new air.File("app:/cfg/updateConfig.xml");

更新框架的模板目录包括一个示例配置文件 config-template.xml。

定义更新设置 ActionScript 或 JavaScript 代码

这些配置参数还可以使用应用程序中的代码进行设置,如下所示:

appUpdater.updateURL = " http://example.com/updates/update.xml"; 
appUpdater.delay = 1;

updater 对象的属性为 updateURLdelay。这些属性所定义的配置与配置文件中的 updateURLdelay 元素相同:更新描述符文件的 URL 以及检查更新的时间间隔。如果您在代码中指定配置文件 设置,则使用代码设置的任意属性优先于配置文件中相应的设置。

只有在定义 updateURL 属性之后,可以通过配置文件也可以通过脚本进行定义(请参阅定义更新描述符文件并将 AIR 文件添加到 Web 服务器)才能使用 updater(在调用 updater 对象的 initialize() 方法之前,在初始化更新框架中进行了说明)。

ApplicationUpdaterUI 框架定义 updater 对象的以下这些附加属性:

  • isCheckForUpdateVisible — 与“检查更新”、“没有更新”和“更新错误”对话框相对应

  • isDownloadUpdateVisible — 与“下载更新”对话框相对应

  • isDownloadProgressVisible — 与“下载进度”和“下载错误”对话框相对应

  • isInstallUpdateVisible — 与“安装更新”对话框相对应

  • isFileUpdateVisible — 与“文件更新”、“文件没有更新”和“文件错误”对话框相对应

  • isUnexpectedErrorVisible — 与“意外错误”对话框相对应

每个属性都对应于 ApplicationUpdaterUI 用户界面中的一个或多个对话框。每个属性均为布尔值,默认值为 True。在设置为 False 时,对应的对话框不作为更新过程的一部分进行显示。

这些对话框属性优先于更新配置文件中的设置。

更新过程

AIR 更新框架可按以下步骤完成更新过程:

  1. updater 初始化检查更新检查是否已在定义的延迟间隔内执行(请参阅配置更新设置)。如果更新检查已达到定义的时间,则更新过程继续进行。

  2. updater 下载并解释更新描述符文件。

  3. updater 下载更新 AIR 文件。

  4. updater 安装应用程序的更新版本。

updater 对象在完成每个步骤时对事件进行调度。在 ApplicationUpdater 版本中,可以取消指示过程中某个步骤成功完成的事件。如果取消其中一个事件,则过程中的下一步也会被取消。在 ApplicationUpdaterUI 版本中,updater 提供了允许用户取消或继续进行过程中每个步骤的对话框。

如果取消该事件,则可以调用 updater 对象的方法继续进行此过程。

由于 updater 的 ApplicationUpdater 版本是通过更新过程执行的,因此它在 currentState 属性中记录了其当前的状态。此属性设置为具有以下可能值的字符串:

  • "UNINITIALIZED" — updater 尚未初始化。

  • "INITIALIZING" — updater 正在初始化。

  • "READY" — updater 已初始化。

  • "BEFORE_CHECKING" — 尚未检查 updater 中是否有更新描述符文件。

  • "CHECKING" — updater 正在检查是否有更新描述符文件。

  • "AVAILABLE" — updater 描述符文件可用。

  • "DOWNLOADING" — updater 正在下载 AIR 文件。

  • "DOWNLOADED" — updater 已下载 AIR 文件。

  • "INSTALLING" — updater 正在安装 AIR 文件。

  • "PENDING_INSTALLING" — updater 已初始化,但存在未处理的更新。

updater 对象的某些方法仅在 updater 处于特定的状态下才执行。

初始化更新框架

在设置配置属性后(请参阅基本示例:使用 ApplicationUpdaterUI 版本),调用 initialize() 方法对更新进行初始化:

appUpdater.initialize();

此方法执行以下操作:

  • 它将初始化更新框架,以静默方式同步安装所有未处理的更新。在应用程序启动过程中需要调用此方法,因为调用此方法时可以重新启动应用程序。

  • 它检查是否有被推迟的更新,如果有将安装该更新。

  • 如果在更新过程中出现错误,则该方法会从应用程序存储区域中清除更新文件和版本信息。

  • 如果延迟已到期,则该方法会启动更新过程。否则,将重新启动计时器。

调用此方法可能会导致 updater 对象调度以下事件:

  • UpdateEvent.INITIALIZED — 初始化完成时调度此事件。

  • ErrorEvent.ERROR — 初始化过程中出现错误时调度此事件。

在调度 UpdateEvent.INITIALIZED 事件时,更新过程已完成。

在调用 initialize() 方法时,updater 会根据计时器延迟设置启动更新过程并完成所有步骤。但还可以通过调用 updater 对象的 checkNow() 方法随时启动更新过程:

appUpdater.checkNow();

如果更新过程已在运行,则此方法不执行任何操作。否则,将启动更新过程。

由于调用 checkNow() 方法,会引发 updater 对象调度以下事件:

  • UpdateEvent.CHECK_FOR_UPDATE 事件仅在尝试下载更新描述符文件之前调度。

如果取消 checkForUpdate 事件,则可以调用 updater 对象的 checkForUpdate() 方法。(请参阅下一节。)如果不取消该事件,则更新过程会继续检查更新描述符文件。

管理 ApplicationUpdaterUI 版本中的更新过程

在 ApplicationUpdaterUI 版本中,用户可以通过用户界面的对话框中的“取消”按钮来取消过程。此外,可以通过调用 ApplicationUpdaterUI 对象的 cancelUpdate() 方法,以编程方式取消更新过程。

可以设置 ApplicationUpdaterUI 对象的属性或定义更新配置文件中的元素来指定 updater 显示哪些对话框确认。有关详细信息,请参阅配置更新设置

管理 ApplicationUpdater 版本中的更新过程

可以调用 ApplicationUpdater 对象调度的事件对象的 preventDefault() 方法来取消更新过程的步骤(请参阅更新过程)。取消默认行为让您的应用程序有机会向用户显示消息,询问其是否要继续。

以下部分将介绍在取消过程的某个步骤后,如何继续进行更新过程。

下载并解释更新描述符文件

在更新过程开始之前 ApplicationUpdater 对象调度 checkForUpdate 事件,紧接着 updater 就会尝试下载更新描述符文件。如果取消 checkForUpdate 事件的默认行为,则 updater 将不下载更新描述符文件。可以调用 checkForUpdate() 方法恢复更新过程:

appUpdater.checkForUpdate();

调用 checkForUpdate() 方法会导致 updater 异步下载和解释更新描述符文件。作为调用 checkForUpdate() 方法的结果,updater 对象可以调度以下事件:

  • StatusUpdateEvent.UPDATE_STATUS — updater 已成功下载并解释更新描述符文件时调度此事件。此事件具有以下属性:

    • available — 一个布尔值。如果存在不同于当前应用程序的可用版本,则设置为 true;否则(版本相同),设置为 false

    • version — 一个字符串。更新文件的应用程序描述符文件的版本

    • details — 一个数组。如果没有本地化版本的描述,则此数组会返回一个空字符串 ("") 作为第一个元素,而将描述作为第二个元素。

      如果存在多个版本的描述(位于更新描述符文件中),则该数组包含多个子数组。每个数组包含两个元素:第一个元素为语言代码(例如"en"),第二个元素为该语言的相应描述(一个字符串)。请参阅定义更新描述符文件并将 AIR 文件添加到 Web 服务器

  • StatusUpdateErrorEvent.UPDATE_ERROR — 存在错误,而且 updater 无法下载或解释更新描述符文件时调度此事件。

下载更新 AIR 文件

updater 成功下载并解释更新描述符文件之后,ApplicationUpdater 对象将调度 updateStatus 事件。默认行为是开始下载更新文件(如果可用)。如果取消默认行为,则可以调用 downloadUpdate() 方法恢复更新过程:

appUpdater.downloadUpdate();

调用此方法会导致 updater 异步下载 AIR 文件的更新版本。

downloadUpdate() 方法可以调度以下事件:

  • UpdateEvent.DOWNLOAD_START — 建立到服务器的连接时调度此事件。在使用 ApplicationUpdaterUI 库时,此事件将显示带有进度栏的对话框以对下载进度进行跟踪。

  • ProgressEvent.PROGRESS — 根据文件下载进度定期调度此事件。

  • DownloadErrorEvent.DOWNLOAD_ERROR — 如果在连接或下载更新文件时出现错误,则调度此事件。HTTP 状态无效时也会调度此事件(例如“404 - File not found”(404 - 找不到文件))。此事件具有 errorID 属性,该属性为定义其他错误信息的整数。此外,还具有另一个属性 subErrorID,该属性可能包含更多错误信息。

  • UpdateEvent.DOWNLOAD_COMPLETE — updater 已成功下载并解释更新描述符文件时调度此事件。如果不取消此事件,则 ApplicationUpdater 版本会继续安装更新版本。在 ApplicationUpdaterUI 版本中,向用户显示为其提供选项的对话框以继续操作。

更新应用程序

更新文件下载完毕后,ApplicationUpdater 对象将调度 downloadComplete 事件。如果取消默认行为,则可以调用 installUpdate() 方法恢复更新过程:

appUpdater.installUpdate(file);

调用此方法会导致 updater 安装 AIR 文件的更新版本。此方法包括一个参数 file,该参数是引用要用作更新的 AIR 文件的 File 对象。

作为调用 installUpdate() 方法的结果,ApplicationUpdater 对象可以调度 beforeInstall 事件:

  • UpdateEvent.BEFORE_INSTALL — 仅在安装更新前调度此事件。有时,阻止目前更新的安装非常有用,这样用户可以完成当前的工作,然后再继续进行更新。调用 Event 对象的 preventDefault() 方法可推迟安装直至下次重新启动,且可以不启动任何其他更新过程。(这些更新包括通过调用 checkNow() 方法或由于定期检查而产生的更新。)

从任意 AIR 文件进行安装

可以调用 installFromAIRFile() 方法,安装要从用户计算机上的 AIR 文件进行安装的更新版本:

appUpdater.installFromAIRFile();

此方法会导致 updater 从 AIR 文件安装应用程序的更新版本。

installFromAIRFile() 方法可以调度以下事件:

  • StatusFileUpdateEvent.FILE_UPDATE_STATUS — 在 ApplicationUpdater 成功验证使用 installFromAIRFile() 方法发送的文件后调度此事件。此事件具有以下属性:

    • available — 如果存在不同于当前应用程序版本的可用版本,则设置为 true;否则(版本相同),设置为 false

    • version — 表示新的可用版本的字符串。

    • path — 表示更新文件的本机路径。

    如果 StatusFileUpdateEvent 对象的可用属性设置为 True,则可以取消此事件。取消该事件可阻止更新继续进行。调用 installUpdate() 方法可继续进行取消的更新。

  • StatusFileUpdateErrorEvent.FILE_UPDATE_ERROR — 存在错误且 updater 无法安装 AIR 应用程序时调度此事件。

取消更新过程

可以调用 cancelUpdate() 方法来取消更新过程:

appUpdater.cancelUpdate();

此方法可取消所有未处理的下载,删除所有不完整的下载文件,并可重新启动定期检查计时器。

如果 updater 对象正在初始化,则该方法不执行任何操作。

本地化 ApplicationUpdaterUI 界面

ApplicationUpdaterUI 类为更新过程提供默认的用户界面。该用户界面包括允许用户启动过程、取消过程以及执行其他相关操作的对话框。

使用更新描述符文件的 description 元素,您可以用多种语言定义应用程序的描述。使用定义 lang 属性的多个 text 元素,如下所示:

<?xml version="1.0" encoding="utf-8"?> 
     <update xmlns="http://ns.adobe.com/air/framework/update/description/1.0"> 
       <version>1.1a1</version> 
       <url>http://example.com/updates/sample_1.1a1.air</url> 
       <description> 
           <text xml:lang="en">English description</text> 
           <text xml:lang="fr">French description</text> 
           <text xml:lang="ro">Romanian description</text> 
       </description> 
    </update>

更新框架将使用最适合最终用户的本地化链的描述。有关详细信息,请参阅“定义更新描述符文件并将 AIR 文件添加到 Web 服务器”。

Flex 开发人员可以直接将新的语言添加到"ApplicationUpdaterDialogs"包中。

JavaScript 开发人员可以调用 updater 对象的 addResources() 方法。此方法可动态地添加某种语言的新资源包。该资源包定义某种语言的本地化字符串。这些字符串用于各种对话框的文本字段。

JavaScript 开发人员可以使用 ApplicationUpdaterUI 类的 localeChain 属性来定义用户界面所使用的区域设置链。通常只有 JavaScript (HTML) 开发人员使用此属性。Flex 开发人员可以使用 ResourceManager 管理区域设置链。

例如,以下 JavaScript 代码定义了罗马尼亚语和匈牙利语的资源包:

appUpdater.addResources("ro_RO", 
                    {titleCheck: "Titlu", msgCheck: "Mesaj", btnCheck: "Buton"}); 
appUpdater.addResources("hu", {titleCheck: "Cím", msgCheck: "Üzenet"}); 
var languages = ["ro", "hu"]; 
languages = languages.concat(air.Capabilities.languages); 
var sortedLanguages = air.Localizer.sortLanguagesByPreference(languages, 
                         air.Capabilities.language, 
                         "en-US"); 
sortedLanguages.push("en-US"); 
appUpdater.localeChain = sortedLanguages;

有关详细信息,请参阅语言参考中对 ApplicationUpdaterUI 类的 addResources() 方法的说明。