Buy any Easy Native Extensions 2nd Edition package and get our $99 iOS + Android ANE Template completely free before the end of June 2015.
- step-by-step guide to making your iOS extension in under an hour
- library for data conversion between ActionScript and native code
- tutorials
- infographics
- code included
The other week we had an overview of how an AIR Native Extension (ANE) fits in your app, after which we saw what goes into an ANE. We even inspected the elements of an ANE for:
Today we are zooming in to see what you need to set in the ANE, so that an app can find it.
1. You need an Extension ID
The Extension ID is a string that identifies your extension. The app will need to know about it at compile time.
It is defined in the extension descriptor file, your_extension_name-extension.xml:
<id>com.diadraw.extensions.camera.NativeCameraExtension</id>
This will be the string by which an app will know your extension from another one, so it better be unique. Adobe suggests using a reverse DNS for naming your extension, in order to avoid conflicts. For example, instead of just naming it NativeCameraExtension, I prepended the example above with “com.diadraw…”
What happens if two extensions have the same ID?
If you manually add the same <id> tag to your app descriptor file, the ADT packager will spit out this error message:
1 |
error 109: Duplicate extensionID element: ... |
Funnily enough, there is something else that really has to be unique for your extension to be found and loaded: the extension initializer and finalizer.
2. You need Extension Initializer and Finalizer
When your extension is first loaded, AIR looks for a specific function to call, in which the extension initializes itself: sets any global data and lets AIR know what functions to call when it needs to create an extension context.
When the extension is unloaded, AIR looks for another function to call, which ‘finalizes’ it, i.e. gives the native code a chance code to tidy things up: free any global data it may have previously set, release resources it may be hogging and so on.
Both of these functions are implemented in the native part of your extension, in C or in Java, and need to have specific signatures. If you wan to look ahead, click on the links to see what the functions look like in C and in Java.
Unlike the signatures, the names of your function implementations can be anything you like. To let AIR know what they are called, you put the names of your Extension Initializer and Finalizer in your extension descriptor file like this:
<initializer>CameraExtensionInitializer</initializer>
<finalizer>CameraExtensionFinalizer</finalizer>
What happens if two extensions have the same Extension Initializer and Finalizer names?
Nothing at compile time. No smoke from the back of your monitor, not even a compiler warning… But don’t be fooled, trouble is lurking and waiting to make an appearance at run time. Even worse, it sneaks up on you in the dark, so you won’t know what hit you at first.
If you happen to be using two ANEs, both of which have an Extension Initializer function with the same name, AIR will call the one in the ANE that happens to be loaded first: the extension you instantiate first in your ActionScript code. Let’s call it ANE “A”. AIR will shake hands with it, exchange information and, when the extension context gets initialized, it will tell AIR what the ANE “A” API is. The minute you try to access the second extension, ANE “B”, AIR will assume that the Extension Initializer for that has already been called and that it has all the information needed about ANE “B”. When it tries to make a call into the ANE “B” API, AIR will discover that the API function in question does not exist and will throw an exception. Not one that Flash Builder can show you, but one that you can see in Xcode for iOS, for example.
Morals of the story:
- Give unique names to your Extension Initializer and Finalizer.
- Make sure you set up your ANE for debugging, because sh** happens. More on that in a future post.
3. Put these in the extension descriptor file
These two pieces of information, your extension ID and the names of the extension Initializer and Finalizer go in an XML file, which serves as descriptor for your extension.
Below is a diagram of an ANE for iOS for illustration: your-extension.xml is the extension descriptor.
What else?
Tomorrow we are talking about the extension descriptor file.
Then we will look at what you need to set in an app when you include an ANE.
Over to you
Do you have any horror stories about problems that managed to escape you at compile time, but haunted you at run time? Share your story in the comments below.
Devanshu Kaushik
Hi,
Can you guys help me understand exactly how are third party libraries, that run without a sweat on the native Android code in eclipse, included inside an ANE? I have tried myriad export options from eclipse and yet end up with the ‘NoClassDefFoundError’ in the final .apk execution when trying to refer to anything in the said third party library. It will be great if you can explain that process step by step using ADT.
Thanks!
Hristo
Hi Devanshu,
You have stumbled into a well known problem in packing ANEs for Android.
For some reason if there is a third-party .jar file included in the libraryр it gets omitted from the ANE package.
This is quicksand territory and solutions vary among different projects and cases.
Here are some links outlining solution strategies, which may apply to your case:
http://stackoverflow.com/questions/7732742/air-3-native-extensions-for-android-can-i-how-to-include-3rd-party-libraries
http://stackoverflow.com/questions/9085189/how-to-add-third-party-jar-files-into-my-android-application-jar-file
http://techiepulkit.blogspot.bg/2013/01/air-android-native-extensions-part-4.html
Hope that helps.
Cheers,
Hristo