In my last post I described how we use JNI and the Java AudioTrack class to output audio from native code on Android versions prior to 2.3 (that is, before the release of OpenSL ES). But actually, that’s only half the story.
OpenSL ES code is in the libOpenSLES.so shared library. If you link to this library, though, then your executable will try to load it when it starts up, and if it’s running in a version of Android before 2.3, then that library will not exist, and the executable will fail to start, even if you were never going to actually call any of the OpenSL ES code.
One solution is to delay loading of the shared library until we’re sure we actually can; that is, until we know we’re on Android 2.3 or later. This can be done with the functions dlopen() and dlsym().
Rather than linking to libOpenSLES.so on the link line, use dlopen() to load it at runtime when you’ve verified that SDK version. Use dlsym() to look up pointers to the functions and data you’re going to need; and use dlclose() when you shut down.
This is awkward, but it’s made somewhat easier by the design of OpenSL ES; there is actually only one exported function (slCreateEngine), plus several SL_IID constants.
Note also that the other big API released in 2.3 is the native asset manager, so you’ll have to go through a similar process if you want to read assets also.