亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Flex > 正文

flex與js通信與彼此之間的互調整理(二)

2024-09-08 18:17:14
字體:
來源:轉載
供稿:網友

之前寫了一篇flex和js之間的通信,還記得最開始研究這兩門語言如何交互,一晃我的任務也快做完了,公司的realspace產品之開了js的API,但是現在使用flex產品的人也比較多,要求開設flex的三維API,已經過去幾個月了,產品也上線了,有興趣的可以在https://github.com/SuperMap/Flex-Realspace下載,這是一個利用as與js交互放在了一個完整的產品里。

網上也有很多關于flex和js通信的文章,不過不知道大家有沒有注意到好像都需要把js文件放在固定的文件下(flex調用js),并且需要在index.template.html文件里面動手腳,而且你把源代碼考給團隊的其他人,發現flash builder導進去后重新生成了index.template.html,又得自己修改一下,不是很麻煩嗎?如果你是需要此技術做自己的產品的話我建議你一定要看一下我想出的辦法,也許會幫了不少人哦!

一個大項目或者產品,在js代碼里面估計都會有很多用原型建的類,在flex端估計也有很多功能。我們的假設場景是你正在使用flex制作項目,不過有一些功能只能通過js來實現,所以你將部分功能使用js封裝成了一些js的文件,希望通過as與js之間的通信來使用as語言調用js里面的功能。js文件基本已經寫好了,但是因為需要在不少地方懂手腳團隊協作起來不方便,我這篇文章就是用來解決這個問題的。

一、設計好代碼

首先我們需要明白的是:js文件在啟動之后被加載到html頁面里面,我們可以通過ExternalInterface.call("js的方法",參數);在flex端調用js端的方法,我們可以通過ExternalInterface.addCallback("對外公開的方法名",具體實現的方法);來解決在js端調用flex端的方法。

現在我們需要思考:js里面有很多功能,我們每次調用js功能都得去調用相關的方法嗎?那樣as和js之間的耦合不是太高了,不符合設計模式,并且很麻煩。同樣js這邊需要回調(常用在事件回調上)flex的方法時,方法很多,我們是不是也要在flex端動態注冊那么多個方法名稱呢?那樣不怕名稱沖突嗎?所以這樣的實現都是不可取的。

為了達到低耦合,我將as和js之間的通信設定為只有兩座橋,as調用js功能永遠只會通過調用js里面的固定方法,js回調flex的功能也只能調用在程序初始化flex端動態創建的唯一的一個方法。這樣as和js之間的通信永遠只通過這兩個方法來交互,就不會出現之前的很多問題。但是大家肯定想問如何知道我這一次調用的功能和我下一次調用的有什么區別怎么辦?那就是在參數上面做手腳了。說白了就是通過參數來判斷你的行為。

在我們flex realspace產品面as調用js的功能都是通過var result:Object=ExternalInterface.call("SuperMap.Web.Util.ApplicationManager.initBridgeFlexToJs",object);這一局來的,SuperMap.Web.Util.ApplicationManager.initBridgeFlexToJs是在js端的一個文件里面的方法,唯一的as訪問js的通道,特殊的是object,這是一個鍵值對,形如:

復制代碼 代碼如下:

var realArgument:Array=[strServerUrl.toString()+"$String"];
var array:Object={
action:"FUNCTION",
key:this.KEY,
functionName:"checkPluginUpdate",
isReturn:true,
realArgument:realArgument
};

上面的array就是我說的object,里面的action:"FUNCTION"代表我需要調用的是方法,調用的對象的key(唯一標示)是this.KEY,方法名稱是checkPluginUpdate,有返回值,方法的參數是realArgument(一個特殊數組)。

其實這些有點類似json,用來傳遞數據的,而我自定義的一個格式是用來傳遞行為操作的,這個你們可以自己定義,反正核心就是通過參數來判斷你的行為,方法永遠調用同一個,這點明白了就是自己設計上的事情,不過在解析的時候有點麻煩哈!

