My Android app has a simple "loader" NativeActivity with a very simple android_main()
which only loads a different shared object and passes control to it:
typedef void (*Tandroid_main)( android_app*);
void android_main( android_app* state )
{
void* glib = dlopen("libmain.so", RTLD_NOW);
void* fmain = dlsym(glib, "android_main");
Tandroid_main libmain = (Tandroid_main)fmain;
libmain(state)
}
This works well.. about half of the times. Other times it crashes since dlopen()
fails and return NULL with errno=2 (No such file).
Due to the strange inconsistency of this occurrence I suspected a timing issue and indeed, adding a sleep(1)
before dlopen()
stopped it from happening. Something more robust than sleep(1)
would be just trying it in a loop:
int count = 0;
void* glib = dlopen(soName, RTLD_NOW);
while(glib == NULL) {
sched_yield();
++count;
glib = dlopen(soName, RTLD_NOW);
}
The count I'm getting from this loop is usually something in the range of 10-70 on my device. But this is a hackish ugly solution.
What is really going on here? How come I can only load other shared objects only slightly after the NativeActivity starts? Is there a better way to find when when it's safe to load it?
It should be noted that I am also calling System.loadLibrary("main")
from my NativeActivity's onCreate()