Building a Native Extension | Part 5 – Putting It All Together

This is the last step of the native extension build process. Did you miss something or are you late to the party? Jump back to step 1.

Now that all of the supporting projects have been built and compiled, it’s time to put it all together.  For native extensions, that means building a .ane file.

Building the ANE

1) Put all of the files into a folder together.  The structure should look like:

[sourcecode class=”text”]
build directory
-extension.xml
-SWC for main ActionScript library

android
-androidLib.jar
-library.swf (main ActionScript library)
ios
-iOSLib.a
-library.swf (main ActionScript library)
-platformoptions.xml (if required)
default
-library.swf (default library)
[/sourcecode]

2) Run the following command:

adt –package –storetype pkcs12 –keystore cert.p12 –storepass XXXX –target ane Name.ane extension.xml –swc Name.swc –platform iPhone-ARM –C iOS . –platformoptions ios/platformoptions.xml –platform Android-ARM –C android . –platform default –C default .

Exclude any platforms that you aren’t supporting.

The –C directory . indicates that all of the files in directory should be included in the ANE.  The command –C directory library.swf would make only the file directory/library.swf be included in the ANE.

Signing the ANE is optional, but Flash Builder will have a warning when using unsigned native extensions.  You can use any p12 to sign a native extension, including a p12 built from Flash Builder during the release build process, so it’s easy to sign the ANE.

3) Include the ANE in the application.

Go to the properties of your project.  Navigate to “Flex Build Path” and go to the “Native Extensions” tab.  Click “Add ANE…” and find the ANE you built.

At some point, either during this step or one of the following steps, Flash Builder should indicate that the package of the ANE must be included in the app descriptor file and that Flash Builder will automatically include it.  Say yes to this prompt.

Now that the ANE has been added, you must toggle it on for each platform you are supporting.  Expand the “Flex Build Packaging” item.

If supporting iOS, click on the “Apple iOS” item.  Go to the “Native Extensions” tab.  Be sure that the checkbox in the “Package” column next to your ANE is checked.  Also be sure to reference the iOS SDK (as mentioned previously) in the “Apple iOS SDK” input.  Click “Apply”.

If supporting Android, click on the “Google Android” item.  Go to the “Native Extensions” tab.  Be sure that the checkbox in the “Package” column next to your ANE is checked.  Click “Apply”.

Now click OK and clean your project.  You’re ready to implement the native extension now!

Note: If you make any changes that require you to rebuild the ANE, I suggest removing the ANE from the “Flex Build Path -> Native Extensions” tab and redo the steps in item #3 (this one!) to re-add the ANE.  I’ve has some caching issues where an old version of the ANE is used if I didn’t totally remove it and start the add process over from scratch.

Note: If you make changes to any of the libraries, be sure to update the files in the build directory!  It’s especially easy to overlooking extracting the library.swf file from the main ActionScript library’s swc file.  Also be sure to place this library.swf file in both the iOS and Android directories.

Note: It’s very possible to automate this process via ANT.  I don’t cover it here, but many other examples use ANT to perform the entire packaging process.  You can even extract the library.swf from the swc files using ANT.

Wrap-up

Creating a native extension has a lot of steps and it’s easy to overlook some of the finer details that are required to get the ANE working.  There are a lot of great examples out there so check them out and get an even better understanding of the power native extensions give you.

