開發(fā)Adobe AIR的原生擴(kuò)展
目錄:
- 什么是原生擴(kuò)展?
- 入門
- 創(chuàng)建原生代碼
- 創(chuàng)建ActionScript 3代碼
- 封裝原生擴(kuò)展
- 在Flex示例應(yīng)用程序中使用原生擴(kuò)展
- 延伸閱讀
需求
預(yù)備知識(shí)
對(duì)AIR和ActionScript 3具有中等或深入的理解,熟悉Flash Builder和Java。
需要的產(chǎn)品
示例文件
開始之前
要充分掌握本教程中的知識(shí),請(qǐng)確保您安裝了以下軟件:
- Flash Builder 4.6(注冊(cè)獲取預(yù)發(fā)行版*)
- Adobe AIR 3(包含在Flash Builder中),用于移動(dòng)平臺(tái)(AIR 2.5或更高版本,用于針對(duì)TV擴(kuò)展的Adobe AIR)
- Adobe Flex 4.6(包含在Flash Builder中)
- Java API for AS擴(kuò)展(包含在AIR 3 SDK中,位于lib/android/FlashRuntimeExtensions.jar下)
您還需要以下工具:
- 一個(gè)Android設(shè)備用于在設(shè)備上進(jìn)行測(cè)試。
您可以選擇使用另一種平臺(tái),但本指南的原生代碼部分中的步驟將要求您維護(hù)您自己的原生構(gòu)建環(huán)境。
- 正確安裝的JDK和Android SDK。
其他資源
- Android SDK*
- 安裝Android SDK*
- 為Adobe AIR開發(fā)ActionScript擴(kuò)展
- 將Android開發(fā)工具(ADT)添加到Flash Builder 4.5.1*
什么是原生擴(kuò)展?
Adobe AIR允許應(yīng)用程序開發(fā)人員使用一組稱為Adobe AIR原生擴(kuò)展的工具擴(kuò)展運(yùn)行時(shí)的功能。從2.5版開始,此功能已為AIR for TV啟用,它現(xiàn)在已擴(kuò)展到移動(dòng)和桌面平臺(tái)。通過使用原生擴(kuò)展,您的應(yīng)用程序可訪問目標(biāo)平臺(tái)的所有功能,即使運(yùn)行時(shí)本身沒有內(nèi)置的支持。
為了演示這一點(diǎn),想象您在Android設(shè)備上創(chuàng)建一個(gè)應(yīng)用程序,并希望在應(yīng)用程序完成下載時(shí)震動(dòng)電話。沒有原生擴(kuò)展支持,您要么必須使用Java編寫整個(gè)程序,要么使用AIR并接受此任務(wù)不可實(shí)現(xiàn)的事實(shí)。但是,使用原生擴(kuò)展,您可以創(chuàng)建一個(gè)橫跨原生代碼和您自己的應(yīng)用程序邏輯的橋梁,允許您來回傳遞指令,使您的應(yīng)用程序能夠控制震動(dòng)馬達(dá)。您然后可以利用AIR的多平臺(tái)支持將相同的應(yīng)用程序部署到iOS,通過包含Objective-C代碼來擴(kuò)展您的原生擴(kuò)展。您甚至可以將原生代碼更改為可感知平臺(tái),以便更改震動(dòng)持續(xù)時(shí)間和模式,無論應(yīng)用程序是在Android上還是在iOS上運(yùn)行。
原生擴(kuò)展允許您利用您設(shè)備的獨(dú)特和特定于平臺(tái)的功能,它們還允許您在ActionScript應(yīng)用程序中使用原生代碼,重用現(xiàn)有的平臺(tái)代碼,在線程中執(zhí)行操作來提高您應(yīng)用程序的處理能力,以及提供對(duì)原生平臺(tái)庫(kù)的訪問。原生擴(kuò)展的封裝和分發(fā)就像所有其他ActionScript庫(kù)一樣:您可以分發(fā)您自己的庫(kù),以及使用其他開發(fā)人員發(fā)布的原生擴(kuò)展,可以將功能插入到您自己的應(yīng)用程序中。
Adobe還提供了多個(gè)經(jīng)過良好備案的原生擴(kuò)展示例,將幫助開發(fā)人員開始使用上述功能。
入門
本教程將指導(dǎo)您開始自行創(chuàng)建一個(gè)原生擴(kuò)展。它將介紹創(chuàng)建用于Android的原生Java代碼、ActionScript 3代碼和一個(gè)原生擴(kuò)展文件所需的步驟,您還將學(xué)習(xí)如何創(chuàng)建一個(gè)使用您的原生擴(kuò)展的Flex移動(dòng)應(yīng)用程序,最后您將在您的設(shè)備上測(cè)試它。盡管這是一個(gè)"Hello, World!"教程,但我們會(huì)避免通過原生代碼打印這條常見的消息,而選擇控制Android智能電話的震動(dòng)馬達(dá)。如果您感覺這有點(diǎn)冒險(xiǎn)(或者希望針對(duì)不同的平臺(tái)),您可以選擇調(diào)整本指南的原生代碼部分來適應(yīng)非Android平臺(tái)。
以下是以下頁面中將采取的總體步驟:
創(chuàng)建原生代碼
- 在Flash Builder 4.6中設(shè)置一個(gè)Android開發(fā)環(huán)境。
- 連接和測(cè)試您的Android設(shè)備。
- 創(chuàng)建一個(gè)原生Android項(xiàng)目。
- 創(chuàng)建Java代碼來創(chuàng)建一個(gè)擴(kuò)展上下文。
- 創(chuàng)建Java代碼來連接回ActionScript 3。
- 編譯您的代碼。
創(chuàng)建ActionScript 3代碼
- 在Flash Builder 4.6中設(shè)置一個(gè)ActionScript 3庫(kù)項(xiàng)目。
- 創(chuàng)建與您的Java代碼連接的橋。
- 為您的Android電話設(shè)置一個(gè)Flex移動(dòng)電話。
創(chuàng)建.ANE文件,將原生代碼和ActionScript 3捆綁在一起
- 處理證書。
- 使用adt命令。
- 修改您的Flex應(yīng)用程序以使用新的.ANE文件。
測(cè)試您的原生擴(kuò)展
證明您的原生擴(kuò)展有效!
創(chuàng)建原生代碼
原生擴(kuò)展的核心是原生代碼,它充當(dāng)著您的應(yīng)用程序與您希望控制的功能之間的第一層。在本示例中,原生代碼將控制震動(dòng)馬達(dá),使用ActionScript 3發(fā)送和接受信息。您將自行編寫功能來控制震動(dòng)馬達(dá),還將使用Adobe AIR提供的Java API來向ActionScript 3發(fā)送和從其接受數(shù)據(jù)。
但是,在開始編碼和使用庫(kù)之前,您必須設(shè)置您的構(gòu)建環(huán)境。
使用Flash Builder 4.6設(shè)置一個(gè)Android開發(fā)環(huán)境
因?yàn)槟鷮⒕帉懺鶤ndroid代碼,您需要一個(gè)可操作Android SDK的開發(fā)環(huán)境。如果您還沒有,請(qǐng)依照本指南開頭包含的鏈接安裝和配置Android SDK。完成此過程后,您將修改Flash Builder以創(chuàng)建和編譯Android項(xiàng)目:
- 打開Flash Builder并轉(zhuǎn)到Install New Software(在OS X上為Flash Builder > Window > Install New Software)。(如果有必要,關(guān)閉并使用管理特權(quán)重新啟動(dòng)Flash Builder。)
- 在Work with框中輸入Google的公共ADT軟件存儲(chǔ)庫(kù)的路徑:https://dl-ssl.google.com/android/eclipse/。單擊Add并將存儲(chǔ)庫(kù)命名為Google ADT。單擊OK添加存儲(chǔ)庫(kù)。
- Flash Builder將下載一組可用軟件。安裝所有開發(fā)人員工具,包括Android DDMS、Android開發(fā)工具、Android歷史查看器和Android Traceview。單擊Next兩次,閱讀EULA并決定是否同意,等待包安裝。一些Android包包含未簽名的內(nèi)容,即使這樣您也應(yīng)該繼續(xù)安裝。
- 在提示時(shí)重新啟動(dòng)Flash Builder。
- 您需要將Flash Builder指向您的Android SDK的位置。轉(zhuǎn)到Window > Preferences(在OS X上為Flash Builder > Preferences)并單擊Android。單擊Browse并選擇您的Android SDK的根位置(比如C:\Users\dan\Programs\android-sdk)。如果您缺少Android SDK的任何組件,您將收到一個(gè)指令要求運(yùn)行Android SDK管理器并安裝它們。選擇最新版本的SDK并單擊OK。
- 單擊Window > Android SDK and AVD Manager。
- 轉(zhuǎn)到Available Packages并選擇最新的Google Inc.包,以確保您擁有最新的Android SDK和API包。您可能還希望安裝USB驅(qū)動(dòng)程序,具體取決于您的設(shè)備。
- 關(guān)閉此窗口。您現(xiàn)在應(yīng)該能夠單擊File > New Project,查看并輸入Android Project的信息。完成之后,F(xiàn)lash Builder就已正確配置。
連接并測(cè)試您的Android設(shè)備
您可能急于了解編寫代碼的具體細(xì)節(jié),但如果現(xiàn)在確認(rèn)您的電話能夠連接并經(jīng)過了Android SDK的識(shí)別,將在以后省掉不少麻煩。
- 連接您的Android設(shè)備
- 在設(shè)備上,轉(zhuǎn)到Settings > Applications > Development并確保勾選了"USB Debugging"復(fù)選框,確認(rèn)開發(fā)模式已啟用。
- 如果有必要,單擊操作您計(jì)算機(jī)上允許安裝驅(qū)動(dòng)程序的對(duì)話框。在Windows上,您可能希望選擇位于android_sdk\usb_driver文件夾中的驅(qū)動(dòng)程序。
- 打開一個(gè)命令提示符或終端,運(yùn)行"adb devices"。
- 您應(yīng)該看到列出了您的設(shè)備ID。如果沒有,請(qǐng)查閱在線指南,使adb可處理您的電話。如果該命令生成"command not found"或類似錯(cuò)誤,請(qǐng)將android_sdk\tools文件夾的位置添加到您的系統(tǒng)PATH變量,并再試一次。
創(chuàng)建一個(gè)新Android項(xiàng)目
我們現(xiàn)在必須在Flash Builder中創(chuàng)建一個(gè)新Android項(xiàng)目,要求鏈接器查找隨AIR SDK提供的Java API JAR文件。
- 在Flash Builder中,轉(zhuǎn)到File > New > Project。
- 選擇Android Project并單擊Next。
- 將項(xiàng)目命名為HelloANENative。
- 標(biāo)注項(xiàng)目位置(如果愿意,您也可以更改該位置)。
- 確保為您的構(gòu)建目標(biāo)選擇了一個(gè)最新的Android SDK。如果沒有看到您想要的目標(biāo),返回到前面的步驟以將Android SDK安裝在Eclipse中,或者更新SDK以包含您想要的API和目標(biāo)。本教程的剩余部分將假設(shè)您選擇了Android 2.3.3或更新版本,但這應(yīng)該不會(huì)影響下面的任何指令。
- 輸入包名稱com.<您的域>.example.android.helloANE。例如com.yourDomain.example.android.helloANE。
- 單擊Finish。
- Flash Builder將為您創(chuàng)建一個(gè)HelloANENativeActivity.java文件。使用包資源管理器打開它。
- 在包資源管理器中右鍵單擊HelloANENative項(xiàng)目,單擊Properties。
- 單擊Java Build Path,然后單擊Libraries。
- 您現(xiàn)在必須添加Java API,以便連接ActionScript 3。單擊Add External JARs。
- 找到并選擇FlashRuntimeExtensions.jar文件(該文件的路徑類似于:C:\...\Adobe Flash Builder 4.5\sdks\4.5.2\lib\android\)
- 單擊OK解除項(xiàng)目屬性對(duì)話框。
您還有一項(xiàng)項(xiàng)目配置任務(wù):設(shè)置應(yīng)用程序,以擁有使用設(shè)備的震動(dòng)控件的權(quán)限。
- 打開AndroidManifest.xml文件。您應(yīng)該看到Android Manifest Permissions屏幕。
- 單擊Add并選擇Uses Permission,然后單擊OK。
- 在Attributes for Uses Permission下,選擇android.permission.VIBRATE。
- 選擇HelloANENative Manifest文件。
您已執(zhí)行了這一步,所以如果您決定創(chuàng)建原生測(cè)試案例,您的原生代碼將擁有運(yùn)行所需的必要權(quán)限。盡管本教程沒有介紹它,在繼續(xù)編寫ActionScript 3之前測(cè)試原生代碼可能很有幫助——尤其是對(duì)于更高級(jí)的原生擴(kuò)展。
什么是擴(kuò)展上下文?
現(xiàn)在您的Android項(xiàng)目已正確配置,您必須開始添加在ActionScript和您的原生Java代碼之間建立橋梁的結(jié)構(gòu)。這些結(jié)構(gòu)中的第一個(gè)是一個(gè)擴(kuò)展上下文。擴(kuò)展上下文負(fù)責(zé)包含最多3個(gè)基于原生擴(kuò)展的項(xiàng)目(另請(qǐng)參見Oliver Goldman的文章Extending Adobe AIR*):
- 原生函數(shù)到ActionScript可飲用的名稱的映射。這允許ActionScript代碼調(diào)用特定的原生函數(shù),是原生擴(kuò)展的核心部分。
- 一個(gè)ActionScript對(duì)象的引用,它在原生代碼與您的AIR應(yīng)用程序之間共享。
- 原生代碼結(jié)構(gòu)的引用,它僅可從原生代碼訪問。
現(xiàn)在您的原生擴(kuò)展可以擁有多個(gè)擴(kuò)展上下文,您應(yīng)該基于功能將它們分開。在本例中,您僅需要一個(gè)上下文,它將提供一個(gè)映射來訪問Android震動(dòng)功能。
創(chuàng)建一個(gè)震動(dòng)擴(kuò)展上下文
接下來您將創(chuàng)建一個(gè)新VibrationExtensionContext類。
- 在包資源管理器中,右鍵單擊src.com.yourDomain.example.android.helloANE包并選擇New > Class。
- 將包設(shè)置為com.yourDomain.example.android.helloANE.extensions。
- 將名稱設(shè)置為VibrationExtensionContext。
- 將超類設(shè)置為com.adobe.fre.FREContext。您可以使用Browse按鈕選擇此類。這是Adobe提供來使原生擴(kuò)展橋生效的AIR Java API。
- 單擊Finish創(chuàng)建新類。
您將看到已為您創(chuàng)建了兩個(gè)函數(shù):public void dispose()和public Map<String, FREFunction> getFunctions()。您可能已猜到,getFunctions()必須返回字符串(在您的ActionScript 3代碼中引用和任何FREFunction類(您接下來將定義)之間的一個(gè)鍵值對(duì)映射。Adobe提供的API為您提供了以縮寫詞FRE(表示Flash運(yùn)行時(shí)擴(kuò)展)開頭的類和函數(shù)。
創(chuàng)建函數(shù)映射
在您的原生擴(kuò)展中定義函數(shù)的第一步是創(chuàng)建一個(gè)新Map用于返回。在getFunctions()類中,添加:
- @Override
- public Map<String,FREFunction> getFunctions()
- {
- Map<String, FREFunction> functionMap = new HashMap<String, FREFunction>();
- return functionMap;
- }
這創(chuàng)建一個(gè)空HashMap,但它如果是空,顯然不是很有用。您將映射3個(gè)鍵值對(duì),每個(gè)鍵值對(duì)將定義一個(gè)實(shí)現(xiàn)FREFunction接口的類:
- 將isSupported映射到一個(gè)VibrationSupportedFunction。這將運(yùn)行某種邏輯,將一個(gè)FREObject傳遞到包含true或false(具體取決于平臺(tái)是否支持震動(dòng))的ActionScript 3。
注意:一種最佳實(shí)踐是在使用您的原生擴(kuò)展的其他功能之前,始終允許ActionScript 3代碼執(zhí)行兼容性檢查。
- 將vibrateMe映射到一個(gè)VibrationVibrateFunction。這個(gè)FREFunction接受一個(gè)來自ActionScript 3的參數(shù),以控制震動(dòng)的持續(xù)時(shí)間,然后在您的設(shè)備上執(zhí)行實(shí)際的震動(dòng)。
- 將initMe映射到一個(gè)VibrationInitFunction。在其他函數(shù)準(zhǔn)備好被使用之前,此函數(shù)允許原生代碼執(zhí)行和初始化任務(wù)。在本例中,您將創(chuàng)建Android的VIBRATOR_SERVICE的引用,它將用在VibrationVibrateFunction(在ActionScript 3中也稱為"vibrateMe")中。
- 在getFunctions()類中,在您的functionMap對(duì)象上調(diào)用put()函數(shù)。第一個(gè)參數(shù)將是一個(gè)字符串,表示上述函數(shù)名稱,第二個(gè)函數(shù)是該函數(shù)(還未創(chuàng)建)的一個(gè)新實(shí)例:
- functionMap.put("initMe", new VibrationInitFunction());
- functionMap.put("isSupported", new VibrationSupportedFunction());
- functionMap.put("vibrateMe", new VibrationVibrateFunction());
三個(gè)函數(shù)中的第一個(gè):VibrationInitFunction
您已定義了三個(gè)函數(shù)。接下來,您將它們編寫為實(shí)現(xiàn)FREFunction接口的類。您將從VibrationInitFunction開始,它被調(diào)用時(shí)將在您的VibrationExtensionContext中設(shè)置一個(gè)將在以后用于震動(dòng)設(shè)備的類。
- 右鍵單擊包資源管理器中的一個(gè)包,選擇New > Class。
- 將包設(shè)置為 com.yourDomain.example.android.helloANE.extensions,將名稱設(shè)置為VibrationInitFunction。
- 保留Superclass為一個(gè)java.lang.Object,向Interfaces框添加一個(gè)新條目:com.adobe.fre.FREFunction。
- 單擊Finish。
請(qǐng)注意,你可以通過使用Eclipse的代碼生成功能完成以上的步驟:點(diǎn)擊你希望創(chuàng)建的類(本例中是VibrationInitFunction),敲擊Ctrl –1打開代碼提示窗口,然后選擇 "創(chuàng)建VibrationInitFunction類 "。這樣編輯器就可以自動(dòng)幫你創(chuàng)建類代碼了。
您將看到,已在您的VibrationInitFunction中為您定義了一個(gè)函數(shù):call(),它接受兩個(gè)參數(shù):一個(gè)FREContext和一個(gè)FREObject[]數(shù)組。默認(rèn)情況下,這兩個(gè)參數(shù)定義為arg0和arg1,但您可以為它們提供更具描述性的名稱。將call()函數(shù)定義更改為類似以下形式:
- public FREObject call(FREContext context, FREObject[] passedArgs)
當(dāng)調(diào)用此函數(shù)時(shí),第一個(gè)參數(shù)將是您的VibrationExtensionContext的引用,第二個(gè)參數(shù)將是ActionScript 3代碼傳遞的所有參數(shù)(如果有)的數(shù)組。這將對(duì)您的VibrationVibrateFunction很重要,它將基于該數(shù)組中的第一個(gè)參數(shù)設(shè)置持續(xù)時(shí)間。
現(xiàn)在,您的init函數(shù)將使用傳入的FREContext對(duì)象來獲取VibrationExtensionContext,然后獲取它所屬的Android活動(dòng)。使用此活動(dòng)引用,它然后將能夠檢索名為Context.VIBRATOR_SERVICE的全局Android系統(tǒng)服務(wù),該服務(wù)將允許您控制震動(dòng)馬達(dá)。您將此系統(tǒng)服務(wù)存儲(chǔ)在您的VibrationExtensionContext中包含的一個(gè)新變量中,您稍后將創(chuàng)建它:
- 在VibrationInitFunction的call()函數(shù)中,添加以下代碼來從傳入的FREContext獲取VibrationExtensionContext:
- VibrationExtensionContext vbc = (VibrationExtensionContext)context;
- 您現(xiàn)在可以使用VibrationExtensionContext getActivity()函數(shù)抓取活動(dòng)。在FREContext類中包含此函數(shù)的目的是為了支持常見任務(wù),比如您需要抓取上下文的活動(dòng),進(jìn)而擁有我們需要的SystemService的路徑。
- Activity a = vbc.getActivity();
- 您現(xiàn)在可以調(diào)用a.getSystemService(),傳入全局Context.VIBRATOR_SERVICE的引用。這將返回一個(gè)類型為Vibrator的對(duì)象。您需要一個(gè)可用于整個(gè)擴(kuò)展上下文的位置來存儲(chǔ)此引用,所以將它放在一個(gè)位于VibrationExtensionContext內(nèi)的新變量vb中。
- vbc.vb = (Vibrator)a.getSystemService(Context.VIBRATOR_SERVICE);
- 您現(xiàn)在應(yīng)該打開VibrationExtensionContext類,向該類添加一個(gè)名為vb的公共變量:
- public Vibrator vb = null;
現(xiàn)在,您已創(chuàng)建了一個(gè)原生代碼結(jié)構(gòu)的引用vb Vibrator類,它可供可引用您的VibrationExtensionContext的任何類訪問。
您完成的VibrationInitFunction看起來應(yīng)該類似于:
- public class VibrationInitFunction implements FREFunction
- {
- @Override
- public FREObject call(FREContext context, FREObject[] passedArgs)
- {
- VibrationExtensionContext vbc = (VibrationExtensionContext)context;
- Activity a = vbc.getActivity();
- vbc.vb = (Vibrator)a.getSystemService(Context.VIBRATOR_SERVICE);
- return null;
- }
- }
您已學(xué)習(xí)了如何:創(chuàng)建一個(gè)實(shí)現(xiàn)FREFunction的類,理解從ActionSscript 3傳入的參數(shù),通過FREContext參數(shù)傳入您的擴(kuò)展上下文,而且您已看到擴(kuò)展的一種常見的初始化任務(wù)。
接下來您必須實(shí)現(xiàn)在Map<String, FREFunction> getFunctions()函數(shù)中實(shí)現(xiàn)的其他兩個(gè)FREFunction。
三個(gè)函數(shù)中的第二個(gè):VibrationSupportedFunction
您前面定義的第二個(gè)函數(shù)是VibrationSupportedFunction。您在getFunctions()返回的HashMap中已表明,此函數(shù)可使用ActionScript 3字符串isSupported調(diào)用。此函數(shù)的創(chuàng)建非常類似于VibrationInitFunction,但它將向您展示如何在一個(gè)FREObject內(nèi)返回一個(gè)布爾值。
- 右鍵單擊包資源管理器中的一個(gè)包,單擊New > Class。
- 選擇com.yourDomain.example.android.helloANE.extensions作為包,將此類命名為VibrationSupportedFunction,正如前面的HashMap中提供的值所期望的。
- 選擇FREFunction作為此類將實(shí)現(xiàn)的一個(gè)接口。
- 單擊Finish創(chuàng)建該類。
- passedArgs, respectively.
將此類的參數(shù)分別從arg0和arg1更改為context和passedArgs。 - 您將希望返回一個(gè)FREObject作為call()函數(shù)中的結(jié)果,現(xiàn)在創(chuàng)建并返回該結(jié)果。您還想要您的VibrationExtensionContext的引用,所以通過轉(zhuǎn)換上下文參數(shù)來創(chuàng)建它:
- FREObject result = null;
- VibrationExtensionContext vbc = (VibrationExtensionContext)context;
- // ...
- return result;
- 此函數(shù)的邏輯將如下所示:
- VibrationInitFunction函數(shù)已調(diào)用,因此應(yīng)該設(shè)置vbc.vc。
- vbc.vc是否非空?如果非空,結(jié)果應(yīng)該為true。
- 如果vbc.vc為空,我們可以合理地推斷初始化失敗,以及此平臺(tái)不支持震動(dòng)。結(jié)果應(yīng)該設(shè)置為false。
創(chuàng)建以下if語句:
- if (vbc.vb == null)
- {
- result = FREObject.newObject(false);
- }
- else
- {
- result = FREObject.newObject(true);
- }
- 還有一項(xiàng)任務(wù):在FREObject上調(diào)用newObject()可能導(dǎo)致拋出一個(gè)FREWrongThreadException異常。您會(huì)將您的if語句放在一個(gè)try catch代碼塊中,以處理此不測(cè)事件。
您完成的call()函數(shù)現(xiàn)在看起來應(yīng)該類似于:
- @Override
- public FREObject call(FREContext context, FREObject[] passedArgs)
- {
- FREObject result = null;
- VibrationExtensionContext vbc = (VibrationExtensionContext)context;
- try
- {
- if (vbc.vb == null)
- {
- // Not supported
- result = FREObject.newObject(false);
- }
- else
- {
- // Supported
- result = FREObject.newObject(true);
- }
- }
- catch (FREWrongThreadException fwte)
- {
- fwte.printStackTrace();
- }
- return result;
- }
您現(xiàn)在有了3個(gè)原生擴(kuò)展函數(shù)中的第二個(gè):VibrationSupportedFunction。當(dāng)被ActionScript 3字符串isSupported調(diào)用時(shí),此函數(shù)將檢查VibrationExtensionContext"context"中的變量vb是否為非空。它將基于此條件返回值為true或false的FREObject,將捕獲一個(gè)可能由FREObject的靜態(tài)newObject()函數(shù)拋出的FREWrongThreadException。
三個(gè)函數(shù)中的第三個(gè):VibrationVibrateFunction
您必須實(shí)現(xiàn)的最后一個(gè)原生擴(kuò)展函數(shù)執(zhí)行您的原生擴(kuò)展的核心職責(zé):它允許AIR應(yīng)用程序震動(dòng)設(shè)備的馬達(dá)指定的持續(xù)時(shí)間。
- 在包資源管理器中,右鍵單擊一個(gè)包并選擇New > Class。
- 選擇com.yourDomain.example.android.helloANE.extensions作為包,將類命名為VibrationVibrateFunction。
- 將類實(shí)現(xiàn)命名為com.adobe.fre.FREFunction。
- 單擊Finish創(chuàng)建該類。
- 在函數(shù)定義中,將arg0重命名為context,將arg1重命名為passedArgs。
- 創(chuàng)建一個(gè)名為result的空FREObject。
- 將上下文變量轉(zhuǎn)換一個(gè)名為vbc的VibrationExtensionContext變量。您將使用此變量訪問Vibrator對(duì)象vbc.vb。
我們現(xiàn)在已準(zhǔn)備好訪問第一個(gè)傳入的參數(shù)FREObject,嘗試將它設(shè)置為一個(gè)整數(shù)。如果數(shù)據(jù)格式奇怪,可能會(huì)拋出一個(gè)異常并且您將獲取該異常。您的call()函數(shù)現(xiàn)在看起來應(yīng)該類似于:
- @Override
- public FREObject call(FREContext context, FREObject[] passedArgs)
- {
- FREObject result = null;
- VibrationExtensionContext vbc = (VibrationExtensionContext)context;
- try
- {
- // Vibrate the device
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- return result;
- }
- 在try { // ... }代碼塊內(nèi),我們將嘗試抓取passedArgs數(shù)組中的第一個(gè)元素作為FREObject:
- FREObject fro = passedArgs[0];
- 我們現(xiàn)在可以在這個(gè)FREObject上調(diào)用getAsInt();來創(chuàng)建一個(gè)int:
- int duration = fro.getAsInt();
- 最后,在我們的vb Vibrator變量上調(diào)用Android原生震動(dòng)函數(shù),傳入持續(xù)時(shí)間:
- vbc.vb.vibrate(duration);
您現(xiàn)在已成功創(chuàng)建了3個(gè)原生函數(shù),將它們映射到了getFunctions()提供的HashMap中的字符串,創(chuàng)建執(zhí)行您的原生擴(kuò)展所需的所有操作所必要的原生邏輯。這樣就完成了VibrationExtensionContext的創(chuàng)建,它是您的原生擴(kuò)展需要的唯一的擴(kuò)展上下文。
創(chuàng)建主要擴(kuò)展類
您已創(chuàng)建了您的原生擴(kuò)展需要的一個(gè)且是唯一一個(gè)擴(kuò)展上下文,但您還未創(chuàng)建我們的擴(kuò)展的主要類。幸運(yùn)的是,添加此類很簡(jiǎn)單,我們所需做的就是創(chuàng)建一個(gè)名為VibrationExtension的類,它實(shí)現(xiàn)FREExtension接口。
FREExtesion接口定義initialize、dispose和createContext函數(shù),它們?cè)试S掛鉤到一個(gè)原生擴(kuò)展的生命周期中。盡管為我們提供了3個(gè)函數(shù),我們僅需要自定義一個(gè):createContext函數(shù)。此函數(shù)必須返回一個(gè)FREContext。幸運(yùn)的是,您已創(chuàng)建了您自己的VibrationExtensionContext,可以簡(jiǎn)單地返回此類的一個(gè)實(shí)例。
- 右鍵單擊一個(gè)包,選擇New > Class。
- 選擇com.yourDomain.example.android.helloANE.extensions作為包名稱。
- 將類命名為VibrationExtension。
- 使用接口框旁邊的Add按鈕添加類實(shí)現(xiàn)com.adobe.fre.FREExtension。
- 單擊Finish創(chuàng)建該類。
- 默認(rèn)情況下,createContext()函數(shù)中定義的字符串參數(shù)將顯示為arg0。此參數(shù)實(shí)際上是一個(gè)ID,定義要?jiǎng)?chuàng)建的上下文類型(它僅在您擁有多種上下文類型時(shí)才有用)。將arg0更改為contextType。
- 要完成createContext()函數(shù),我們僅需要返回VibrationExtensionContext的一個(gè)新實(shí)例。將return null;代碼替換為以下代碼:
- return new VibrationExtensionContext();
這將初始化并創(chuàng)建您的擴(kuò)展上下文,允許您使用放在您的原生擴(kuò)展內(nèi)的原生代碼。
將您的原生代碼導(dǎo)出為JAR文件
在本教程的以下各節(jié)中,我們將介紹如何編寫原生擴(kuò)展的ActionScript 3部分代碼,以及封裝和測(cè)試完成的原生擴(kuò)展文件和示例應(yīng)用程序。這些步驟將涉及以JAR文件的形式引用您的原生代碼。在Flash Builder中創(chuàng)建一個(gè)JAR文件很簡(jiǎn)單:
- 在包資源管理器中選擇您的HelloANENative項(xiàng)目之后,轉(zhuǎn)到File > Export。
- 選擇Java > JAR file并單擊Next。
- 選擇HelloANENative作為要導(dǎo)出的資源。
- 確保選擇了"Export generated class files and resources"。
- 選擇JAR文件的目標(biāo),將它命名為HelloANENative.JAR并單擊Finish。您將在您的Flex庫(kù)項(xiàng)目中創(chuàng)建extension.xml文件時(shí),以及運(yùn)行封裝命令來創(chuàng)建您的原生擴(kuò)展文件時(shí),使用此JAR文件。
創(chuàng)建ACTIONSCRIPT 3代碼
您已完成了在創(chuàng)建原生擴(kuò)展過程中大部分必要的編碼工作,創(chuàng)建了可使用其他函數(shù)、邏輯以及(如果有必要)甚至其他擴(kuò)展上下文進(jìn)行擴(kuò)展的Java代碼,以擴(kuò)大您的原生擴(kuò)展的范圍。
相對(duì)而言,創(chuàng)建完成此平臺(tái)橋所需的ActionScript 3代碼比較簡(jiǎn)單。您的任務(wù)包括:
- 創(chuàng)建和配置一個(gè)Flex庫(kù)項(xiàng)目。
- 創(chuàng)建一個(gè)extension.xml文件來描述您的擴(kuò)展。
您的ActionScript 3庫(kù)代碼將包括一個(gè)類,該類將導(dǎo)入flash.external.ExtensionContext API,提供以下函數(shù):
- 一個(gè)構(gòu)造函數(shù),它將創(chuàng)建一個(gè)具有合適ID的新擴(kuò)展上下文,還將調(diào)用您的initMe原生函數(shù)。
- 一個(gè)名為isSupported的函數(shù),它將調(diào)用我們的isSupported原生函數(shù),還將依據(jù)來自我們的原生代碼的響應(yīng)而返回true或false。
- 一個(gè)名為vibrate的函數(shù),它將接受一個(gè)表示持續(xù)時(shí)間的數(shù)字,使用此數(shù)字作為參數(shù)調(diào)用您的原生vibrateMe函數(shù)。
- 完成此代碼后,您的ActionScript 3庫(kù)函數(shù)就完成了,您可以繼續(xù)封裝和使用您的原生擴(kuò)展。請(qǐng)注意,庫(kù)函數(shù)定義了使用您的原生擴(kuò)展所必要的ActionScript 3 代碼,但它不是一個(gè)示例應(yīng)用程序。為了使用您的原生擴(kuò)展,您將必須從一個(gè)Flex移動(dòng)應(yīng)用程序引用這個(gè)庫(kù)應(yīng)用程序,在本指南后面一節(jié)中將創(chuàng)建該移動(dòng)應(yīng)用程序。
創(chuàng)建一個(gè)Flex庫(kù)項(xiàng)目
您的ActionScript 3 代碼將位于一個(gè)Flex庫(kù)項(xiàng)目中:
- 在Flash Builder中,在屏幕右上角選擇Flash perspective打開Flash透視圖。
- 單擊File > New > Flex Library Project。
- 將項(xiàng)目命名為HelloANELibrary。
- 確保選擇了Generic library單選按鈕。
- 確保勾選了"Include Adobe AIR libraries"。您的項(xiàng)目將依賴的原生擴(kuò)展庫(kù)包含在AIR API中。
- 單擊Finish創(chuàng)建項(xiàng)目。
- 在您的包資源管理器中打開HelloANELibrary項(xiàng)目,右鍵單擊src文件夾,選擇New > ActionScript Class。
- 將包命名為com.<您的域>.nativeExtensions.Vibrate。
- 將類命名為Vibrate。
- 將超類設(shè)置為flash.events.EventDispatcher。這將允許此類分派事件,這在您將原生擴(kuò)展集成到真實(shí)應(yīng)用程序中時(shí)很有用。
- Click Finish to create the Vibrate class.
向您的原生代碼編寫ActionScript 3橋
您現(xiàn)在必須創(chuàng)建與我們的擴(kuò)展上下文的連接,這將允許您訪問您使用Java創(chuàng)建的initMe、isSupported和vibrateMe。
- 在Vibrate類中,添加一個(gè)擴(kuò)展上下文的一個(gè)私有、靜態(tài)的引用:
- private static var extContext:ExtensionContext = null;
- 在構(gòu)造函數(shù)中,您將驗(yàn)證這個(gè)extContext變量是否已初始化。如果沒有,您將調(diào)用靜態(tài)函數(shù)ExtensionContext.createExtensionContext(),傳入兩個(gè)標(biāo)識(shí)符。第一個(gè)是一個(gè)ID,您稍后將在一個(gè)extension.xml文件中設(shè)置。第二個(gè)是一個(gè)參數(shù),傳遞到VibrationExtension的createContext()函數(shù)。您應(yīng)該記得,它允許您創(chuàng)建不同的擴(kuò)展上下文,因?yàn)槟挥幸粋€(gè),所以在原生代碼中忽略了此闡述。如果您擁有多個(gè)擴(kuò)展上下文,您應(yīng)該讓原生代碼使用if或switch語句分析您傳入的值,基于可用的共享字符串值創(chuàng)建合適的值。編寫以下代碼:
- if ( !extContext )
- {
- extContext = ExtensionContext.createExtensionContext("com.yourDomain.Vibrate","vibrate");
- extContext.call("initMe");
- }
- 請(qǐng)注意,您通過extContext.call()調(diào)用了initMe,沒有傳入其他參數(shù)。這將這將使用您使用Java編寫的VibrationInitFunction完成,將為您初始化震動(dòng)設(shè)備所必要的內(nèi)部數(shù)據(jù)結(jié)構(gòu)。
現(xiàn)在,只要任何使用您的新ActionScript 3庫(kù)的應(yīng)用程序調(diào)用Vibrate()構(gòu)造函數(shù),就會(huì)創(chuàng)建和初始化您的擴(kuò)展上下文。但是,您還有兩個(gè)函數(shù)要實(shí)現(xiàn)。首先創(chuàng)建isSupported()函數(shù),它將連接到原生isSupported函數(shù),并檢查您的應(yīng)用程序邏輯所返回的布爾值。
- 創(chuàng)建一個(gè)名為isSupported的靜態(tài)getter,它返回一個(gè)布爾值:
- public static function get isSupported():Boolean
- {
- var supported:Boolean = false;
- // ...
- return supported;
- }
- 在兩個(gè)語句之間,添加一個(gè)對(duì)extContext.call()的調(diào)用,傳入isSupported作為一個(gè)字符串參數(shù),這會(huì)將您的supported變量設(shè)置為返回的布爾值:
- supported = extContext.call("isSupported") as Boolean;
-
重復(fù)此過程以創(chuàng)建vibrateMe函數(shù),它將接受一個(gè)Number作為持續(xù)時(shí)間。此函數(shù)的創(chuàng)建很簡(jiǎn)單:
- public function vibrate(duration:Number):void
- {
- extContext.call("vibrateMe",duration);
- }
請(qǐng)注意,F(xiàn)lash Builder會(huì)自動(dòng)將您的庫(kù)編譯為一個(gè)SWC文件(位于項(xiàng)目的bin文件夾中。SWC文件是一個(gè)包含library.swf的壓縮文件。只要您使用ADT封裝一個(gè)ANE文件,就必須手動(dòng)引用SWC和SWF。因此,您現(xiàn)在應(yīng)該在壓縮文件管理工具中打開SWC文件,提取library.swf,將它放在HelloANELibrary的bin/目錄中:
- 導(dǎo)航到HelloANELibrary/bin/。
- 解壓HelloANELibrary.swc文件,或者在壓縮文件管理工具(比如7-Zip)中打開它。
- 您將在SWC壓縮文件中看到一個(gè)catalog.xml和一個(gè)library.swf文件。
library.swf文件需要放在您針對(duì)的每個(gè)平臺(tái)的原生代碼目錄內(nèi)。例如,可以將此文件放在了iOS/、android/、x86/等目錄內(nèi),具體取決于您的項(xiàng)目的目標(biāo)平臺(tái)。(對(duì)于更高級(jí)的ANE,您可以指定不同的library.swf的文件,只要您需要您的AS3庫(kù)對(duì)于不同平臺(tái)而言不同。但是,這與定義一個(gè)通用接口的最佳實(shí)踐不符,建議您堅(jiān)持使用單一版本的library.swf。)
- 完成時(shí),您的HelloANELibrary文件夾應(yīng)該包含HelloANELibrary.swc,HelloANENative應(yīng)該包含library.swf。
通過提取library.swf,您現(xiàn)在擁有創(chuàng)建原生擴(kuò)展所需的所有文件。請(qǐng)注意,只要更改了您的庫(kù)代碼,就必須重復(fù)步驟1到4,否則library.swf將過期。
現(xiàn)在您編寫了使用原生擴(kuò)展所需的所有庫(kù)代碼。
在extension.xml文件中描述您的原生擴(kuò)展
您創(chuàng)建了必要的代碼,但還未將所有內(nèi)容鏈接到一個(gè)ANE文件中。首先在您的Flex庫(kù)文件內(nèi)創(chuàng)建一個(gè)extension.xml文件。對(duì)于每個(gè)原生目標(biāo),此文件指向原生代碼(您的JAR文件),并描述初始化器函數(shù)(以及可選地,一個(gè)終結(jié)器函數(shù),本示例中不需要它)的包位置。在創(chuàng)建您的ANE文件(后面將在一個(gè)示例應(yīng)用程序中使用它)時(shí),將此文件傳遞給封裝程序。
在您的Flex庫(kù)項(xiàng)目中創(chuàng)建extension.xml文件:
- 右鍵單擊您的HelloANELibrary項(xiàng)目中的src文件夾。單擊New > File。
- 將文件命名為extension.xml。
- 右鍵單擊此文件并選擇Text Editor,而不是默認(rèn)的XML編輯器,以重新打開此文件。
- 以下XML描述了要使用的AIR命名空間(2.5)、擴(kuò)展的ID,以及我們希望針對(duì)的單一平臺(tái)(請(qǐng)注意"iPhone-ARM"是另一個(gè)通用的目標(biāo)平臺(tái)):
- <extension xmlns="http://ns.adobe.com/air/extension/2.5">
- <id>com.yourDomain.Vibrate</id>
- <versionNumber>1</versionNumber>
- <platforms> <platform name="Android-ARM"> <!-- ... --> </platform> </platforms> </extension>
-
在<platform>標(biāo)記內(nèi),現(xiàn)在將設(shè)置JAR文件在一個(gè)<nativeLibrary>標(biāo)記中的位置,將初始化器的位置設(shè)置為我們?cè)谠a中設(shè)置的位置(回想一下,您在VibrationExtension類中創(chuàng)建了initialize()函數(shù))。
- <applicationDeployment>
- <nativeLibrary>HelloANENative.jar</nativeLibrary>
- <initializer>com.yourDomain.example.android.helloANE.extensions.VibrationExtension </initializer>
- </applicationDeployment>
您現(xiàn)在已成功創(chuàng)建了您的extension.xml文件,擁有了創(chuàng)建ANE文件所需的所有組件。
封裝原生擴(kuò)展
目前,封裝一個(gè)原生擴(kuò)展需要使用命令行工具adt,向它傳遞一些參數(shù)。我建議在Windows中創(chuàng)建一個(gè)批處理腳本(.bat文件),或者在OS X中創(chuàng)建一個(gè)bash腳本(通常為.sh文件),您將創(chuàng)建的腳本將允許您在腳本的頂部設(shè)置您自己的變量,支持針對(duì)您的其他原生擴(kuò)展項(xiàng)目輕松調(diào)整它。
您需要將許多信息插入到腳本中。我將列出這些信息,給出我在我自己的系統(tǒng)上使用的值:
- adt的位置:C:\Program Files\Adobe Flash Builder 4.5\sdks\4.5.2\bin
- 編程根目錄:C:\Users\dan\Programs
- ActionScript 3庫(kù)目錄:%root_directory%\HelloANELibrary
- Android原生目錄:%root_directory%\HelloANENative
- 簽名選項(xiàng):-storetype pkcs12 -keystore "c:\Users\dan\Programs\ cert.p12"
- 目標(biāo)ANE文件:HelloANE.ane
- extension.xml的位置:%library_directory%\src\extension.xml
- 編譯的ActionScript 3庫(kù)SWC的位置:%library_directory%\bin\HelloANELibrary.swc
您應(yīng)該為您自己的系統(tǒng)創(chuàng)建一個(gè)類似的值列表。您然后可以使用以下ADT命令引用變量來插入它們。
- "%adt_directory%"\adt -package %signing_options% -target ane "%dest_ANE%" "%extension_XML%" -swc "%library_SWC%" -platform Android-ARM bin/library.swf -C "%native_directory%" .
此命令可能看起來很復(fù)雜,但只是運(yùn)行adt并傳入簽名選項(xiàng),指定ane作為目標(biāo),提供extension.xml文件,指定HelloANELibrary.swc文件,以Android-ARM作為目標(biāo)平臺(tái),以及高速ADT在何處查找原生庫(kù)文件。
Windows上的compile_ane.bat文件看起來可能類似于:
- set adt_directory=C:\Program Files\Adobe Flash Builder 4.5\sdks\4.5.2\bin
- set root_directory=C:\Users\dan\Programs
- set library_directory=%root_directory%\HelloANELibrary
- set native_directory=%root_directory%\HelloANENative
- set signing_options=-storetype pkcs12 -keystore "c:\Users\dan\Programs\cert.p12"
- set dest_ANE=HelloANE.ane
- set extension_XML=%library_directory%\src\extension.xml
- set library_SWC=%library_directory%\bin\HelloANELibrary.swc
- "%adt_directory%"/adt -package %signing_options% -target ane "%dest_ANE%" "%extension_XML%" -swc "%library_SWC%" -platform Android-ARM -C "%native_directory%" .
在Mac OS X上,該腳本可能類似于:
- #!/bin/bash
- adt_directory="/Users/Applications/Adobe Flash Builder 4.5/sdks/4.5.2/bin" root_directory=/Users/dan/Programs library_directory=${root_directory}/HelloANELibrary
- native_directory=${root_directory}/HelloANENative
- signing_options="-storetype pkcs12 -keystore /Users/dan/Programs/cert.p12"
- dest_ANE=HelloANE.ane
- extension_XML=${library_directory}/src/extension.xml
- library_SWC=${library_directory}/bin/HelloANELibrary.swc
- "${adt_directory}"/adt -package ${signing_options} -target ane "${dest_ANE}" "${extension_XML}" -swc "${library_SWC}" -platform Android-ARM -C "${native_directory}" .
請(qǐng)注意,我使用了一個(gè)p12文件作為簽名證書。您可以使用您通常用于簽名AIR文件的文件代替。如果您需要?jiǎng)?chuàng)建一個(gè),最簡(jiǎn)單的方式是在Flash Builder中打開一個(gè)Flex或AIR項(xiàng)目,轉(zhuǎn)到Project > Export Release Build。在第二步,您將可以選擇使用GUI創(chuàng)建一個(gè)證書。
從命令行運(yùn)行您的腳本,輸入您證書的密碼,應(yīng)該還會(huì)創(chuàng)建%dest_ANE%文件,它可用于示例應(yīng)用程序中!
在FLEX示例應(yīng)用程序中使用原生擴(kuò)展
您現(xiàn)在將創(chuàng)建一個(gè)使用您的原生擴(kuò)展的Flex移動(dòng)應(yīng)用程序!設(shè)置一個(gè)項(xiàng)目并將它部署到Android的流程很簡(jiǎn)單:
- 在Flash Builder 4.5.2中,單擊File > New > Flex Mobile Project。
- 將項(xiàng)目命名為HelloANESample。
- 確保您使用了4.5.2或更高版本的SDK,單擊Next。
- 確保僅選擇了Google Android作為目標(biāo)平臺(tái)。
- 選擇一個(gè)基于視圖的應(yīng)用程序,單擊Next。
- 單擊Next,因?yàn)槟恍枰魏畏?wù)器設(shè)置。
- 單擊NativeExtensions選項(xiàng)卡,它將允許您找到您的應(yīng)用程序需要的任何ANE文件。
- 單擊Add并瀏覽到您在上一步中封裝的ANE文件。它應(yīng)該位于HelloANELibrary文件夾內(nèi),名為HelloANE.ane。
- 單擊OK,您應(yīng)該在ANE文件的條目旁邊看到一個(gè)綠色的勾選符號(hào)。如果展開此條目,應(yīng)該會(huì)看到以下警告"Launching on win32(Windows-x86) is not supported"(或針對(duì)OS X的類似消息)。這是因?yàn)椋覀冊(cè)诰帉懺鷶U(kuò)展的元神代碼時(shí),沒有以我們的桌面環(huán)境為目標(biāo),在編寫extension.xml或運(yùn)行ADT時(shí)也沒有配置它。
- 單擊Finish。
- 現(xiàn)在再次檢查確認(rèn)原生擴(kuò)展已包含在封裝的文件中,而不只是包含在構(gòu)建路徑中。盡管它應(yīng)該已正確配置,但如果您修改了原生擴(kuò)展,可能必須執(zhí)行這些步驟。在包資源管理器中右鍵單擊您的項(xiàng)目,選擇Properties。
- 展開Flex Build Packaging并選擇Google Android。
- 單擊Native Extensions選項(xiàng)卡。
- 您應(yīng)該在原生擴(kuò)展旁邊看到一個(gè)綠色勾選符號(hào),以及在針對(duì)該原生擴(kuò)展的Package列中看到一個(gè)勾選符號(hào)。如果沒有,請(qǐng)選擇該復(fù)選框。
- 單擊OK關(guān)閉項(xiàng)目屬性。
配置權(quán)限
要完成您項(xiàng)目的設(shè)置,需要指定您的應(yīng)用程序需要使用Android震動(dòng)控件。在利用設(shè)備的其他功能時(shí),請(qǐng)?zhí)貏e注意這個(gè)方面——很容易忘記某些功能需要其他權(quán)限。AIR應(yīng)用程序描述符不會(huì)使這些條目可用于注釋掉的部分中,因?yàn)檎谑褂眠\(yùn)行時(shí)的功能。如果您忘記了指定合適的權(quán)限,原生代碼將無法工作,可能將拋出一個(gè)與權(quán)限相關(guān)的異常。(在Android上,此輸出可在adb shell中使用logcat輕松看到。
要向AIR應(yīng)用程序描述符添加權(quán)限:
- 右鍵單擊HelloANESample-app.xml應(yīng)用程序描述符,選擇使用文本編輯器打開它。
- 向下滾動(dòng)到這一節(jié):
- <android>
- <manifestAdditions><![CDATA[
- <manifest android:installLocation="auto">
- 添加使用震動(dòng)控件的權(quán)限:
- <uses-permission android:name="android.permission.VIBRATE"/>
使用您的原生擴(kuò)展
現(xiàn)在項(xiàng)目已配置,您可以向主視圖添加一個(gè)震動(dòng)按鈕:
- 在s:View標(biāo)記(類的主體中)之間,添加一個(gè)新s:Button。為它提供一個(gè)標(biāo)簽Vibrate using ANE,創(chuàng)建一個(gè)新的單擊處理函數(shù)。Flash Builder應(yīng)該自動(dòng)為您創(chuàng)建一個(gè)fx:Script標(biāo)記和ActionScript 3單擊處理函數(shù)。
- 在您的單擊處理函數(shù)內(nèi)創(chuàng)建一個(gè)新Vibrate類,它將通過一個(gè)ActionScript 3對(duì)象公開您的原生擴(kuò)展:
- var v:Vibrate = new Vibrate();
- 跟蹤v.isSupported的值,然后調(diào)用您的主要震動(dòng)函數(shù),傳入硬編碼的值100作為馬達(dá)應(yīng)該運(yùn)行的毫秒數(shù):
- trace("Is this ANE supported on this platform? " + Vibrate.isSupported);
- v.vibrate(100);
- 單擊主要工具欄中的調(diào)試按鈕。
- 選擇Google Android作為目標(biāo)平臺(tái),選擇啟動(dòng)設(shè)備,通過USB進(jìn)行調(diào)試。
- 單擊Debug。
Flex應(yīng)用程序現(xiàn)在應(yīng)該啟動(dòng)設(shè)備,使用ANE提供一個(gè)標(biāo)為Vibrate的按鈕。點(diǎn)擊此按鈕應(yīng)該會(huì)產(chǎn)生來自您的Android設(shè)備中的馬達(dá)的持續(xù)100ms的震動(dòng)!您還將在Flash Builder的控制臺(tái)視圖中注意到以下輸出:
- [SWF] com.yourDomain.Vibrate - 2,916 bytes after decompression
- [SWF] HelloANESample.swf - 2,702,220 bytes after decompression
- Is this ANE supported on this platform? True
如果您希望控制震動(dòng)持續(xù)時(shí)間,可以添加一個(gè)TextInput或數(shù)字輸入表。只需將我們硬編碼的參數(shù)100替換為一個(gè)全局范圍的變量,使用一個(gè)控件來設(shè)置此變量?,F(xiàn)在,編寫應(yīng)用程序的ActionScript 3代碼與其他Flex應(yīng)用程序開發(fā)沒什么兩樣。
延伸閱讀
在本指南中,您了解到AIR原生擴(kuò)展允許擴(kuò)展Adobe AIR的功能,為您的應(yīng)用程序提供訪問設(shè)備和硬件功能的能力,這些功能無法單獨(dú)通過運(yùn)行時(shí)API訪問。您學(xué)習(xí)了如何為Android創(chuàng)建原生擴(kuò)展,可以將這些技能用于其他目標(biāo)平臺(tái)。在本例中,您重點(diǎn)學(xué)習(xí)了使Android設(shè)備的震動(dòng)馬達(dá)激活指定的持續(xù)時(shí)間的簡(jiǎn)單任務(wù),這個(gè)示例演示了如何創(chuàng)建并初始化一個(gè)原生擴(kuò)展,以及在您的原生代碼和AIR應(yīng)用程序之間來回傳遞數(shù)據(jù)。
為了完成此任務(wù),您:
- 編寫了原生Java代碼來連接Adobe AIR所提供的原生擴(kuò)展API(FREObject、FREFunction等)。
- 編寫了一個(gè)包含ActionScript 3 API的Flex庫(kù)。這些API掛鉤到您的原生API中。
- 編寫一個(gè)描述我們的擴(kuò)展的 extension.xml。
- 編寫一個(gè) batch/bash 文件,使用命令行實(shí)用工具 ADT 封裝我們的原始擴(kuò)展。
- 創(chuàng)建一個(gè)使用原生擴(kuò)展的移動(dòng)Flex項(xiàng)目。
- 盡管您重點(diǎn)關(guān)注的是Android,原生擴(kuò)展也適用于iOS、Mac OS X、Windows和Adobe AIR for TV。您可以創(chuàng)建針對(duì)多個(gè)平臺(tái)的單一原生擴(kuò)展,您的應(yīng)用程序邏輯可以按平臺(tái)確定(在運(yùn)行時(shí)或編譯時(shí))具體的功能是否受支持。
- 您現(xiàn)在擁有了創(chuàng)建您自己的原生擴(kuò)展所必要的知識(shí)和技能。您的應(yīng)用程序可訪問更多硬件功能,利用原生優(yōu)化的代碼或第三方庫(kù),甚至生成多個(gè)線程來處理耗時(shí)的計(jì)算,而不影響您的AIR應(yīng)用程序的運(yùn)行。
在原生擴(kuò)展中包含資產(chǎn)
我們的示例不需要除已編譯代碼外的任何資產(chǎn),但是您可能希望您的原生擴(kuò)展能夠訪問圖像、文件、數(shù)據(jù)庫(kù)或配置存儲(chǔ)等。這很可能發(fā)生,并且需要注意一些移動(dòng)方面的考慮因素:
- 在Android上,將您的資產(chǎn)包含在Android項(xiàng)目路徑的"res"文件夾中。這些文件將合并到您的主要應(yīng)用程序的資源目錄中,所以您需要選擇不會(huì)與其他資產(chǎn)沖突的唯一名稱。要訪問它們,您可以使用FREContext.getResourceId(),傳入想要的資源ID(另請(qǐng)參見Oliver Goldman的文章"擴(kuò)展Adobe AIR*")。
- 在iOS上,資源通過NSBundle API來訪問,請(qǐng)注意,在編譯項(xiàng)目時(shí)命名空間會(huì)扁平化,您為資源選擇的名稱(即使僅在原生代碼中使用)應(yīng)該保證不會(huì)與您項(xiàng)目中的其他資源沖突。例如,不要在您項(xiàng)目中的任何地方使用兩個(gè)都名為L(zhǎng)ocalizable.strings的資源(另請(qǐng)參見Oliver Goldman的文章"擴(kuò)展Adobe AIR*")。
分派狀態(tài)事件
您可能將會(huì)發(fā)現(xiàn),您的原生擴(kuò)展必須在原生代碼中執(zhí)行異步任務(wù),您將需要一種方式來在任務(wù)完成時(shí)將通知傳遞給您的AIR應(yīng)用程序。這通過函數(shù)FREContext類中的函數(shù)dispatchStatusEventAsync(String code, String level);來完成。例如,以下Java代碼告訴一個(gè)虛構(gòu)的原生擴(kuò)展庫(kù),有一個(gè)編碼為"DATA_CHANGED"的狀態(tài)事件:
- context.dispatchStatusEventAsync("DATA_CHANGED", stringData);
- 此狀態(tài)事件將異步分派,并且(假設(shè)您的AIR應(yīng)用程序不是很忙)將立即可供相應(yīng)的原生擴(kuò)展ActionScript 3事件監(jiān)聽器使用。因?yàn)樯舷挛目梢苑峙蛇@些事件,所以您將必須要求原生擴(kuò)展庫(kù)監(jiān)聽它們:
- context.addEventListener(StatusEvent.STATUS, onStatus);
- ...
- private function onStatus(e:StatusEvent):void
- {
- if (e.code == "DATA_CHANGED")
- {
- var stringData:String = e.level;
- // ...
- }
- }
狀態(tài)事件提供了一種方便的方式來在原生代碼任務(wù)的狀態(tài)上更新您的原生擴(kuò)展庫(kù)(進(jìn)而更新您最終的AIR和Flex應(yīng)用程序)。
了解更多信息
您可以閱讀本指南開頭的"其他資源"一節(jié)中的內(nèi)容,繼續(xù)了解原生擴(kuò)展的知識(shí)。這些資源包括Adobe已創(chuàng)建和分發(fā)的原生擴(kuò)展的鏈接,允許您通過將原生擴(kuò)展文件放在您的Flex和ActionScript 3應(yīng)用程序中而擴(kuò)展AIR的功能。
另外,一定要查閱Adobe AIR開發(fā)人員中心中的原生擴(kuò)展示例*。
關(guān)于作者
Daniel Koestler 是 Adobe 的一名應(yīng)用程序開發(fā)人員,他使用 Adobe AIR、Flex 和 Flash Builder。他從詹姆斯麥迪遜大學(xué)畢業(yè),主修計(jì)算機(jī)科學(xué)和天文學(xué)。作為一名應(yīng)用程序開發(fā)人員,Dan 有機(jī)會(huì)在 Adobe 內(nèi)部和外部創(chuàng)建真實(shí)的應(yīng)用程序,并借助這些經(jīng)驗(yàn)為負(fù)責(zé) AIR 2、Flex 4 和 Flash Builder 的小組提供反饋。他曾幫助創(chuàng)建 AIR 新聞閱讀器 ShareFire,近期在 Adobe MAX 2009 上探討了 AIR 和 Flex 中的輔助功能,演示一個(gè)可供有視覺障礙的用戶使用的簡(jiǎn)單的 Twitter 客戶端。Daniel 通過他的博客*和 Twitter* 討論 AIR、Flex 和 Flash。