• AIR面向IOS设备的原生扩展


    来源:http://www.cnblogs.com/alex-tech/archive/2012/03/22/2411264.html

    ANE组成部分


    在IOS平台中,ANE的组成部分基本分为AS 3.0扩展类库和Obj-C原生扩展类库两个部分,这两个部分打包后生成AIR扩展文件(.ane),最后和.swf起打包成IOS原生应用IPA文件。

     未命名

    Action Script类库构建


    ANE的AS扩展部分是一个SWC,AIR 3.0 SDK里为flash.external.ExtensionContext类添加了新的方法,这里类名为NativeAlert.

    1) 开发环境, Adobe AIR 3.03.1 SDK, Flash Builder或Flash Develop.

    2) 建立Flex 库项目,编译的时候包括AIR库,链接方式设定为默认的外部链接.

    3) 主要类NativeAlert与NativeAlertEvent.

    4) 最终得到NativeAlert.swc

    NativeAlert中主要工作:

    • 定义扩展唯一ID;
    • 通过指定ID,初始化上下文环境,获取实例;
    • 根据ane中导出的方法名encodeBMP调用原生类中定义的方法decode,参数为ByteArray和int,int;
       1:  package com.wanghui.nativeextensions
       2:  {
       3:      import flash.external.ExtensionContext;
       4:      import flash.utils.ByteArray;
       5:      
       6:      public class ImageProcessor
       7:      {
       8:          private var context:ExtensionContext;
       9:          
      10:          public function ImageProcessor()
      11:          {
      12:              context = ExtensionContext.createExtensionContext('com.wanghui.nativeextensions.myextension', ''); //@Attention[1]
      13:          }
      14:          public function decode(data:ByteArray)
      15:          {
      16:               var byteArray:ByteArray = data;
      17:               var transparent:int     = byteArray.readUnsignedByte();
      18:               // 调用原生类的decode方法
      19:               var handler:int         = int(context.call("decode",byteArray,byteArray.position,transparent)); //@Attention[2]
      20:          }
      21:      }
      22:  }

    ExtensionContext通过静态方法createExtensionContext()来获得一个实例,参数com.wanghui.nativeextensions.myextension是这个扩展的ID,它非常重要,在扩展的配置文件里和应用程序描述文件中都需要用这个ID进行配对。

    调用原生类中定义的方法可以用方法call()来实现,由于是同步调用,所以函数可以有返回值。还可以给ExtensionContext类添加事件侦听,用来获取从原生类中派发回来的事件。

    Obj-C本地扩展


    1)开发环境XCode

    2) 建立Cocoa Touch Static Library;

    3) 选择build settings,选中 Preprocessor Macros,移除所有标记,诸如DEBUG=1 and ${inherited};

    4) 选择build settings,设定Enable linking with shared librariesYES;

    5) 引入AIR SDK中的头文件FlashRuntimeExtensions.h;

    6) 原生类中导出方法decode

    7) 最终得到decoder.a

    decode方法定义为返回FREObject方法,FREObject是接口类型,参数类型如下。这里要注意,与AS的接口包括函数返回值,都要定义成FREObject类型,比如代码中的handlerObject。

       1:  // ctx为上下文id,argc为参数个数,argv中为参数信息
       2:  FREObject decode(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[])
       3:  {
       4:      FREByteArray byteArray;
       5:      int position,transparent;
       6:      // 获取参数信息
       7:      FREAcquireByteArray(argv[0],&byteArray);
       8:      FREGetObjectAsUint32(argv[1],(uint32_t*)&position);
       9:      FREGetObjectAsUint32(argv[2],(uint32_t*)&transparent);
      10:      Handler *handler=malloc(sizeof(Handler));
      11:      
      12:      // Acquir之后进行Release
      13:      FREReleaseByteArray(argv[0]);
      14:      FREObject handlerObject;
      15:      // 申请返回数据空间
      16:      FRENewObjectFromUint32((uint32_t)handler,&handlerObject);
      17:      return handlerObject;      
      18:  }

    要将decode方法定义为接口方法,需在ContextInitializer进行导出,指定导出的方法数,方法名称:

       1:  void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx,
       2:          uint32_t* numFunctionsToTest, const FRENamedFunction** functionsToSet){
       3:      initTables();
       4:      //定义的接口的数量
       5:      *numFunctionsToTest = 1;
       6:      //定义一个FRENamedFunction类型的实例func,初始化函数的个数
       7:      FRENamedFunction* func = (FRENamedFunction*) malloc(sizeof(FRENamedFunction) * 1);
       8:      //定义一个接口,name是字符串"decode";,函数体是decode
       9:      func[0].name = (const uint8_t*) "decode";
      10:      func[0].functionData = NULL;
      11:      func[0].function = &decode;
      12:      *functionsToSet = func;
      13:  }

    ContextInitializer方法是在原生扩展类的初始化函数ExtInitializer中指定的:

       1:  void ExtInitializer(void** extDataToSet,FREContextInitializer* ctxInitializerToSet,FREContextFinalizer* ctxFinalizerToSet){
       2:      *extDataToSet = NULL;
       3:      *ctxInitializerToSet = &ContextInitializer;
       4:      *ctxFinalizerToSet = &ContextFinalizer;
       5:  }

    ExtInitializer是原生扩展的程序入口,它可以通过扩展配置文件extension.xml来定义:

       1:  <extension xmlns="http://ns.adobe.com/air/extension/2.5">
       2:      <id>com.wanghui.nativeextensions.myextension</id>          <!--@ Attention [3]扩展ID>
       3:      <versionNumber>0.0.1</versionNumber>
       4:      <platforms>
       5:          <platform name="iPhone-ARM">
       6:              <applicationDeployment>
       7:                  <nativeLibrary>decoder.a</nativeLibrary>       <!--@ Attention [4]本地扩展库名称>
       8:                  <initializer>ExtInitializer</initializer> 
       9:                  <finalizer>ExtFinalizer</finalizer>
      10:              </applicationDeployment>
      11:          </platform>

    打包ANE


    1) decoder.a

    2) NativeAlert.swc

    3) NativeAlert.swc解压得到的library.swf

    4) 扩展描述文件extension.xml

    5) 利用AIR提供的adt打包,得到decoder.ane

    adt -package  -target ane decoder.ane extension.xml -swc NativeAlert.swc -platform iPhone-ARM library.swf decoder.a

    打包IPA


    1) 写测试程序(flex手机项目),使用类库NativeAlert.swc,选择外部链接swc的方式,得到testmobile.swf;应用程序描述文件testmobile-app.xml,添加如下描述:

       1:  <extensions>
       2:  <!--@ Attention [5]扩展ID>
       3:  <extensionID> com.wanghui.nativeextensions.myextension </extensionID> 
       4:  </extensions>

    1) decoder.ane,存放在ext目录下

    2) 开发者设备授权文件 ceshi.mobileprovision

    3) 开发者签名证书文件developerkey.p12

    4) 打包ipa得到example.ipa

    /adt -package -target ipa-test-interpreter -provisioning-profile ceshi.mobileprovision -storetype pkcs12 -keystore developerkey.p12 -storepass 1234 example.ipa testmobile-app.xml testmobile.swf -extdir ext

    注:


    1) @ Attention[1] [3] [5]位置的扩展ID一定要一致;

    2) 模拟器中无法运行,调试可以选择输出调试信息的方式;

    3) 运行程序后如果白屏立刻退出,确定[Obj-C本地扩展部分的] 3)4)两项设置是正确的;

  • 相关阅读:
    浅谈MVP与ModelViewViewModel(MVVM)设计模式
    策略模式
    C#验证码
    如何招到烂程序员
    承载和使用WCF服务
    .NET Remoting 使用总结
    基于.Net Remoting的应用程序
    HTML5 是什么?
    关于HTTP及XMLHTTP状态代码一览
    Remoting多个信道(Chennel)的注册问题
  • 原文地址:https://www.cnblogs.com/sunminmin/p/3822480.html
Copyright © 2020-2023  润新知