解决方案
当您为 APK 提供 libopencv_java3.so 时,OpenCV 加载程序不需要 OpenCV 管理器
只需将 OpenCV libs 文件夹(参见下面的 Context)复制到包含您的 AndroidManifext.xml 的文件夹中。现在将这个 libs 文件夹重命名为 jniLibs。结果应该类似于下面的结构。 Props to this post。还有一些细节。
android studio project/
├──libs/
| └── *.jar <-- if your library has jar files, they go here
├──src/
└── main/
├── AndroidManifest.xml
├── java/
└── jniLibs/
├── arm64-v8a/ <-- ARM 64bit
│ └── libopencv_java3.so
├── armeabi-v7a/ <-- ARM 32bit
│ └── libopencv_java3.so
├── x86/ <-- Intel 32bit
│ └── libopencv_java3.so
└── ...
└── libopencv_java3.so
现在构建您的 APK 文件。确保在您的应用程序中正确提供了这些库。这是构建后的 APK:
[project name]\[app name]\build\outputs\apk\debug
只需使用您选择的 Zip 程序打开您的 APK。上面列出的 *.so 文件应该在 APK 中列出:
APK file/
├──lib/
| ├── arm64-v8a/
| │ └── libopencv_java3.so
| ├── armeabi-v7a/
| │ └── libopencv_java3.so
| ├── x86/
| │ └── libopencv_java3.so
| └── ...
| └── libopencv_java3.so
├─ ...
使用此 APK 应该会导致 OpenCV 不再寻找 OpenCV 管理器应用程序。当然,通过为每个 ABI 提供库,您的 APK 会变得非常大。根据您的用例,仅为目标 ABI/平台提供库可能会变得有用。可以为支持的 ABI 创建过滤器。如果是相关的start reading here。
尽情享受吧!
上下文
在运行时,您的应用程序需要 OpenCV 库文件
libopencv_java3.so。该文件有不同的版本,具体取决于您要使用它的目标平台。在此位置查看您的本地 OpenCV SDK 目录:
-
[OpenCV SDK]\sdk\native\libs\
在这里,您可以通过提供相应的 OpenCV 库文件找到提供的 ABI/平台的简短列表:
- armeabi
- armeabi-v7a
- x86
- x86_64
- arm64-v8a
Android OpenCV 管理器
据我了解,OpenCV 管理器应用程序仅在从以下位置调用时向应用程序提供所需的 OpenCV 库:
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
当您有多个需要 OpenCV 库的应用程序时,这很有意义。因此,您只需将其存储在您的移动设备上一次,而不是作为每个应用程序的一部分。
当您查看 OpenCVLoader.initDebug() 在 OpenCV 源代码you'll end up at this statement 中的作用时:
loadLibrary("opencv_java3")
所以基本上,OpenCVLoader 会在查询 OpenCV 管理器之前尝试在您的 APK 中查找 OpenCV 库文件。