I'm developing an app using plain C and the latest Android NDK. I noticed that the *.so is never flushed from memory and so the global variables retain their values from the last run of the app, e.g. consider the following code:
static int init = 0;
void android_main(struct android_app* state)
{
init = 1;
dostuff();
}
When my app is launched for the first time, "init" is 0 and set to 1. Starting with the second run, "init" will always be 1 because the *.so is still in memory. But I want the globals to be reset to their default value whenever android_main() is called!
So is there any way to ensure that the globals are always reset before android_main() is called or do I have to do this manually? (which would be a huge work for my app because I'm having tons of globals spread across different *.c sources)
Thanks!
You are kinda between a rock and a hard place. The rock being that initialized global data in shared libraries is never actually "initialized", per se. The initial values are actually in the .so file itself in DATA sections which just get copied into memory on load and Voila! initialized data.
The hard place is is that Java JNI by design has no UnloadLibrary(), and specifies that a call to LoadLibrary() for an already-loaded library is to be ignored.
This is further complicated because you are using the Android NativeActivity helper, which hides you from any of the Java that actually loads the library, as well as the Activity code itself, where you might (might) be able to end the activity when your native code is done.
I'm not sure dumping NativeActivity and just writing a thin JNI shim would help much, though, since you still wouldn't be able to unload, or reload, the native code anyway, and explicitly ending an activity in Android can be a little tricky. Actually, I'll bet you COULD get the activity to end cleanly and reliably - it's not something I do and so I am not very familiar with it.
Another possibility would be to build 2 native libraries. One would just be your app, and would have no Android-specific code in it at all. The other library would be the one loaded by NativeActivity - with android_main() and all - and it would use the dlopen() / dlsym() / dlclose() C API to load, run, and cleanup the "app" library.
I think it could work - but I've never tried it. The header to do the shared library stuff (dlfcn.h) is in the NDK.
The only solution I've found is to call exit() within the native c code - However, this does have the side affect of also closing the activity. Would be interested to know if you found a better solution?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With