二、打包js代碼

如果你的代碼符合我這樣的邏輯,交互通過兩座橋來通信,那么我們就開始下一步,其實這樣設計后已經可以使得自己的產品交互起來很方便了,我當時花了一個月就是這么做的,都做的差不多了,上面交代說js代碼不能開放出來,而且每次都需要修改index.template.html文件,太麻煩,希望flex端的開放人員完全看不到js的任何東西,要求需要把js文件打包成為swc文件,通過去調用swc文件里面的js來實現功能,我當時一聽這簡直就是不可能的嘛!不過后來研究了好久,發現這樣可以實現,并且還有它的優勢。

首先我們需要知道如何把js文件打包成為swc文件,新建一個庫項目,將你的js文件都放進去,如下圖:

我建的項目叫bridge,里面有我所有的js文件,還有不少as文件,細心的發現每一個js文件旁邊都有一個...Stream.as文件,這里就是重點了,我們如何才能把js文件打包到swc里面呢,flex提供了一種流的方式,例如上面的ApplicationManager.js文件,我們創建一個類ApplicationManagerStream繼承于flash.utils.ByteArray,代碼如下:

復制代碼 代碼如下:

package SuperMap.Js
{
import flash.utils.ByteArray;
/**
* 制定js文件以及打包方式
*/
[Embed(source="ApplicationManager.js", mimeType="application/octet-stream")]
public class ApplicationManagerStream extends ByteArray
{
public function ApplicationManagerStream()
{
super();
}
}
}

寫好你對應的js文件,一定要和此類放在一個文件夾下,配上打包的類型application/octet-stream,每一個js文件都配置一個相應的as類,這樣在

里面會自動生成好打包好的swc文件

現在問題又來了,里面是二進制的東西,我們如何使用啊,不是我們平時寫的as類,寫了什么方法引用這個包直接使用就行。

所以我們還需要一個as類。這里我創建IncludeStream.as,代碼如下:

復制代碼 代碼如下:

package SuperMap
{
import SuperMap.Js.ApplicationManagerStream;
import SuperMap.Js.HashTableStream;
import SuperMap.Js.SceneDivStream;
import SuperMap.lib_Ajax.IServerJava6RStream;
import SuperMap.lib_Ajax.JsStream;
import SuperMap.lib_Ajax.MicrosoftAjaxStream;
import SuperMap.lib_Realspace.RealspaceStream;
/**
* 此類主要用于以字符串形式獲取二進制形式的js代碼
*/
public class IncludeStream
{
/**
* 構造函數
*/
public function IncludeStream()
{
}
/**
* 返回js文件里面代碼的字符串形式
*/
public function toString():String
{
var microsoftAjaxStream:MicrosoftAjaxStream=new MicrosoftAjaxStream();
var jsStream:JsStream=new JsStream();
var iServerJava6RStream:IServerJava6RStream=new IServerJava6RStream();
var realspaceStream:RealspaceStream=new RealspaceStream();
var hashTableStream:HashTableStream=new HashTableStream();
var applicationManagerStream:ApplicationManagerStream=new ApplicationManagerStream();
var sceneDivStream:SceneDivStream=new SceneDivStream();
return microsoftAjaxStream.toString()+jsStream.toString()+iServerJava6RStream.toString()+realspaceStream.toString()+hashTableStream.toString()+applicationManagerStream.toString()+sceneDivStream.toString();
}
}
}

有了這個類,我們可以通過實例化一個此對象,然后通過方法toString()獲取到字符串形式的js的所有代碼。這又是一個問題,我們還是不能使用,沒法調用。不過先這樣打包好,引用到你的flex項目里面再說。

三、調用js文件

首先我們要知道as調用js的方法只能調用js形式的方法,也就是嵌入到了html頁面的js,而現在我們只有字符串形式的js源代碼,所以需要想辦法將它轉化為標準的js代碼,嵌入到html頁面里面。

