这是一个由多个部分组成的系列文章的第一部分,它包含了Flex移动开发的若干技巧。如果你过去习惯于桌面和Web编程,你会发现,开发移动应用程序将面临一系列新的挑战。 除了重新思考你的对数据存储和处理的策略,你还需要考虑屏幕尺寸和分辨率,而且需要在管理性能和电池消耗之间做出取舍。本系列文章将通过提出克服这些新的开发挑战的技术来帮助你轻松地过渡到移动开发领域。

数据处理是移动开发涵盖的一个方面,它需要传统的应用程序开发人员采取不同的思维方式。例如,对于许多移动应用程序来说,当用户关闭应用程序或切换到其它应用程序时,或当收到来电时,或当应用程序由于其它一些原因被迫关闭时,保存数据是非常重要的。 此外,移动应用程序的视图常常被销毁并重新创建。 因此,你需要思考如何处理你的视图之间的数据。因而,你需要用于保存数据的两个场景方案是:

  • 在应用程序执行之间(也就是说,在关闭和重启应用程序时)
  • 在你的应用程序的视图之间

本文介绍几种处理这些场景的方法。

使用destructionPolicy属性处理视图之间的数据

在深入讨论在视图之间浏览时处理保存数据的不同方法之前,必须了解 View的生命周期。在Flex 4.5中,在任意给定时刻只有一个View是处于激活状态。默认情况下,所有其它的View将予以销毁,并在需要时重新创建。 这种行为是由View类的destructionPolicy 属性控制的,View类的默认设置为auto。如果你将该属性的值设置为 never ,则View将被缓存,并保持其状态,直到它通过调用 navigator.popView()被重新调用。

考虑如图1所示的图。默认情况下(或当你明确地设置destructionPolicy="auto"),当View B推入堆栈时,View A将被销毁,而当View C推入堆栈时,View B将被销毁。 每次当堆栈中View A和 View B之上的视图弹出时,它们将被重新创建。当你在View A和 View B上设置 destructionPolicy="never" 时,这些视图将被去激活和缓存,但当一个新的视图推入时,它们将不会被销毁。之后,当位于它们上面的视图被弹出时,它们会很容易地被激活。

图1. 在 Flex 4.5中创建和销毁视图

注意即使你在一个View中设置destructionProperty="never",如果你调用pushView()来再次显示它,则它也会被重新创建。只有当上述的View从堆栈中弹出以便显示以前的视图时,缓存才有效。考虑图 2给出的框图。当第二次推入View B 时,它将被重新创建,并且不能访问以前显示的数据(除非你使用另一种方法来保存和检索数据)。

图2. 第二次推入View B 将会导致该视图重新创建

我创建了一款简单的应用程序,它在 View 1启动然后调用pushView() 来激活 View 2。你可以在我在我的应用程序插入的下列跟踪语句中看到默认发生事件的正常顺序(没有设定 destructionPolicy属性):

  1. 删除View 1 以响应屏幕变化(removing事件)
  2. 将View 2 添加到display列表(added事件)
  3. View 2 add 事件(add事件)
  4. View 2 创建完成( creationComplete事件)
  5. 去激活View 1 ( viewDeactivate 事件)
  6. 从display列表中删除 View 1(removed 事件)
  7. 激活View 2( viewActivate 事件)

使用data属性处理视图之间的数据

另一个(在我看来更加直观)用于保存视图之间数据的选项是在View对象中使用 data 属性。这一属性将在内存中保存数据的状态,因此当你通过推入或弹出返回到你的View时,你可以对它进行访问。你可以对data 属性设置任意对象类型,其中包括自定义类。 在下面给出的 Person 类中,data 属性被设置为一个value对象。注意,在View被显示之前,视图中的data 属性已经经过例示并且准备完毕,因此你不必担心其可用性。

你还可以通过在View中覆盖 createReturnObject() 方法从弹出的视图中返回数据。 如果你的应用程序正在显示View A并且你希望推入View B,那么你可以通过在View B中覆盖createReturnObject() ,从View B中将数据返回到View A;例如:

override public function createReturnObject():Object { return person; }

在本范例中, person是我已经利用ActionScript定义的一个类的实例:

package model { [Bindable] public class Person { public var person_id:int; public var userid:String; public var password:String; public var fname:String; public var lname:String; public var city:String; } }

一旦回到 ViewA之后,你可以使用下面代码访问返回的对象:

