JNI_OnUnload is never called on Android, because the shared library is
never unloaded. It can't be, unless any code that potentially uses it
is also gone.
In an ideal world, this would simply mean that the relevant class
loader, and all classes loaded by that class loader, are unreferenced
and can be garbage-collected. With native code the world is rarely in
an ideal state, and if bits of native code manage to share parts of
themselves then things can get ugly. One way this commonly goes bad
is when there's a C++ object lurking somewhere and the destructor gets
called. If we've dlclosed the shared library, the process will crash.
At any rate, the Android lifecycle doesn't really support an
"application exit" -- either your app lurks quietly until something
needs it, or the system kills it abruptly when it needs the memory for
something else. Because the system works this way, support for class
unloading has not been implemented yet, and is not at the top of the
feature list.
It sounds like you want to explicitly manage resources allocated in
native code. You should not rely on JNI_OnLoad / JNI_OnUnload to do
that. Even on a non-Android system you're likely going to get in
trouble, because if you're holding global references to app classes,
those references would prevent the classes from being unloaded and
JNI_OnUnload would never be called. Instead, use explicit startup/
shutdown calls at appropriate points in your Android app.
Incidentally, there's no need to use UnregisterNatives -- the methods
are presumably registered to a class that is getting discarded. In
fact, the JNI spec says you shouldn't use it:
"This function should not be used in normal native code. Instead, it
provides special programs a way to reload and relink native
libraries."