My Android application has a simple NativeActivity βloaderβ with a very simple android_main() that only loads another shared object and transfers 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) }
It works well .. in about half the cases. In other cases, it fails because dlopen() fails and returns NULL with errno = 2 (There is no such file).
Due to the strange inconsistency of this event, I suspected a synchronization problem, and indeed adding sleep(1) to dlopen() stopped it. Something more reliable than sleep(1) will just try 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 number I get from this loop is usually in the range of 10-70 on my device. But this is a hacker ugly decision.
What's going on here? Why can I only load other shared objects only after running NativeActivity? Is there a better way to find when it is safe to download it?
It should be noted that I also call System.loadLibrary("main") from my NativeActivity onCreate()
source share