1.ANE简介

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扩展包,有人就骂,AIR你不是号称跨平台,怎么又还要写一大堆ANE?是的,这样被人骂对于Adobe AIR来说也很无奈,毕竟AIR不是万能的,什么功能都可以写进去,否则AIR就会变得越来越庞大,越来越臃肿,这样大家自然不会去安装AIR了。当然你尽可以大骂ANE,但是如果你的实际项目中还是需要开发ANE,那就得花时间好好研究它吧。

因为存在不同的平台,这样就增加了我们开发ANE的难度。在Android手机上,我们需要用Android开发ANE;在iPhone手机上,我们需要用object-c来开发ANE;在Windows上,我们则需要用C++来开发ANE,这对于大部分只做AS代码的程序员而言,确实有点痛苦。不过不要紧,如果你的程序水平还可以,大可不必畏惧这些东西,毕竟程序是相通的,除了语法不同外,无非就是条件和循环,OOP都是差不多的,更重要的是有google和baidu,足矣。

你可以从Adobe官网http://www.adobe.com/devnet/air/native-extensions-for-air.html 下载一些ANE,然后将其后缀名改为.zip,解压后你可以看到这样一些东西在里面,

图1 ANE文件的解压内容

上图是一个消息推送的ANE文件的解压结果,其中省略了一些其他的文件和文件夹。由图可见,ANE运行不同的平台需要各自产生独立的本地文件,这里有Android和iPhone两个平台的本地文件,分别是jar包和a文件(静态链接库文件)。同时与本地文件并存的是library.swf文件,这是从一个swc文件中解压出来的。另外还有一个extension.xml文件,这是一个对扩展进行描述的Manifest文件,后面详述。

2. ANE的开发过程

ANE的开发分两步走,第一步需要生成一个swc文件,供AS程序调用;第二步需要生成本地程序,AIR会让系统执行它。

为方便起见,请参考http://www.milkmangames.com/blog/2011/09/25/developing-android-extensions-for-air-3-a-beginners-guide/ 此文中的操作和代码,我这里会省略其中的琐碎部分,突出重点。

2.1 生成swc文件

生成的swc文件主要用于两个地方,一是在将来开发时将其放在库里面进行引用;二是需要从这个swc中抽取library.swf文件,用于打包生成ane。

生成这个swc非常简单,代码量不多,主要使用flash.external.ExtensionContext类的call()方法,调用本地程序中的方法。这个ExtensionContext类非常类似我们经常调用javascript的ExternalInterface类。call()方法主要有两个参数,一个是本地程序的方法,另一个是传递给该方法的参数表。比如ExtensionContext.call("showMessage", "Nice to meet you!")表示调用本地程序中的showMessage()方法,同时把一个字符串当做传输传递进去。这个方法showMessage()需要在本地程序中具体实现,如果实在Android中会写成一个Alert.show(),或者其他的形式。

写好这个swc之后,我们就可以在AS程序中引用它里面的方法,而具体的实现则最终由本地程序中的方法来实现。

  1. package com.aneexample.extension
  2. {
  3. import flash.external.ExtensionContext;
  4. import flash.events.EventDispatcher;
  5. /** AndroidDialog */
  6. public class AndroidDialog extends EventDispatcher
  7. {
  8. //
  9. // Static Variables
  10. //
  11. /** Extension Context */
  12. private static var extContext:ExtensionContext=null;
  13. //
  14. // Public Methods
  15. //
  16. /**
  17. * Display a simple Android Dialog box.
  18. * @param   msg the message you wish to display.
  19. */
  20. public static function showDialogMessage(msg:String):void
  21. {
  22. initContext();
  23. extContext.call("ffiShowDialogMessage",msg);
  24. }
  25. //
  26. // Implementation
  27. //
  28. /** Init Context */
  29. private static function initContext():void
  30. {
  31. if(!extContext)
  32. {
  33. extContext=ExtensionContext.createExtensionContext("com.aneexample.AndroidDialog","");
  34. extContext.call("ffiInit");
  35. }
  36. }
  37. }
  38. }

Note:在编译生成swc的时候,需要加入编译参数 -swf-version 13 ,或更高的值,具体参考http://help.adobe.com/en_US/air/extensions/index.html

2.2 生成本地程序jar包

这里讨论的是Android本地程序,因此需要生成jar吧,iPhone则需要生成a文件。

在生成android的本地程序时,首先需要导入AIR SDK中的FlashRuntimeExtensions.jar,此文件在AIR SDK的路径下,比如我机器上是,

D:\Program Files\Adobe Flash Builder 4.6\sdks\4.6.0\lib\android\FlashRuntimeExtensions.jar