data = navigator.poppedViewReturnedObject.object;

由于对象类型实际上是 ViewReturnObject,因此你必须指定object 属性以便获得相应的值。

在应用程序执行之间保存数据

你有若干在应用程序之间保存你的数据的选项,因此当应用程序在关闭之后重新启动时可以获得相应的数据。Flex 4.5 具有一种内置的保存机制,通过 ViewNavigatorApplicationTabbedViewNavigatorApplication中的一个名称为 persistNavigatorState 的属性可以对它进行访问。在你将 persistNavigatorState 设置为true 以便启用该机制之后,你可以侦听navigatorStateLoading 和 navigatorStateSaving事件,并且在这些事件发生时 执行必要的处理操作。如果你希望开发你自己的自定义保存数据的方法,你可以在事件处理程序中调用preventDefault()

当使用这一技巧时,你的根应用程序标签与下面代码相似:

<?xml version=”1.0” encoding="utf-8"?> <s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.SampleDataPersistenceHomeView" firstViewData="{person}" persistNavigatorState="true" navigatorStateSaving="onStateSave(event)" navigatorStateLoading="onStateLoad(event)" >
/Applications/Adobe Flash Builder 4.5/sdks/4.5/frameworks/projects/mobilecomponents/src/spark/managers

当你设置persistNavigatorState="true"时,你的应用程序将自动将其Views的状态和数据保存到一个名称为FXAppCache的本地共享对象中。如果你在Flex 4.5 SDK 中查看PersistenceManager.as 源代码(在我的Mac中,该文件可在文件夹 /Applications/Adobe Flash Builder 4.5/sdks/4.5/frameworks/projects/mobilecomponents/src/spark/managers中找到),你将看到该变量是如何创建的。

在使用 Flash Builder 仿真器运行你的应用程序之后,你可以通过在你的硬盘上寻找相应的本地共享对象查看保存的数据。 在我的Mac中,该文件的路径是:

/Users/hollyschinsky/Library/Preferences/DataPersistence.debug/Local Store/#SharedObjects/DataPersistence.swf/FXAppCache.sol.
图3. 在 FXAppCache 本地共享对象中保存数据

如果你需要保存一个自定义类,例如在上面范例中提及的Person类,你必须在主应用程序中侦听preinitialize 事件并且注册该类的别名;例如:

protected function viewnavigatorapplication1_preinitializeHandler(event:FlexEvent):void { flash.net.registerClassAlias("person",model.Person); }

当你将persistNavigatorState 属性设置为true时,你的数据将自动保存,但如果你希望添加更多属性或访问保存数据管理器(persistence manager)时,你可以通过使用ViewNavigatorApplicationTabbedViewNavigatorApplication的 persistenceManager 对象实现这一目的;例如:

persistenceManager.setProperty("hollysProp","myProperty"); // set my own custom property persistenceManager.getProperty("hollysProp"); // retrieve the value for my property

如果你从一个View访问它,则你可以使用:

FlexGlobals.topLevelApplication.persistenceManager.getProperty("person"); //Retrieves my custom Person class object that was persisted

要想了解内情,你可以打开调试器,然后看一看 persistenceManager 变量即可(参见图4)。

图4. 调试器中的persistenceManager变量

你可以看到在默认情形下还能够保存两个传统的属性:versionNumber 和 navigatorState ,这可以用于将视图回复到它们以前的状态。

使用默认 PersistenceManager的主要缺点是数据不能加密。然而,你可以免费使用 IPersistenceManager 接口来定义一个自定义保存数据的机制。因此,你可能希望实施一种本地加密存储方式以便获取和设置敏感数据。另一个次要缺点是在某些情形下,该机制仅适用于少量数据。如果你需要保存大量数据,你应该使用SQLite替代上述方式。关于一篇仔细分析如何创建能够与SQLite数据库通信的移动应用程序的优秀文章,参见Christophe Coenraets的利用Flex和Flash Builder创建一个移动雇员号码地址簿范例(Building a mobile employee directory sample with Flex and Flash Builder)

