[AIR接入Android 平台]第二步 编写 JAVA端接口 与 AS端接口项目

这和编写其他所有ANE类似。网上可以找到一堆的教程。但是我觉得都不够清晰。如果你已经对编写ANE有足够的把握 那这篇文章完全可以不看。

一点声明:我的水平有限 这里仅仅只能写出我认为可行的方案 和 代码

而且针对接入平台运营商的情况。这种ANE基本都具有四个功能:

初始化SDK  -> 登录 -> 付费 -> 退出

所以我决定针对接入android平台而写一个基本的ANE教程。我接入的所有平台的ANE 都是基于教程中给出的源码而做的改进。

ANE作为AIR调用本地代码的机制 他的组成分为两部分:

在开始之前 先限定一些共同的ID:

接口 ID:com.rect.ane

初始化SDK标识:rect_function_init

登录标识:rect_function_login

付费标识:rect_function_pay

退出SDK标识:rect_function_exit

1.JAVA端项目

新建库项目 如图

注意包名最好和我们在之前限定的接口 ID一致。

然后记得勾选为library

然后一直确定 生成项目  Rectane。在eclipse中右键

项目属性 – java构建路径 – 源代码 – Rectane/gen – 包括

选择[包括]点击编辑  在[包括模式]中 点击 添加 输入 nothing 按确定。完成后如图

接下来加入AIR SDK中的 FlashRuntimeExtensions.jar 文件到项目下的lib文件夹 然后导入到项目中 如图

接下来就是贴代码的时间了:

RectContext.java
[cc lang=”java”]
package com.rect.ane;

import java.util.HashMap;
import java.util.Map;

import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;

/**
* @author Rect
* @version Time:2013-5-8
*/
public class RectContext extends FREContext {
/**
* INIT sdk
*/
public static final String RECT_FUNCTION_INIT = “rect_function_init”;
/**
* 登录Key
*/
public static final String RECT_FUNCTION_LOGIN = “rect_function_login”;
/**
* 付费Key
*/
public static final String RECT_FUNCTION_PAY = “rect_function_pay”;
/**
* 退出Key
*/
public static final String RECT_FUNCTION_EXIT = “rect_function_exit”;
@Override
public void dispose() {
// TODO Auto-generated method stub

}

@Override
public Map getFunctions() {
// TODO Auto-generated method stub
Map map = new HashMap();
// //映射
map.put(RECT_FUNCTION_INIT, new RectInit());
map.put(RECT_FUNCTION_LOGIN, new RectLogin());
map.put(RECT_FUNCTION_PAY, new RectPay());
map.put(RECT_FUNCTION_EXIT, new RectExit());
return map;
}

}
[/cc]
RectExtension.java
[cc lang=”java”]
package com.rect.ane;

import com.adobe.fre.FREContext;
import com.adobe.fre.FREExtension;

/**
* @author Rect
* @version Time:2013-5-8
*/
public class RectExtension implements FREExtension {

@Override
public FREContext createContext(String arg0) {
// TODO Auto-generated method stub
return new RectContext();
}

@Override
public void dispose() {
// TODO Auto-generated method stub

}

@Override
public void initialize() {
// TODO Auto-generated method stub

}

}
[/cc]
更多的详细代码 请看附件中的 Rectane_java 项目
在源码中会有更详细的表述