对应于前面提到的flash.external.ExtensionContext,在jar中也有一个com.adobe.fre.FREContext,这个FREContext一方面寻找Android应用中的Activity,另一方面寻找来自ExtensionContext请求的方法,因为在FREContext里面有一个Map<String, FREFunction> getFunctions()的函数,完成了外部请求方法名与实际执行方法之间的映射,因此FREContext可以在外部请求时,迅速找到并调用真正执行的方法。

实际中真正执行的方法必须要实现FlashRuntimeExtensions.jar中的接口com.adobe.fre.FREFunction,在具体的代码实现中,通常利用FREContext获取到Activity,然后将具体方法注入到Activity中。

虽然FREContext是承载任务的核心类,但它还是要包在com.adobe.fre.FREExtension里面,利用FREExtension.createContext()进行初始化,从而方便AIR获取FREContext对象。总之,记住FREContext的核心地位。

FREContext的实现:

  1. public class AndroidDialogExtensionContext extends FREContext {
  2. public android.app.Activity activity;
  3. @Override
  4. public void dispose() {
  5. // TODO Auto-generated method stub
  6. activity=null;
  7. }
  8. @Override
  9. public Map<String, FREFunction> getFunctions()
  10. {
  11. Map<String,FREFunction> functionMap=new java.util.HashMap<String,FREFunction>();
  12. functionMap.put("ffiShowDialogMessage",new AndroidDialogShowDialogMessageFunction());
  13. functionMap.put("ffiInit",new AndroidDialogInitFunction());
  14. return functionMap;
  15. }
  16. }

FREFunction的实现:

  1. public class AndroidDialogShowDialogMessageFunction implements FREFunction {
  2. @Override
  3. public FREObject call(FREContext context, FREObject[] args)
  4. {
  5. AndroidDialogExtensionContext adec=(AndroidDialogExtensionContext)context;
  6. android.app.AlertDialog.Builder builder=new android.app.AlertDialog.Builder(adec.activity);
  7. try
  8. {
  9. String message=args[0].getAsString();
  10. builder.setMessage(message).setNeutralButton("OK",null).show();
  11. }
  12. catch(Exception e)
  13. {
  14. android.util.Log.e("AIR_AndroidDialog",e.getMessage());
  15. }
  16. return null;
  17. }
  18. }

FREContext在FREExtension中的初始化:

  1. public class AndroidDialogExtension implements FREExtension {
  2. @Override
  3. public FREContext createContext(String arg0) {
  4. return new AndroidDialogExtensionContext();
  5. }
  6. @Override
  7. public void dispose() {
  8. // TODO Auto-generated method stub
  9. }
  10. @Override
  11. public void initialize() {
  12. // TODO Auto-generated method stub
  13. }
  14. }

最后将本地程序导出为jar包。

2.3 打包ane

有了swc和jar之后,还需要准备一个Manifest文件,即前面提到的extension.xml文件,此文件描述了各平台的本地程序以及入口/出口位置,供AIR阅读使用,具体如下,

  1. <extension xmlns="http://ns.adobe.com/air/extension/2.5">
  2. <id>com.aneexample.AndroidDialog</id>
  3. <versionNumber>1</versionNumber>
  4. <platforms>
  5. <platform name="Android-ARM">
  6. <applicationDeployment>
  7. <nativeLibrary>AndroidDialogAPI.jar</nativeLibrary>
  8. <initializer>com.aneexample.androiddialog.AndroidDialogExtension</initializer>
  9. <finalizer>com.aneexample.androiddialog.AndroidDialogExtension</finalizer>
  10. </applicationDeployment>
  11. </platform>
  12. </platforms>
  13. </extension>

另外将swc解压,从中抽取library.swf文件,现在我们手中的用于打包的文件清单包括:AndroidDialogAPI.swc,AndroidDialogAPI.jar,extension.xml和library.swf,把这四个文件放到某个文件夹中,参考如下,

具体打包命令是AIR SDK中的adt,我机器上是在这个位置,

D:\Program Files\Adobe Flash Builder 4.6\sdks\4.6.0\bin\adt

可以把这个bin目录放到系统的环境变量Path中,这样我们就可以在cmd中直接调用adt。

打包命令有点长,具体可以参考AIR官方文档http://help.adobe.com/en_US/air/extensions/index.html

adt -package -target ane com.aneexample.AndroidDialog.ane .\extension.xml -swc .\AndroidDialogAPI.swc -platform Android-ARM -C .\Android-ARM .

Note:最后的一个点不要漏掉了。

这样我们就得到一个ane文件。

2.4 ane的测试和使用

