System.loadLibrary() does not work in some cases
I’m working on a cocos2d-x game and I’m experiencing some weird behavior, I’m not sure if it’s normal or what’s happening, but that’s what’s happening, so the AppActivity
.java class extends the Cocos2dxActivity.java
class. I don’t have to call
System.loadLibrary("MyGame") in my AppActivity.java class;
Because it is a > called in Cocos2dxActivity.java
. However, this happens if I make a normal declaration like this
private native String invokeNativeString();
Everything works fine, but then I tried to declare it directly below but I get this error
String ami = new String(invokeNativeString());
An error occurred:
05-01 09:11:27.250 10135-10135/com.izzyjmachado.spaceball E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.izzyjmachado.spaceball, PID: 10135
java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String org.cocos2dx.cpp.AppActivity.invokeNativeString() (tried Java_org_cocos2dx_cpp_AppActivity_ invokeNativeString and Java_org_cocos2dx_cpp_AppActivity_invokeNativeString__)
Why does it work when I declare a plain native string, but I can’t find it when I use it in a string declaration?
I
was able to solve this problem by calling it in my AppActivity
class, but I feel that it should work without having to call the
class in my appActivity since it is already in loadLibrary
Cocos2dxActivity
and appActivity extends Cocos2dxActivity
called? Thank you for any help you can give me
static {
System.loadLibrary("MyGame");
}
Solution
That’s because your activity called super.onCreate()
early in its onCreate().
Just to make it clear: it should be called like this, you’re not mistaken.
But. The Cocos2dxActivity author chooses to load the native library during onCreate().
They made this decision for good reason: it allows them to extract android.app.lib_name from your package and choose the right library that way.
The JNI tutorial generally recommends loading local libraries in a static {}
block. The latter is a safer practice (for example, it solves your field initialization problem), but it has its own drawbacks.
Most importantly, you can
move the initialization of the ami field into AppActivity.onCreate()
if you prefer that way, or you can use static blocks in AppActivity if you prefer
. End users won’t really notice the difference.