您好,登錄后才能下訂單哦!
這兩天對Flash游戲如何去接入android平臺的SDK做了下研究,做了4399的支付SDK接入的工作,這里與大家分享下。
一、ANE的介紹
(網絡描述也是一大堆,這里描述摘自http://blog.csdn.net/myquark/article/details/7904030)
Adobe AIR Native Extension,Adobe AIR的本地擴展,簡稱ANE。什么叫本地擴展?因為Adobe AIR是跨平臺的一個運行時,可以在Windows,Mac,Android,iOS等系統上跑,正是因為其跨平臺,所以它本身的功能就有局限性,不可能面面俱到;換句話來說,比如我們想在flash程序中調用一下系統的消息通知功能,但是AIR并沒有這個功能,那么怎么辦?這就要根據本地平臺寫段代碼,讓AIR委托本地平臺去執行這段代碼,這樣就達到了拓展AIR程序的功能。換個角度來看問題,就好像系統有個dll文件,AIR可以去直接調用這個dll文件(這只是一個比方而已,讓大家更容易理解,實際上AIR不能直接調用dll文件)。我們可以開發一個Android手機振動程序,然后打包成ANE,這樣運行在AIR中的程序就可以調用寫好的手機程序了。有了ANE機制,我們就可以開發很多Flash無法完成但是卻可以使用的功能。
二、ANE開發步驟
ANE的生成需要兩個步驟,一個是生成本地的jar包,一個生成SWC庫文件,最后進行編譯合成。
本文開發工具為fb 4.7 與eclipse為主
1、創建ane Android項目,生成本地jar包
準備工作
1)在eclipse中創建一個android的項目,假定命名為4399PaySDKANE_JAVA;
2) 將需要依賴的包(4399PaySdk.jar和FlashRuntimeExtensions.jar)添加到項目的libs目錄下。
3)在項目屬性中-java build path-Libraries下,添加以下
4399PaySdk.jar(4399的支付sdk包,在http://opensj.4399api.net/dev/downloadExchange可以下載到)
FlashRuntimeExtensions.jar(該包在E:\softinstall\ADOBE\Adobe Flash Builder 4.7\sdks\4.6.0\lib\android可找到)
4)在項目屬性 - Java Build Path - Order and Export 下,將游戲 SDK 及其依賴的 JAR 包(4399PaySdk.jar)打上勾,確保能夠被輸出到生成的 JAR 包中;
準備工作有些多哈。接下來正式進入開發。
編碼部分:
1、編寫 FREContext 的派生類(YJPaymentApiContext.java)
package com.sj4399.pay.ane; import java.util.HashMap; import java.util.Map; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; public class YJPaymentApiContext extends FREContext { @Override public void dispose() { } @Override public Map<String, FREFunction> getFunctions() { return null; } }
空的文件先不管。
2、編寫 FREExtension 的派生類(如:YJPaymentApiExtension),在 createContext 方法中創建 YJPaymentApiContext的實例,并作為該方法的結果值返回。
package com.sj4399.pay.ane; import com.adobe.fre.FREContext; import com.adobe.fre.FREExtension; public class YJPaymentApiExtension implements FREExtension { @Override public FREContext createContext(String arg0) { // TODO Auto-generated method stub return new YJPaymentApiContext(); } @Override public void dispose() { // TODO Auto-generated method stub } @Override public void initialize() { // TODO Auto-generated method stub } }
3、編寫一系列 FREFunction 的派生類(如:YJFInit,YJFLogin……等),以實現每一個接口,每個接口方法用一個 FREFunction 派生類實現;
以YJFInit.java為例
package com.sj4399.pay.ane; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; import com.adobe.fre.FREObject; import com.sj4399.pay.YjPaymentApi; public class YJFInit implements FREFunction { private static final String TAG = "YJFInit"; @Override public FREObject call(FREContext context, FREObject[] args) { YJPaymentApiContext yjac = (YJPaymentApiContext)context; YjPaymentApi.getInstance().init(yjac.getActivity()); return null; } }
我們通過
context.dispatchStatusEventAsync(callbackString, "");
進行回調給as3端。編寫完其他接口類即可。
4、修改 YJPaymentApiContext的 getFunctions 方法,將實現的每一個 FREFunction 派生類添加到函數集合中,該函數集合作為該方法的結果值返回;此函數集合即承擔接口調用職責
package com.sj4399.pay.ane; import java.util.HashMap; import java.util.Map; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; public class YJPaymentApiContext extends FREContext { @Override public void dispose() { } @Override public Map<String, FREFunction> getFunctions() { Map<String, FREFunction> mapFunc = new HashMap<String, FREFunction>(); mapFunc.put("getUser", new YJFGetUser()); mapFunc.put("charge", new YJFCharge()); mapFunc.put("destoryLogin", new YJFLogout()); mapFunc.put("openLogin", new YJFLogin()); mapFunc.put("init", new YJFInit()); return mapFunc; } }
5、編寫 ant 配置文件 build.xml,編譯導出 JAR 包
<?xml version="1.0" encoding="UTF-8" ?> <project name="4399paysdk" basedir="." default="exportJar"> <!-- 設置全局變量 --> <property name="src.dir" value="src" /> <property name="classes.dir" value="bin/classes" /> <property name="dist.dir" value="dist" /> <property name="jar.file" value="4399PaySDKANEJava.jar" /> <property name="classes.encode" value="UTF-8" /> <property name="libs.dir" value="libs" /> <path id="classpath"> <fileset dir="${libs.dir}"> <include name="**/*.jar" /> </fileset> <fileset dir="E:\softinstall\Java\jdk1.6.0_24\jre\lib"> <include name="**/*.jar" /> </fileset> <fileset dir="E:\soft\android\adt-bundle-windows-x86\sdk\platforms\android-8"> <include name="android.jar" /> </fileset> <fileset dir="E:\softinstall\ADOBE\Adobe Flash Builder 4.7\sdks\4.6.0\lib\android"> <include name="FlashRuntimeExtensions.jar" /> </fileset> </path> <target name="init"> <!-- Create the time stamp --> <tstamp /> </target> <!-- 編譯源文件 --> <target name="buildFiles" depends="init"> <echo message="start building ....." /> <delete dir="${classes.dir}" /> <mkdir dir="${classes.dir}" /> <javac deprecation="on" debug="on" encoding="${classes.encode}" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" source="1.6" target="1.6" includeAntRuntime="false" /> <copy todir="${classes.dir}"> <!-- copy config files --> <fileset dir="${src.dir}" includes="**/*.properties,**/*.xml,**/*.bsh,**/*.logic, **/*.hbm" /> </copy> </target> <!-- 導出jar文件 --> <target name="exportJar" depends="buildFiles"> <delete dir="${dist.dir}" /> <!-- Create the distribution directory --> <mkdir dir="${dist.dir}" /> <jar destfile="${dist.dir}/${jar.file}" basedir="${classes.dir}"> <zipfileset excludes="META-INF/*.SF" src="${libs.dir}/4399PaySdk.jar"/> </jar> <copy todir="${basedir}/../ane" file="${dist.dir}/${jar.file}" /> </target> </project>
這樣就完成了本地jar包的生成工作了。
2、創建flex庫項目,生成swc庫
準備工作:
1)創建項目
2)屬性設置
編碼部分:
這邊使用單例模式,創建actionscript代碼
package com.sj4399.pay.ane { import flash.events.EventDispatcher; import flash.events.IEventDispatcher; import flash.events.StatusEvent; import flash.external.ExtensionContext; public class YjPaymentApi extends EventDispatcher { public static const EXTENSION_ID:String = "com.sj4399.pay.ane.android"; private var _context:ExtensionContext; private static var _instance:YjPaymentApi; public static function getInstance():YjPaymentApi{ if(_instance == null){ _instance = new YjPaymentApi(); } return _instance as YjPaymentApi; } public function YjPaymentApi(target:IEventDispatcher=null) { _context = ExtensionContext.createExtensionContext(EXTENSION_ID,null); if(_context == null){ trace("YjPaymentApi(.as) constructor: _context is null,please call 'init()' first!"); } _context.addEventListener(StatusEvent.STATUS,onStatus); super(target); } /** * SDK初始化 */ public function init(){ _context.call("init",null); } /** * 登錄 */ public function openLogin(){ _context.call("openLogin",null); } /** * 注銷 */ public function destoryLogin(){ _context.call("destoryLogin",null); } /** * 充值 * amount 充值金額 * server 分服標識 * mark 拓展標記 */ public function charge(amount:int,server:int=0,mark:String=null){ _context.call("charge",amount,server,mark); } /** * 獲取用戶信息*/ public function getUser():String{ return String(_context.call("getUser")); } private function onStatus(e:StatusEvent):void{ //trace("received status event:"+e.toString()); var eventObject:Object = JSON.parse(e.code); var evt:PayCallbackEvent = new PayCallbackEvent(Constants.EVENT_TYPE_4399PAYSDK_CALLBACK, eventObject.callbackType, eventObject.code, eventObject.data); this.dispatchEvent(evt); } } }
2、編寫PayCallbackEvent
package com.sj4399.pay.ane { import flash.events.Event; /** * 支付SDK回調事件 */ public class PayCallbackEvent extends Event { private var _eventType: String; private var _callbackType: String; private var _code: int; private var _data: Object; public function PayCallbackEvent(eventType:String, callbackType: String, code: int, data: Object, bubbles:Boolean=false, cancelable:Boolean=false) { this._eventType = eventType; this._callbackType = callbackType; this._code = code; this._data = data; super(eventType, bubbles, cancelable); } /** * 獲取回調事件類型,Constants 中定義了回調事件類型常量(CALLBACKTYE_*),游戲應根據此回調事件類型對事件進行不同的處理。 * @return * */ public function get callbackType(): String { return _callbackType; } /** * 獲取回調事件狀態碼,表示SDK返回的執行結果和狀態,StatusCode 中定義了回調事件狀態碼常量。不同回調事件類型的事件有自己對應的狀態列表,游戲應根據此狀態碼進行不同的處理。 * @return * */ public function get code(): int { return _code; } /** * 獲取SDK返回的執行結果數據,不同回調事件類型的事件具有不同的數據結構,游戲應根據回調事件類型來獲取相應的數據。 * @return * */ public function get data(): Object { return _data; }} }
3、定義常量
package com.sj4399.pay.ane { public class Constants { public static const EVENT_TYPE_4399PAYSDK_CALLBACK = "4399_pay_sdk_callback"; public static const CB_LOGIN:String = "login"; public static const CB_LOGOUT:String = "logout"; public static const CB_CHARGE:String = "charge"; public static const STATUS_LOGIN_COMPLETE:int = -1;//登錄完成 public static const STATUS_LOGIN_CANCEL:int = -2; //取消登錄 public static const STATUS_LOGOUT_COMPLETE:int = -3; //取消登錄 public static const STATUS_CHARGE_COMPLETE:int = -4; //充值完成 public static const STATUS_CHARGE_CANCEL:int = -5; //取消充值 } }
編譯在bin目錄下可以看到swc庫文件。
3、生成ANE
拷貝生成的本地jar文件 與swc文件到要創建ANE的目錄下
這里我們可以看到有個extension.xml,這個就是用于as3代碼里面的的拓展標識,用于as3調用jar包中的函數,里面內容是
<extension xmlns="http://ns.adobe.com/air/extension/2.5"> <id>com.sj4399.pay.ane.android</id> <versionNumber>1</versionNumber> <platforms> <platform name="Android-ARM"> <applicationDeployment> <nativeLibrary>4399PaySDKANEJava.jar</nativeLibrary> <initializer>com.sj4399.pay.ane.YJPaymentApiExtension</initializer> <finalizer>com.sj4399.pay.ane.YJPaymentApiExtension</finalizer> </applicationDeployment> </platform> </platforms> </extension>
signature.p12是air生成的密鑰,相信air游戲開發者都清楚這個內容。
以解壓的方式打開SWC,解壓其中的library.swf到Android-ARM文件夾中。
將jar包和第三方所需要的res資源文件拷貝到Android-ARM中,如圖
這里都做好了,接下來就是生成ANE了,我們編寫一個批處理文件
@REM 打包 .ane SET SWC_FILE=4399PaySDK_ANE_AS.swc SET ANE_FILE=4399PaySDK.ane SET JAR_FILE=4399PaySDKANEJava.jar SET FLEX_ADT_CMD=java -jar "E:\softinstall\ADOBE\Adobe Flash Builder 4.7\sdks\4.6.0\lib\adt.jar" %FLEX_ADT_CMD% -package -tsa none -storetype pkcs12 -keystore signature.p12 -storepass 123456 -target ane %ANE_FILE% extension.xml -swc %SWC_FILE% -platform Android-ARM -C Android-ARM . pause
好了,這樣就可以生成我們的所需要的ANE了.至于如何調用相信大家都知道,這里就不多說了。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。