ane的测试和使用很简单,只要把ane连同对应的swc文件一起放在待开发的AS项目的libs目录下,添加对这两个文件的引用,然后就可以调用了。具体可以参考

flash Ane的更多相关文章

  1. 【Flash ANE iOS】关于Flash ANE在iOS上面遇到的一些问题

    1.下载Flash Builder: https://www.adobe.com/support/downloads/detail.jsp?ftpID=5516 2.如何生成p12文件: http:/ ...

  2. Flash Air 打包安卓 ane

    工具: 1.flash builder 2.adt打包工具 3.数字证书 一. 创建 jar 文件 1. 打开flash builder, 新建一个java 项目. 2.点击项目属性,选择Java构建 ...

  3. Flash Android ANE打包之基本流程

    搭建环境这里就不详细说明了 一.Android本地库编写 1.从Flash Air SDK中提取需要的jar包 Android下需要的jar包在Flash Air SDK/lib/android目录下 ...

  4. flash builder4.7 for Mac升级AIRSDK详解

    使用flash builder 打包ANE时或者打包ipa时候常常会遇到AIRSDK版本低的问题,然而flash builder4.7默认使用的AIRSDK是3.4而flash builder4.7 ...

  5. ANE 从入门到精通 --- 简单的Whatever

    Flash还是很好的,不过国内没人用. Whatever了. 以下是ANE制作中的一点笔记 分享下 也留作备份 Step1 编写As3 Library package com.eran { impor ...

  6. 如何编写android ANE

    1.编写AndroidAne.jar: a.编写SkyContext.java: import java.util.HashMap;import java.util.Map;import com.ad ...

  7. 编写windows版ANE

    1.编写WinANE.dll: #include <windows.h> #include <stdlib.h> #include <FlashRuntimeExtens ...

  8. 打包ane之后在FB上生成ipa的阶段错误

    1. 初次打包 碰到这个错误得 就是你mac 上jre版本的问题 此时用 FB 必须是跑在jre1.6版本上的 我得是1.8 上图 版本可以自己查下 已经截图了 而且 你如果想要下载 1.6版本的 就 ...

  9. ANE在ios上的使用流程和问题解决

    编写ANE流程: 1. 在xcode里编写.a原生类库 2. 更改配置文件extension.xml, 定义了原生程序的扩展接口 3. 编写AS替身类,生成扩展类包.swc,解压再得到library. ...

随机推荐

  1. CodeForces 702D Road to Post Office

    答案的来源不外乎于3种情况: 纯粹走路,用时记为${t_1}$:纯粹乘车,用时记为${t_2}$:乘车一定距离,然后走路,用时记为${t_3}$. 但是${t_1}$显然不可能成为最优解. 前两个时间 ...

  2. 2、为Eclipse绑定Tomcat

    1.window→preferences打开属性窗口 2.点击add 3.点击Tomcat6.0 点击next 4.选择tomcat的解压目录和jdk,并点击finish 5.点击ok 6.打开ser ...

  3. 一个简单的Servlet工具

    以前老师在项目中用过一个Sevlet的工具,就是在请求Servlet的时候带一个参数,该参数决定要执行Servlet中的方法, public class ServletUtils extends Ht ...

  4. 7 个 jQuery 最佳实践

    前言 随着富网络应用(rich web applications)数量的增长,以及用户对快速交互响应的高期望,开发者开始使用JavaScript库来快速高效的完成一些重复性的工作.这其中最流行的Jav ...

  5. Storm常见问题处理

    错误1:发布topologies到远程集群时,出现Nimbus host is not set异常.异常内容如下所示: [root@xop-dev-a bin]# ./storm jar /home/ ...

  6. spring容器启动的加载过程(三)

    第十步: public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { /** * Load bean def ...

  7. Python 的方法重载

    为防止两个模块互相导入的问题,Python默认所有的模块都只导入一次,如果需要重新导入模块,Python2 7可以直接用reload(),Python3可以用下 为防止两个模块互相导入的问题,Pyth ...

  8. RFC3489 STUN之客户端所处环境探测流程与部分属性含义说明

    1 STUN客户端所处环境探测流程 1.1 流程图 1.2 流程图中Binding请求类型说明 类型1:Binding请求消息中不设置CHANGE-REQUEST,或若设置其相应更改IP与端口标志位都 ...

  9. Class.forName和ClassLoader.loadClass的比较

    文章出处:http://blog.csdn.net/wikijava/article/details/5576043 Class的装载分了三个阶段,loading,linking和initializi ...

  10. 在自学php的路上不知道怎么走!!

    在自学php的路上不知道怎么走!! 真希望有人给我指点一二!!!