Flex移动应用程序开发的技巧和窍门(一)的更多相关文章

  1. Flex移动应用程序开发的技巧和窍门(三)

    这是关于 Flex 移动应用程序开发的技巧和窍门系列文章的第三部分内容.第一部分内容主要集中讨论了视图之间以及应用程序执行之间切换时的数据处理.第二部分则主要涵盖了应用程序动作条和标签组件风格化方面的 ...

  2. Flex移动应用程序开发的技巧和窍门(二)

    范例文件 flex-mobile-dev-tips-tricks-pt2.zip 这是关于Flex移动应用程序开发的技巧和窍门的一系列文章中的第二部分.第一部分 内容主要集中讨论了视图之间以及应用程序 ...

  3. Flex移动应用程序开发的技巧和窍门(四)

    范例文件 flex-mobile-dev-tips-tricks-pt4.zip 这是本系列文章的第四部分,该系列文章涵盖Flex移动开发的秘诀与窍门. 第一部分关注切换视图以及切换执行应用时的数据处 ...

  4. Flex移动应用程序开发的技巧和窍门(五)

    范例文件 flex-mobile-development-tips-tricks-pt5.zip This is Part 5 of a multipart series of articles th ...

  5. 微信小程序开发调试技巧

    1.  查看线上小程序console a.  先打开开发小程序console b.  再打开线上小程序,此时可以查看console

  6. 微信小程序开发小技巧——单击事件传参、动态修改样式、轮播样式修改等

    一. 脚本部分: 1. 表达式无效的处理: 如果你发现自己编写的表达式无效或者数据不展示,那么请先检查你的表达式是否有添加{{}},小程序中全部都要添加的,只要是在模板中调用js中的数据 2. 获取元 ...

  7. 微信小程序开发小技巧:

    小技巧:输入view.tabs_content就可以生成下面的代码. 输入p10,就可以得到: 输入jc:c得到:文字水平对齐 输入d:f得到: 输入ai:c得到: 输入bb得到: currentCo ...

  8. flex开发小技巧集锦

    关于flex开发网上有非常多的相关信息介绍,因此我们要想学习关于flex开发的知识信息技能是一件非常简单和方便的事情.而针对于flex开发小编要告诉大家的是一些flex开发小技巧.利用这些小技巧能够有 ...

  9. 【Abode Air程序开发】Flex air文件打包和运行

    1 安装Adobe AIR 运行时,和java的JVM类似. Adobe AIR 运行时允许在桌面运行AIR应用程序,脱离游览器的束缚. 下载安装文件http://get.adobe.com/cn/a ...

随机推荐

  1. ubuntu14.04英文环境下安装中文输入法

    ubuntu14.04英文环境下安装中文输入法 发表于1年前(2014-07-12 20:12)   阅读(4478) | 评论(0) 3人收藏此文章, 我要收藏 赞1 9月19日成都 OSC 源创会 ...

  2. 用Java开源项目JOONE实现人工智能编程

    http://www.robotsky.com/ZhiN/MoS/2011-08-25/13142461416649.html 用Java开源项目JOONE实现人工智能编程 https://sourc ...

  3. json转义字符串

    json前台写数据 @RequestMapping("/addUserJson") public void addUserJson(User user,HttpServletReq ...

  4. php 缓存之 APC 和apcu

    php opcode 缓存 apc. 其实,我自己的理解, php apc 缓存其实分两部分, 一部分是 缓存 类似于 java 编译的中间的 字节码, 不同于c 语言编译之后的二进制的机器码. ph ...

  5. 深入浅出 - Android系统移植与平台开发(一)

    深入浅出 - Android系统移植与平台开发(一) 分类: Android移植2012-09-05 14:16 16173人阅读 评论(12) 收藏 举报 androidgitgooglejdkub ...

  6. Hadoop详解一:Hadoop简介

    从数据爆炸开始... 一. 第三次工业革命        第一次:18世纪60年代,手工工厂向机器大生产过渡,以蒸汽机的发明和使用为标志.      第二次:19世纪70年代,各种新技术新发明不断被应 ...

  7. [Unity]C#中 将XML和实体类之间进行相互转换的工具类

    using System; using System.Xml; using System.Xml.Serialization; using System.IO; namespace LOTool { ...

  8. function $(id){ return document.getElementById(id); }导致所有的js不能用解决办法。。。。

    function $(id){ return document.getElementById(id); } document.getElementById(id) 是获得id这个元素的. 相当于定义了 ...

  9. Python中下划线---完全解读

    Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用'from module import *'导入 __xxx__ 系统定义名字 __xxx 类中的私有变量名 核心风格:避免用下划 ...

  10. java求两个集合的差集

    public static void main(String[] args) {Set set = new HashSet();Set set1 = new HashSet();set.add(&qu ...