In my Android app I have 4 libraries:
libTemplate.so
depends on libPorkholt.so
libPorkholt.so
depends on libpng15.so
depends on liblua.so
depends
I don't think Android will automatically load libraries other than the ones specified in the manifest, so you should create a "dummy" Java class to load external dependencies, it should contain:
static {
System.loadLibrary("openal");
System.loadLibrary("lua");
System.loadLibrary("png15");
System.loadLibrary("Porkholt");
System.loadLibrary("Template");
}
Since this section is static, it will be executed when the class is loaded, even if its methods aren't called.
Your Activity probably has a static constructor that calls System.Load("libTemplate.so"). It should load the other libraries according to the dependency order.
This no longer affects API 24+ (see the framework fix here). However, if you need to support older versions, extend NativeActivity
, refer to your extension in the manifest file instead, and add the static
block mentioned in Sdra's answer as workaround.
Since apparently Android isn't smart enough to set a LD_LIBRARY_PATH correctly, I managed to solve my problem by creating a small bootstrapper library that manually loads the actual activity. Here's the code:
#include <android/native_activity.h>
#include <android/log.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "Porkholt", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "Porkholt", __VA_ARGS__))
#define LIB_PATH "/data/data/@PH_BUNDLE_ID@/lib/"
void * load_lib(const char * l)
{
void * handle = dlopen(l, RTLD_NOW | RTLD_GLOBAL);
if (!handle)
{
LOGE("dlopen(\"%s\"): %s", l, strerror(errno));
exit(1);
}
return handle;
}
void ANativeActivity_onCreate(ANativeActivity * app, void * ud, size_t udsize)
{
LOGI("Loaded bootstrap");
load_lib(LIB_PATH "libpng15.so");
load_lib(LIB_PATH "liblua.so");
load_lib(LIB_PATH "libopenal.so");
load_lib(LIB_PATH "libPorkholt.so");
void (*main)(ANativeActivity*, void*, size_t) = dlsym(load_lib(LIB_PATH "lib@PH_APP_TARGET@.so"), "ANativeActivity_onCreate");
if (!main)
{
LOGE("undefined symbol ANativeActivity_onCreate");
exit(1);
}
main(app, ud, udsize);
}