Firefox Windows linux shell apache Ubuntu Android nginx 微软 wordpress 开源 程序员 centos 编程 Python php 云计算 java google mysql

十個Flex/Air疑難雜癥及解決方案簡略

最近去一家臺企,對方給我出了十道“難道”:在TileList中如果選擇檔過多,會出現捲軸,當拖動捲軸時,渲染的進度條會出現花屏現象;
簡體:在TileList中如果選擇檔過多,會出現卷軸,當拖動卷軸時,渲染的進度條會出現花屏現象;電子白板中,控制權轉移;
簡體:電子白板中,控制權轉移;電子白板中,畫面同步;
簡體:電子白板中,畫面同步;電子白板中,錄影;
簡體:電子白板中,錄影;FLASH置頂問題;
簡體:FLASH的置頂問題;聊天表情無法復制粘貼,由於聊天表情是動態文本,所以添加到textflow中的是一個sprite對象;
簡體:聊天表情無法復制粘貼,由於聊天表情是動態文本,所以添加到textflow中的是一個sprite對象;老板模式,當系統焦點離開air程序後,無法檢測到系統的key_down事件;
簡體:老板模式,當系統焦點離開air程序後,無法檢測到系統的key_down事件;Air註冊表操作(登陸啟動look程序);
簡體:Air註冊表操作(登陸啟動look程序);在1.5的air運行時環境下,中文不能輸入問題,因為客戶端可能已經安裝1.5的運行時,在網頁安裝中只能檢測客戶端是否安裝了運行時,卻無法檢測到版本信息或者更新運行時;
簡體:在1.5的air運行時環境下,中文不能輸入問題,因為客戶端可能已經安裝1.5的運行時,在網頁安裝中只能檢測客戶端是否安裝了運行時,卻無法檢測到版本信息或者更新運行時隱藏window邊框後,鼠標在拖動窗口邊界改變窗口大小時,不能設置系統光標樣式。
簡體:隱藏window邊框後,鼠標在拖動窗口邊界改變窗口大小時,不能設置系統光標樣式
ps:一種語言在發音上有幾十種不同的方言風格,在書寫上竟然也有兩種截然不同的風格,不止何時可以統一。
雜癥病因及解決方案簡略:
1, ITEMRENDERER的花屏問題
並非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中官方曾見有示例,有興趣的朋友可以查一查。

sban 2010/6 北京

本文采用署名-非商業性使用-相同方式共享協議,屬於AS3-Expert的一部分,轉載請註明作者及出處,非商業。
如果您是Flash/AS3技術的愛好者,請加入AS3高級技術群:44985308,70782097。如果你是Flash/AS3方面的專家,請加入AS3專家群(71057902),申請驗證請附上作品鏈接或博客地址。

延伸阅读

    评论