android - 从 Java 实例化 JNI 库的多个副本

标签 android android-ndk java-native-interface instantiation

我有一个 JNI 库,用于捕获传感器(主要是加速度计和陀螺仪)数据,并对所述数据执行一些特征检测算法。检测到的功能可以通过一些配置文件进行配置。当检测到这些功能时,JNI 使用回调来通知应用程序的 java 端。所有这些都非常有效。

现在我希望能够同时运行同一个 JNI 库的多个实例(这样我就可以同时识别多个配置文件中的功能)。为此,我编写了一个“包装器”类,它实现 JNI 库的回调,并负责该库的所有初始化。我打算简单地实例化此类并单独使用每个实例。我发现,虽然每个包装器实例都是不同的,但该库可以在实例之间重用,几乎就像静态声明一样。当我尝试从 Wrapper 类的第二个实例初始化库时,我发现它已经初始化了。

这是一个类似于我编写的代码的包装类:

public class JNIWrapper {

    public native int initializeJNI(String configPath);
    public native void endProcessing();
    public native int getInstanceIdFromJNI();

    public JNIWrapper(){
        try {
            System.loadLibrary("libjnicode.so");
        }
        catch (Exception e) {
            Log.e("JNI", "WARNING: Could not load libjnicode.so: " + e.getMessage());
        }
    }

    public int initialize(String configPath){
        return initializeJNI(configPath);
    }
    public void stop(){
        endProcessing();
    }
    public void callbackFromJNI(int output, int instanceId){
        //notify the subscribed application(s) of the feature detection
        //via message passing.
    }
}

有谁知道如何实例化 JNI 库的多个副本?
谢谢!

最佳答案

你不能这么做。动态链接器只会将给定的 .so 文件加载到进程中一次。

理想情况下,您可以修改该库以赋予其轻量级面向对象的风格,从而允许您创建实例并从配置文件或调用初始化这些实例(而不是进程级静态)。这不一定像看起来那么复杂 - 基本上将所有状态放入一个结构中,并通过所有调用将指针传递给它。您将经历一次马拉松式的编辑 session ,导致手指“粘贴”疲劳,然后进行一些错误清理。幸运的是,一旦您删除了静态变量,您在所有剩余的使用它们的尝试中都会遇到编译错误。

一个非常hacky的替代方案可能是在AndroidManifest.xml中声明一些远程进程服务并将库加载到每个服务中。或者,真正打破 Android 模型(理论上存在随机杀戮的风险),将库加载到多个按需创建的 native 可执行文件中。

关于android - 从 Java 实例化 JNI 库的多个副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25534786/

相关文章:

android - 内容提供商 uri 如何工作?

android - 构建安卓应用

java - 找不到指定的程序 (MapVirtualKeyEx) JNA (Java)

Android:如何安全地解除绑定(bind)服务

android - 使用 FFMPEG 和 JNI 压缩视频

android - 数据绑定(bind)中看不到工具栏

android - 为什么在 Android NDK 代码中 #include 时看不到包含路径?

android - 从 native 代码在 android 设备屏幕上显示 rgb888 数据

android - 如何将现有的 .so 库添加到 Android Studio 项目中?

java - 如何在 JNI 中实例化一个类