ANE 在 Android 上的应用

http://blog.csdn.net/linxcool/article/details/7770179

概述

Adobe Air是利用Adobe公司的Flash技术开发的媒体播放平台。而Native Extension就是让AIR可以调用各个平台上的本地代码(native code, 如ios上的object-c,android上的java,desktop上的c++,c#等),从而完成对AIR中Actionscript API的自定义扩展。即可以让开发者通过编写基于平台的本地代码扩展ActionScript。从而完成一些原有Actionscript无法完成的功能。

Native Extension结构及原理

一个NativeExtension项目主要有两个部分组成:As 端的库项目和底层代码的实现项目。
下图是Android 上整个NativeExtension项目的体系结构。

ANE 在 Android 上的应用

AS库项目部分

ExtensionContext是其核心类,负责与Java代码的交互。ExtensionContext需要调用createExtensionContext方法创建和初始化Java端的本地代码。而是用call方法可以调用具体的Java代码并获得返回结果。同时Extension还会接受从java代码抛出的事件。

本地java项目部分

关键类 FREContext
关键接口 FREExtension、FREFunction

FREExtension是java端自定义代码的入口,需要重写createContext方法从而获得本地代码的上下文,即自己扩展的FREContext子类。
FREFunction是本地方法的具体实现,实例化后以键值对的形式存入FREContext,从而在AS端的ExtensionContext中调用的call方法中传入对应键值调起本地方法。

开发流程

项目分成三部分:Android项目,Flex Library库项目和Flex Mobile项目

Android项目

1、在Eclipse中新建Android项目,不必勾选创建Activity

2、将项目的类型设为Library型
properties -> Android -> 勾选 Is Libirary

3、导入Ane android jar包(FlashRuntimeExtensions.jar)

4、添加java本地实现

public class SkyExtension implements FREExtension{  
    @Override  
    public FREContext createContext(String pType) {  
        return new SkyContext();  
    }  
    @Override  
    public void dispose() {}  
    @Override  
    public void initialize() {}  
}  
public class SkyExtension implements FREExtension{
	@Override
	public FREContext createContext(String pType) {
		return new SkyContext();
	}
	@Override
	public void dispose() {}
	@Override
	public void initialize() {}
}
public class SkyContext extends FREContext{  
  
    @Override  
    public void dispose() {}  
    @Override  
    public Map<String, FREFunction> getFunctions() {  
        HashMap<String, FREFunction> map = new HashMap<String, FREFunction>();  
        map.put("keyA", new TestToastFunction());  
        //可继续put其他function  
        return map;  
    }  
  
}  
public class SkyContext extends FREContext{

	@Override
	public void dispose() {}
	@Override
	public Map<String, FREFunction> getFunctions() {
		HashMap<String, FREFunction> map = new HashMap<String, FREFunction>();
		map.put("keyA", new TestToastFunction());
		//可继续put其他function
		return map;
	}

}
public class TestToastFunction implements FREFunction{  
    @Override  
    public FREObject call(FREContext context, FREObject[] params) {  
        Toast.makeText(context.getActivity(), "测试成功:android本地被调用", Toast.LENGTH_LONG).show();  
        FREObject result=null;  
        try {  
            result = FREObject.newObject("这是可返回的值");  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return result;  
    }  
  
}  
public class TestToastFunction implements FREFunction{
	@Override
	public FREObject call(FREContext context, FREObject[] params) {
		Toast.makeText(context.getActivity(), "测试成功:android本地被调用", Toast.LENGTH_LONG).show();
		FREObject result=null;
		try {
			result = FREObject.newObject("这是可返回的值");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

}

5、导出jar包(AneTestNative.jar)

Flex Library库项目

1、新建Flex Library项目,注意指定AIR3的SDK,并且勾选“包括Adobe AIR库”
2、在src下新建包,并添加as代码

public static void setResourctID(String rName,FREContext context) throws Exception{  
    Class<?> R = Class.forName(rName);  
    Class<?>[] clss = R.getDeclaredClasses();  
    for (int i = 0; i < clss.length; i++) {  
        Class<?> cls = clss[i];  
        Field[] flds = cls.getDeclaredFields();  
        for (int j = 0; j < flds.length; j++) {  
            Field fld = flds[j];  
            fld.setAccessible(true);  
            Object obj = cls.newInstance();  
            String name = cls.getSimpleName()+"."+fld.getName();  
            int id = context.getResourceId(name);  
            fld.set(obj, id);  
        }  
    }  
}  
public static void setResourctID(String rName,FREContext context) throws Exception{
	Class<?> R = Class.forName(rName);
	Class<?>[] clss = R.getDeclaredClasses();
	for (int i = 0; i < clss.length; i++) {
		Class<?> cls = clss[i];
		Field[] flds = cls.getDeclaredFields();
		for (int j = 0; j < flds.length; j++) {
			Field fld = flds[j];
			fld.setAccessible(true);
			Object obj = cls.newInstance();
			String name = cls.getSimpleName()+"."+fld.getName();
			int id = context.getResourceId(name);
			fld.set(obj, id);
		}
	}
}


其中rName为android生成R.java文件的全类名(如com.linxcool.air.R),打包时请打入。

3、assets资源、.so文件 问题

最简单的方式,生成的apk包解压,拷贝assets文件及so文件到APK包的对应目录下,重新打包签名即可。

4、FlashBuilder工程中引用ANE时报错(扩展XML文件无效或不存在)

不用理会。

5、打包的时候出现 Invalid swc file The extension NameSpace requires to SWF version to be 13 or lower

在AS库项目中右键属性 -> flex库编译器 ->附加库编译器参数 修改为-locale en_US -swf-version=13

其他一些ane打包so库的方法:

http://blog.csdn.net/rogiture/article/details/13986265

http://help.adobe.com/zh_CN/air/extensions/WSf268776665d7970d-2482335412ffea65006-8000.html

相关推荐