一些情况下System.loadLibrary()无法正常工作

3

我正在制作一个cocos2d-x游戏,我遇到了一些奇怪的行为,不确定它是否正常或发生了什么,但是以下是发生的情况:AppActivity.java类扩展了Cocos2dxActivity.java类。在我的AppActivity.java类中,我不需要调用System.loadLibrary("MyGame");,因为它已经在Cocos2dxActivity.java中被调用了。但是如果我像这样进行普通声明,会发生以下情况。

private native String invokeNativeString();

一切都运行良好,但是当我尝试在这个下面直接声明时,我收到了这个错误

String ami = new String(invokeNativeString());

然后遇到了错误:

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__)

为什么我声明一个普通的本地字符串时它可以工作,但是当我在字符串声明中使用方法时,它却找不到方法?
我通过在我的AppActivity类中调用它来解决了这个问题,但我感觉不应该在我的appActivity类中调用loadLibrary,因为它已经在Cocos2dxActivity和appActivity扩展了Cocos2dxActivity中被调用了?非常感谢你们能给我任何帮助。
static {
    System.loadLibrary("MyGame");
}

当我将带有base64的字符串移动到onCreate方法内部时,一切都正常工作,但我仍然想知道为什么在声明它与我的其他全局变量时它不起作用。 - isJulian00
2个回答

3
那是因为你的活动在其onCreate()中早期调用了super.onCreate()。仅为明确起见:这应该是如何调用的,你没有犯错误。
但是,Cocos2dxActivity作者选择在onCreate()期间加载本地库。他们有一个很好的理由做出这个决定:它允许他们从你的包中提取android.app.lib_name,并以此选择正确的库。
JNI教程通常建议在static {}块中加载本地库。后者是一种更安全的做法(例如,它解决了您在字段初始化方面的问题),但它也有自己的缺点。
总之,如果您喜欢这种方式,您可以将ami字段的初始化移动到AppActivity.onCreate()中,或者如果您更喜欢,则可以在您的AppActivity中使用static块。最终用户实际上不会注意到区别。

1
非常感谢您详细的回答,现在一切都清晰明了。 - isJulian00

1
似乎您在尝试调用本地函数时,本地库尚未加载。

但是当我调用“private native String invokeNativeString();”并将此声明“String ami = new String(Base64.decode(invokeNativeString(),Base64.DEFAULT));”放在同一位置时,它可以工作,因此我不认为这是问题所在。 - isJulian00

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接