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:
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:
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.
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:
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.
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.