【问题标题】:Is it necessary to call system.loadLibrary explicitly for accessing the native methods in a NativeActivity sub class?是否需要显式调用 system.loadLibrary 才能访问 NativeActivity 子类中的本地方法?
【发布时间】:2015-06-09 19:35:58
【问题描述】:

我有一个从 NativeActivity 派生的活动的 Android 应用,如下所示:

public class MyNativeActivity extends android.app.NativeActivity 
{
    public native void TellNativeSide(int info);

    static {
        System.loadLibrary("MyNatAct");  // <--- is this necessary?
    }

    public int OtherMethods(...) ...
}

在 C/C++ 方面,我有

extern "C" void  
Java_mycom_nativity_MyNativeActivity_TellNativeSide(JNIEnv *env,
    jobjectactivityobj, jint info)
{
    ... do something
} // java native TellNativeSide() method //

extern "C" jint JNI_OnLoad(JavaVM *vm, void *)
{
    LOGI("***JNI_OnLoad called...");
}

libMyNatAct.so 库由 NativeActivity 类和 android_main() 自动加载,无论是否使用 system.loadLibrary() 行,一切都可以正常运行。但是,JNI_OnLoad() 永远不会被调用,并且 TellNativeSide() 方法在 Java 端也不可用,除非

system.loadLibrary("MyNatAct");

调用在静态类初始化块中。

因此,似乎必须加载本机 .so 两次。一次在 init 块中使所有本机方法可用并调用 JNI_OnLoad(),另一次由 NativeActivity 类而不是通过 system.loadLibrary()?

这是正确的行为吗?

【问题讨论】:

    标签: android android-ndk loadlibrary native-activity


    【解决方案1】:

    没错。您必须显式调用 system.loadLibrary() 以将本机 Java 方法绑定到 .so 文件的导出函数

    【讨论】:

    • 感谢您的回复。我不明白的是,由于Android端即使没有任何Java代码也可以加载本机共享库,为什么它不能正确初始化本机库(例如调用JNI_OnLoad()并准备好函数表等)而不是让开发人员艰难地解决这个问题。至少正确记录它。
    • 如果您查看NativeActivity 的源代码,您会发现它在本机级别(在loadNativeCode 方法内部)连接到自定义库(他们称之为libraryFile)而不是通过loadLibrary() 或她的亲属。
    • 您的投诉在我看来是有道理的,绝对是关于文档的。我只想提醒您,扩展 android.app.NativeActivity 没有记录,并且一开始也没有打算。这种技术是可能的,这是 Android 平台架构的一个很好的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多