Java – System.loadLibrary() does not work in some cases

System.loadLibrary() does not work in some cases… here is a solution to the problem.

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 loadLibrary class in my appActivity since it is already in 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.

Related Problems and Solutions