2.AS 端项目
AS项目是作为和JAVA对应的。负责侦听返回 和调用JAVA函数
这里使用 FB 建立一个 手机库项目 然后在里面加两个类:
RectEvents.as
[cc lang=”java”]
package com.rect.ane
{
/**
*
* @author Rect 2013-5-6
*
*/
public class RectEvents
{
public function RectEvents()
{
}
/**************************平台通知************************************/
/**
*init
*/
public static const DEMO_SDK_STATUS:String = “DemoInit”;
/**
* 用户登录
*/
public static const DEMO_LOGIN_STATUS : String = “DemoLogin”;

/**
* 用户注销
*/
public static const DEMO_LOGOUT_STATUS : String = “DemoExit”;

/**
* 充值
*/
public static const DEMO_PAY_STATUS : String = “DemoPay”;
}
}
[/cc]
RectExtension.as
[cc lang=”java”]
package com.rect.ane
{
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.StatusEvent;
import flash.external.ExtensionContext;

/**
*
* @author Rect 2013-5-6
*
*/
public class RectExtension extends EventDispatcher
{
public static const RECT_FUNCTION_INIT:String = “rect_function_init”;//与java端中Map里的key一致
public static const RECT_FUNCTION_LOGIN:String = “rect_function_login”;//与java端中Map里的key一致
public static const RECT_FUNCTION_PAY:String = “rect_function_pay”;//与java端中Map里的key一致
public static const RECT_FUNCTION_EXIT:String = “rect_function_exit”;//与java端中Map里的key一致

public static const EXTENSION_ID:String = “com.rect.ane”;//与extension.xml中的id标签一致
private var extContext:ExtensionContext;

/**单例的实例*/
private static var _instance:RectExtension;
public function RectExtension(target:IEventDispatcher=null)
{
super(target);
if(extContext == null) {
extContext = ExtensionContext.createExtensionContext(EXTENSION_ID, “”);
extContext.addEventListener(StatusEvent.STATUS, statusHandler);
}

}

//第二个为参数,会传入java代码中的FREExtension的createContext方法
/**
* 获取实例
* @return DLExtension 单例
*/
public static function getInstance():RectExtension
{
if(_instance == null)
_instance = new RectExtension();
return _instance;
}

/**
* 转抛事件
* @param event 事件
*/
private function statusHandler(event:StatusEvent):void
{
dispatchEvent(event);
}

/**
*init发送函数
* @param key 暂时传什么都可以 留着可能要用
* @return
*
*/
public function FeiliuInit(key:int):String{
if(extContext ){
return extContext.call(RECT_FUNCTION_INIT,key) as String;
}
return “call login failed”;
}

/**
*登录发送函数
* @param key 暂时传什么都可以 留着可能要用
* @return
*
*/
public function FeiliuLogIn(key:int):String{
if(extContext ){
return extContext.call(RECT_FUNCTION_LOGIN,key) as String;
}
return “call login failed”;
}
/**
*付费发送函数
* @param key 暂时传什么都可以 留着以后可能要用
* @return
*
*/
public function FeiliuPay(data:Vector.,len:int = 5):String{
if(extContext && data.length == len){
return extContext.call(RECT_FUNCTION_PAY,data)as String;
}
return “call pay failed”;
}

/**
*退出SDK时候调用 这个函数只在退出游戏的时候调用
* @param key
* @return
*
*/
public function ExitSDKHandle(key:int):String{
if(extContext){
return extContext.call(RECT_FUNCTION_EXIT,key) as String;
}
return “call exit failed”;
}
}
}
[/cc]
仔细看这两个类就可以发现 在前面说的 接口ID 和 各个函数调用的 ID 都必须保持一致
3.extension.xml 文件

XML文件中要注意的是 必须保存一致

4.打包ANE  在 1 2 3进行完了之后 我们去取到一下文件

A>.JAVA项目下的 :Rect\Rectane_java\bin\rectane.jar

B>AS库项目下的:Rect\RectANE_as\bin\RectANE.swc

C>XML文件:extension.xml

D>新建一个KEY文件:rect.p12(可用FB新建)

F>解压RectANE 获得:catalog.xml library.swf

总共 6个文件

然后新建文件夹  Rect_make_ane 在 Rect_make_ane文件夹下 新建 android-ARM文件夹

然后上述6个文件分别放在下面:

rectane.jar – > Rect_make_ane/android-ARM/rectane.jar

catalog.xml – > Rect_make_ane/android-ARM/catalog.xml

library.swf – > Rect_make_ane/android-ARM/library.swf

RectANE.swc -> Rect_make_ane/RectANE.swc

extension.xml – > Rect_make_ane/extension.xml

rect.p12 -> Rect_make_ane/rect.p12