在你的flex項目啟動的最開始的地方恰如如下代碼:

復制代碼 代碼如下:

//初始化一個字符串形式的方法parseStringToJs,用于將字符串轉換為js語言
var str:String = "function parseStringToJs(str){var oHead = document.getElementsByTagName('HEAD').item(0);";
str+="var oScript = document.createElement(/"script/");";
str+="oScript.language = /"javascript/";";
str+="oScript.type = /"text/javascript/";";
str+="oScript.id = /"test/";";
str+="oScript.defer = true;";
str+="oScript.text = str;";
str+="oHead.appendChild(oScript);}";
//調用window.eval方法
ExternalInterface.call("eval",str);
var includeStream:IncludeStream=new IncludeStream();
//獲取js的字符串形式的源代碼
var strey:String=includeStream.toString();
//使用正則表達式修改字符串
var char:RegExp = ////g;
strey = strey.replace(char,"http:////");
//生成js的API
ExternalInterface.call("parseStringToJs",strey);
//初始化js調用as的入口方法initBridgeJsToFlex,最終飯方法的實現轉給方法ApplicationManager.initBridgeJsToFlex
ExternalInterface.addCallback("initBridgeJsToFlex",ApplicationManager.initBridgeJsToFlex);

注釋已經寫的很清楚了,不過正則表達式這一步可以不要,我這里是因為我的代碼里出現了反斜杠的東西,所以我這樣是為了轉義一下,這里的思路就是先使用ExternalInterface.call去調用window對象的方法eval在window下創建一個將字符串轉化為js代碼的方法parseStringToJs,然后再調用此方法將我們的字符串的源代碼進行轉化,這樣html中就存在js的代碼了,就不用再去修改index.template.html文件添加引用和添加入口了。并且在其他地方你可以通過ExternalInterface.call直接調用js端公開的橋,并且通過ApplicationManager.initBridgeJsToFlex來接收js的回調函數,這樣我們只需要添加swc這個包就可以使用js的所用功能。

