[转]十个Flex/Air疑难杂症及解决方案简略

今天寻找原来写的关于FXG的文章,无意中发现sban写的几篇很不错的文章都看不到了,原来他的博客挂了。google到新的博客,也没有发现原来的博文。但又找到几篇不错的文章,看来还是转过来保险 😆

原文作者:sban
原文地址:http://sban.biz/239
以下为转载


杂症病因及解决方案简略:

1, 在TileList中如果选择档过多,会出现卷轴,当拖动卷轴时,渲染的进度条会出现花屏现象;

并非TileList有这个问题,在Flex3内,DataGrid,List,Tree等控件如果使用不当,均存在这个问题;在先前的fl组件包内的TileList组件也有类似阴影。根本原因在于,使用ItemRenderer的大数据控件,其在渲染时,并不会一次创建所有数据列/行的显示对象 (ItemRenderer),它仅会创建在屏幕上可见的数据列/行,并且重复利用这些显示对象,以提交运行时效率。

可以做这样一种代码实验,以帮助人们理解这种机制:在一个TileList控件内,它本身有滚动条,它的ItemRenderer也使其有滚动条,在多屏数据的情况下,任意滚动一个ItemRenderer的滚动条,然后滚动TileList的滚动条到另一屏,你会发现,虽然数据已经变了,你从未滚动过这个数据,但它与你先前滚动过的那个数据具有相同的滚动位置。

从严格意义上讲,这并不能算是Adobe的bug,因为如果你严格按照Adobe的官方说明使用,多数情况下,是不会出现的,因此这个bug的复现也颇具难度。从Flex SDk 3.5开始,Adobe Flex团队,对所有基于ItemRenderer实现的数据控件针对开发者遇到的问题进行了改良,优化了SDK内部控件实现方法,并且添加了一个 offscreenExtraRowsOrColumns属性,该属性意为非显示区域的行或列数,用于帮助开发者在特定情况下遇到的花屏问题。

如果遇到这个问题,如果解决(方案按优先级自上向下排列):

1) 修改策划
显示大数据时,传统滚动条是一个糟糕的设计,因为人的眼晴对于大量的,重复结构的数据,很难定位上次查看的位置,多数人都是边察看边用指在屏幕上做标记。此种情况下,
a)要么不使用滚动条,使用翻页,用户每次翻页后,重新取数据、向数据控件赋值,在这种情况下,DataGrid,TileList等均不会出现花屏问题,因为压根儿就不会有滚动,但在此时,使用Repeater效率更高。
b)要么设计一种粗粒度滚动条,在这种粗粒度滚动中,每一个点相关于翻页设计中的一页,用户拖动时还相当有手感,相对传统滚动条要好许多,这种设计在许多产品中都已经开始使用。

2)在更新DataProvider时手动刷新控件视图
每次当data有变化,均手动再次设置一次ItemRenderer,大意如下:
list.itemRenderer = new ClassFactory(YourItemRenderer);
注:在Gumbo中,如果使用Bindable绑定数据,FB在编译时已经做了代码优化。所以,多数时候,按照官方方法可以避免很多问题。

3)使用offscreenExtraRowsOrColumns属性调整
这是最BT的方案,让人感觉是Adobe自己用算法难已处理了,所以请用户告诉控件目前有多少数据列/行在显示区外。具体用法请参照livedoc说明。

2-4,电子白板中,控制权转移;录制;画面同步

在白板开发中,控制权转移,画面同步,录影属于基本功能点。在技术技巧上,录影使用ImageSnapshot取得数据,剩下的便是系统架构师的事情。白板若要做好,方方面面必须设计好,特别是多人同时在线应用。

最基本的白板实现方案是基于ShareObject,但这种实现是demo级的,既浪费资源性能又低,比较合理的设计,作者认为应该是这样:
1)控制权转移实则是多人数据同步,数据同步不要使用SO,当控制权变化时,由Server处理并向Client广播,如果在同一时间内白板只充许有一人控制,此时仅需向二人广播,如果其它人也需要知道当前人控权者是谁,通过另外统一的状态广播实现。
2)画面同步必须设计出二种机制,一种为指令绘制型,另一种为图像同步型。对于后来进入观看白板的人用户,它第一次需要向server请求当前最新的白板画面,server选择一个最可靠的client的白板数据发给新来者,或者使用p2p技术直接由client端发送。指令绘制型用于在活动用户之间更新白板数据、动作。指令需自行设计,这种设计可以轻松实现白板重绘。
3)录影在这里有两种实现,一种为ImageSnapshot,另一种为指令重绘型。
5,FLASH的置顶问题

默认情况下,在网页中swf对象之上放置不了浮动层,解决方案是修改FlashVars属性值,把wmode修改为opaque,同时对照其它对象,排列z-index。

6,聊天表情無法复制粘贴,由于聊天表情是动态文本,所以添加到textflow中的是一个sprite对象

这个问题没有一步到位的方案,属于架构师考虑的设计问题。自定义一种输入框,自定义一套emoticon标签,每一个表情用一个自定义标签标识,监听输入框的copy与paste事件,送入剪辑板的数据仅包含emoticon标签,而不是图像数据,在paste时进行解析、替换。

7,老板模式,当系统焦点离开air程序后,无法检测到系统的key_down事件

系统焦点离开AIR后,即使在AIR中有KEY_DOWN事情监听也无济于事。解决方案是,rumtime升级到AIR 2.0,在AIR程序启动时,同时启动一个C++ native progress,当AIR程序最小化至系统托盘后,由C++程序负责监听系统按键,以此实现AIR程度快捷键呼出。

8,Air注册表操作(登陆启动look程序)

Air直接写不了,解决方案有两种方向:
1)与问题7同,使用nvtive progress写注册表
2)不使用AIR,使用替换解决方案Flex4U

9,在1.5的air运行时环境下,中文不能输入问题,因为客户端可能已经安装1.5的运行时,在网页安装中只能检测客户端是否安装了运行时,却无法检测到版本信息或者更新运行时

这里面有二个问题,第一个,对于必须要求rumtime为2.0的air程序,在编译时指定,强制用户升级。

第二个,在网页中安装air,如何知道用户的air rumtime版本?

Adobe的air网页在线安装是通过这个swf实现的:
http://airdownload.adobe.com/air/browserapi/air.swf

下载,反编译后,里面使用一个叫做ProductManager的类进行客户端环境的签别,验证。一共有两个类文件:AIR.as与 AIRLCEndpoint.as。

从原理上讲,可以hack反编译之后的源码,重新编译为自已的air.swf,然后自定义bridge网页安装实现。

10,隐藏window边框后,鼠标在拖动窗口边界改变窗口大小时,不能设置系统光标样式

这个问题不复杂。如果不使用系统镶边,自定义光标显示对象,添加进显示列表,并添加事情监听实现缩放与拖动逻辑。在livedoc中官方曾见有示例,有兴趣的朋友可以查一查。