我有一个 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/