16 Comments

    Thank you for this step-by-step tutorial.
    I have a question: suppose the native side of your extension (in C) allocates some memory, to be passed to the AS side as a ByteArray, which side should be responsible for releasing the memory?

    • by Keith
    • 10:02 am, May 9, 2012
    • Reply

      That’s a good question, and to be honest I don’t know a definitive answer. I believe that Adobe recommends using autorelease in Objective-C. Based on that, and various experiments I’ve done, I’m inclined to say that the native code is responsible for everything except the FREContext and related classes; the runtime will manage those.

      • by Nathan Weber
      • 10:32 am, May 9, 2012
      • Reply

    Thanks Nathan,
    I got an .ane file. Here is my steps to use it on flash builder 4.7.
    1- Add .ane file from Properties/Flex Build Path/Native Extensions
    2- Checked in Build packaging/Native Extensions my .ane file
    3- I saw ExtensionID in application descriptor file
    4- also added .swc file as external
    When I try to use my app in another platform(Premiere Pro editor software) get error “couldn’t found class” that I created in lib project.
    Do you suggest me anything ? Do I have to write any more dir for .ane file? Where is my wrong while using .ane file?

    • by nthere
    • 2:40 am, December 28, 2012
    • Reply

      I have never used an ANE in Premiere Pro. To my knowledge, you can only use ANE files with Flash Builder and Flash Professional. After a quick google search it looks like other people are having similar problems with Premiere Pro. The best course of action would be to try to get Adobe’s attention on a Premiere Pro forum.

      • by Nathan Weber
      • 7:32 am, January 15, 2013
      • Reply

        Thanks Nathan,
        I solved my problem by using native process instead of native extension.
        Also I know that Adobe forums never helped me.

        • by nthere
        • 7:23 am, February 8, 2013
        • Reply

    Hi,

    Thank you for this tutorial.
    I have a very strange problem. I’ve create an ANE, but when I use it, it change the size of the objects.

    I’ve created a post here:
    http://stackoverflow.com/questions/15009287/flex-object-size-are-different-when-i-add-an-ane

    Do you know which can be the problem?

    I’ve tried with your ANE and I have the same problem. It could be a problem about how I use the ANE or how I compile it? I’m totally lost…

    Thanks

    • by Almudena
    • 3:53 am, February 22, 2013
    • Reply

      Is this running on an iPad 3? My guess is that you are accidentally unlocking the retina resolution when you use the native extension.

      The default iOS SDK that Flash Builder / packager uses is an older version that didn’t support the retina resolution of the iPad 3. So when you package an application without a native extension you get the iPad 2 resolution and iOS scales everything. When you use a native extension and you specify a newer iOS SDK it will automatically use the native resolution of the device.

      Try tracing out stage.stageWidth and stage.stageHeight with and without the extension included.
      Also, check in the Project Properties -> Flex Build Packaging -> Apple iOS -> Native Extensions -> Apple iOS SDK box. If that is populated then you are most likely have the problem I described.

      • by Nathan Weber
      • 7:29 am, February 22, 2013
      • Reply

    Hi,

    In step 1 you wrote ” The second is the ability to notify AIR whenever the user changes the system volume, either by using the hardware volume buttons or by using a different application.”

    Do I have to add a listener ? How do my app gets notified that the user has changed the volume ?

    An example of how to acheave this would be great !

    Thanks a lot.
    Regards

    • by lagommette
    • 4:16 pm, July 17, 2013
    • Reply

        Hi,
        Thanks a lot for your reply, it did help. But now I’m stucked with this message
        “Provided parameter LoaderContext.SecurityDomain is from a disallowed domain.at flash.external::ExtensionContext$/_createExtensionContext()”

        I am building an app for an Android tablet. I guess the error comes from the ID of the ANE beeing different from the ID of my app. Maybe if I could rename the ID by recompiling your project. I don’t know how to do that :(

        Regards

        • by lagommette
        • 2:31 pm, July 18, 2013
        • Reply

          I have not seen that error before. You should not have to recompile the volume ANE. I have used the ANE in a wide variety of projects, so the id not matching is not the issue. Are you using the ANE in the same way as the VolumeTest project?

          • by Nathan Weber
          • 2:35 pm, July 18, 2013
          • Reply

            I’am using Flash Professional CS6 with Adobe AIR 3.4.

            • by lagommette
            • 3:04 pm, July 18, 2013

    I started my program with these lines of code:
    extContext = ExtensionContext.createExtensionContext(“net.digitalprimates.volume”, “” );
    if ( !extContext ) {
    throw new Error( “Volume native extension is not supported on this platform.” );
    }

    It is the createExtensionContext methode that throws my error. I have commented these lines of code and now it working. The event for volume changed is thrown slowly but it si thrown :)

    • by lagommette
    • 3:11 pm, July 18, 2013
    • Reply

      In fact the event is thrown when the native slider of volume fades away. This explains why it is slow. I thought it would throw an event each time the volume key is pressed. Do you know if it is possible ?

      • by lagommette
      • 3:16 pm, July 18, 2013
      • Reply

        Sorry for the delay! It is not possible to get the events as the slider changes. Android only sends out an event when the slider fades away.

        • by Nathan Weber
        • 2:01 pm, August 2, 2013
        • Reply

    Hi i integrated this ane in a test project , the ane is working but not properly , the volume still the same , the event is dispatching but with a wrong value , and always the same …..

    • by chakas3
    • 1:29 am, September 4, 2014
    • Reply

Leave a Reply to Almudena Cancel reply