具体的看源码中的文件夹

在打包ANE之前 接入平台的时候 还有一步 就是 合成 把 平台jar和 rectane.jar 一起合成一个jar 后续文章会详细介绍

然后使用命令行打包 我在这里写成了一个批处理:(注意路径自己配)

“[你的AIR SDK路径]\bin\adt” -package -storetype PKCS12 -keystore rect.p12 -storepass 1234 -target ane com.rect.ane extension.xml -swc *.swc -platform Android-ARM -C Android-ARM .

保存为 ane_pacler.bat 在 Rect_make_ane文件夹下 然后运行这里bat 就可以生成 ane了

至此  ane 成功编写出来。

注意:真正接入平台 的ANE  还需要 在JAVA项目中导入平台jar 然后在各个函数中编写各种操作。在把平台jar 和 rectane.jar一起打包成一个jar  再打包ANE

我在这里把 平台jar 合成最终的 jar 略去 在后面的文章中会具体详细的说明过程。

项目下载

《[AIR接入Android 平台]第二步 编写 JAVA端接口 与 AS端接口项目》有11个想法

  1. public static FREContext AS3Context = null;
    public static Activity aneActivity = null;

    // createContext() creates and returns an FREContext object.
    public FREContext createContext(String extId) {
    Log.i(“GameExtension”, “createContext”);
    if (null == AS3Context) {
    AS3Context = new GameExtensionContext();
    }
    return AS3Context;
    }

    个人觉得,这样写 ,更干(净),更爽,更贴心。。。无论在任何时候 ,你都可以GameExtension.AS3Context.dispatchStatusEventAsync(“报告AS3”, “我有罪”);

  2. java代码端调用SDK中的函数,有些需要传递context的,把FREContext传递过去类型不匹配要怎么解决。。。

    public FREObject call(FREContext arg0, FREObject[] arg1) {

    _context = arg0;

    KSGameSdkManager.getInstance().init(_context, _iksGameSDKCallback);

    callBack();

    return null;
    }

  3. 我懂了,传getActivity返回值就可以了。菜鸟丢人丢到Rect哥这里来了

  4. RECT,我不知道是不是错过看什么了,那个extension.xml是自己添加的,我这个搞的不是很明白。

    com.rect.ane
    1

    lonic_yuane.jar
    com.lonic.ane.LonicExtension
    com.lonic.ane.LonicExtension

    我的理解是从将第三方jar文件解析打包成一个jar库,上面的文字是在库中找到XXExtension初始化。as库项目是没有XML文件生成的,我用的是air15,对于extension.xml,这个文件希望Rect抽空给我说一下。

  5. 我编译的错误的nativelibrary contains an invalid value,但我在文件夹中已经包含的那个.jar文件

  6. Rect,我做出来的ANE使用的时候Scout检测的消息是
    Catch Error:TypeError: Error #1009
    at com.ane.lonic::LonicExtension()
    at com.ane.lonic::LonicExtension$/getInstance()
    at sdk.platForm::SDKjinshan/InitAne()
    at sjsg.ui.system::LoginPlatform/Init()

    我用小项目试了一下,
    if(extContext == null)
    {
    extContext = ExtensionContext.createExtensionContext(EXTENSION_ID,””);
    extContext.addEventListener(StatusEvent.STATUS,statusHandler);
    }
    extContext接受到的返回是一个空值
    我的ID设置:
    代码中:public static const EXTENSION_ID:String = “com.ane.lonic.ane”; //与xml中的id标签一致

    extension.xml: com.ane.lonic.ane

    打包出来ane的名称:com.ane.lonic.ane
    在这里还想请问一下AS端代码和java端代码取名字的规范,上面的借个IP是不是要跟包的名称乃至项目的名臣一样

    1. @lonic, 项目包名不需要一样,这个ID只需要在 ANE的AS注册传入,和extension.xml中一样便可.你随便下载一个我的ANE源码 对比下就知道了

raymond进行回复 取消回复

邮箱地址不会被公开。 必填项已用*标注