其實我也不想使用eval的,eval是很消耗性能的,我的源代碼長度大概是8萬多,還好,沒見卡,我也只會這種方法,不要拿板磚拍我哦!有其他辦法的朋友告訴我哦!期望對某些人有幫助吧!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲乱码一区av黑人高潮| 亚洲午夜av电影| 亚洲人成啪啪网站| 欧美成人精品不卡视频在线观看| 久久久精品999| 欧美极品少妇xxxxⅹ喷水| 国产91精品青草社区| 精品日本高清在线播放| 亚洲精品国产精品国自产观看浪潮| 国产精品影片在线观看| 国产精品第七十二页| 中文亚洲视频在线| 这里只有视频精品| 欧美最猛黑人xxxx黑人猛叫黄| 国产极品精品在线观看| 国产在线观看91精品一区| 亚洲第一精品夜夜躁人人躁| 国产亚洲欧洲黄色| 欧美在线一级va免费观看| 日本精品视频在线| 日韩成人av网址| 久久精品国产亚洲7777| 黑人巨大精品欧美一区二区| 午夜精品三级视频福利| 亚洲国产精品va在线看黑人动漫| www.欧美免费| 亚洲精品中文字| 欧美日韩国产中字| 国产精品三级网站| 2023亚洲男人天堂| 亚洲丝袜一区在线| 亚洲欧洲xxxx| 久热爱精品视频线路一| 国产欧美精品日韩精品| 成人激情在线播放| 欧洲精品久久久| 日本一欧美一欧美一亚洲视频| 国产精品视频自拍| 69国产精品成人在线播放| 国产精品1234| 亚洲精品动漫100p| 国产精品久久久久久av下载红粉| 久久国内精品一国内精品| 久久久国产精品免费| 国内精品模特av私拍在线观看| 亚洲综合色激情五月| 成人中文字幕+乱码+中文字幕| 午夜精品一区二区三区视频免费看| 热久久免费视频精品| 国产精品视频白浆免费视频| 亚洲а∨天堂久久精品喷水| 国产在线观看91精品一区| 国产精选久久久久久| 国产91色在线| 欧美怡红院视频一区二区三区| 亚洲精品国产精品自产a区红杏吧| 欧美日韩色婷婷| 日韩经典中文字幕| 欧美综合第一页| 久久久亚洲天堂| 亚洲人成网在线播放| 91沈先生在线观看| 亚洲欧美日韩中文视频| 国产精品美女久久久久久免费| 欧美午夜激情在线| 国产欧洲精品视频| 激情久久av一区av二区av三区| 亚洲国产精品人久久电影| 国产精品久久久久久久美男| 欧美性生交xxxxx久久久| 成人在线一区二区| 爽爽爽爽爽爽爽成人免费观看| 亚洲国内高清视频| 久久91亚洲人成电影网站| 久久99久久99精品免观看粉嫩| 91精品中国老女人| 欧美性猛交xxxx乱大交极品| 亚洲国产精品电影在线观看| 国产精品三级在线| 欧美午夜精品久久久久久浪潮| 国产精品69久久| 欧美伦理91i| 亚洲国产精品久久精品怡红院| 成人激情在线观看| 亚洲欧美另类在线观看| 国产精品视频区1| 成人激情视频小说免费下载| 精品一区二区三区三区| 久久久久久久国产精品视频| 日韩中文字幕在线观看| 成人国产在线视频| 国产99久久精品一区二区永久免费| 国产99在线|中文| 精品国产91久久久久久老师| 日韩女在线观看| 欧美乱大交xxxxx另类电影| 亚洲精品999| 久久精品成人一区二区三区| 日韩精品免费一线在线观看| 91精品国产色综合久久不卡98| 欧美大片免费看| 国产男女猛烈无遮挡91| 96sao精品视频在线观看| 欧美最猛黑人xxxx黑人猛叫黄| 亚洲一级黄色片| 国产精品美女主播| 日本在线观看天堂男亚洲| 精品久久久久久久大神国产| 欧美在线观看一区二区三区| 日韩av在线电影网| 91免费的视频在线播放| 亚洲精品视频久久| 亚洲精品久久久久国产| 亚洲国产成人在线播放| 中文字幕在线看视频国产欧美在线看完整| 欧美特级www| 91精品久久久久| 亚洲大胆美女视频| 欧美国产精品日韩| 亚洲日本中文字幕免费在线不卡| 欧美一二三视频| 国产自产女人91一区在线观看| 精品久久久av| 欧美天天综合色影久久精品| 国产精品99久久99久久久二8| 亚洲奶大毛多的老太婆| 国产欧美精品一区二区三区-老狼| 亚洲一区二区久久久久久| 26uuu日韩精品一区二区| 亚洲午夜激情免费视频| 久久国产精品久久国产精品| 91在线观看免费| 欧美与欧洲交xxxx免费观看| 丁香五六月婷婷久久激情| 久久久成人的性感天堂| 亚洲一区二区福利| 91亚洲精华国产精华| 成人啪啪免费看| 91欧美视频网站| 欧美日韩中文字幕| www.日韩视频| 欧美日韩亚洲网| 欧美电影在线观看完整版| 成人做爰www免费看视频网站| 国产一区二区成人| 国产精品高潮呻吟久久av黑人| 精品久久久香蕉免费精品视频| 国产精欧美一区二区三区| 少妇高潮久久久久久潘金莲| 亚洲日本欧美日韩高观看| 亚洲美女动态图120秒| 成人午夜在线视频一区| 久久精品国产一区| 欧美日韩美女视频| 清纯唯美日韩制服另类| 国产成人亚洲精品| 91精品久久久久| 国产欧美 在线欧美| 久久免费观看视频| 中文字幕日韩精品有码视频| 欧美电影免费观看| 国产精品免费观看在线| 国产精品入口日韩视频大尺度| 成人午夜小视频|