1 背景
1.1 java.lang.UnsatisfiedLinkError: dlopen failed: library “libc++_shared.so” not found
libc++_shared.so
之前默认集成在 opencv_java3.so
,但是在OpenCV4.x以后,该动态库默认不集成在opencv_java4.so
。
1.2 E/OpenCV/StaticHelper: OpenCV error: Cannot load info library for OpenCV
参考 https://github.com/opencv/opencv/issues/15567#issuecomment-1016603238。这个是OpenCV安卓SDK的问题,不影响正常使用OpenCV库。
2 创建OpenCV-Android库
2.1 下载 opencv-4.6.0-android-sdk
从OpenCV官网下载OpenCV4.6.0的OpenCV for Android压缩文件opencv-4.6.0-android-sdk.zip。
2.2 创建OpenCV4Android项目
利用 Android Studio 3.0.1 创建一个android项目,这里我创建的是OpenCV4Android项目。
2.3 创建OpenCV-Android库
- 依次点击File->New->New Module…,在弹出的对话框中,选择Android Library,然后,点击Next。
- 在Application/Library name:处,输入安卓库名称OpenCV-Android;
点击Package name:后面的Edit,修改包名称为org.opencv
2.4 配置OpenCV-Android库
-
解压下载的 opencv-4.6.0-android-sdk.zip
-
复制 OpenCV-android-sdk/sdk/java/src/org/opencv 文件夹内的所有子文件夹,并粘贴到OpenCV-Android库中 opencv-android/src/main/java/org/opencv 的文件夹下。
-
在 opencv-android/src/main/java/org/opencv/android 子文件中,做如下操作:
- 删除 AsyncServiceHelper.java 文件
- 修改 OpenCVLoader.java 文件,注释掉以下内容:
/** * Loads and initializes OpenCV library using OpenCV Engine service. * @param Version OpenCV library version. * @param AppContext application context for connecting to the service. * @param Callback object, that implements LoaderCallbackInterface for handling the connection status. * @return Returns true if initialization of OpenCV is successful. */
// public static boolean initAsync(String Version, Context AppContext,
// LoaderCallbackInterface Callback)
// {
// return AsyncServiceHelper.initOpenCV(Version, AppContext, Callback);
// }
```
-
复制 OpenCV-android-sdk/sdk/java/res/values/attrs.xml 到 opencv-android/src/main/res/values/ 文件内;
-
修改 opencv-android/src/main/res/values/string.xml ,修改后如下所示:
<resources> <string name="app_name">OpenCV-4.6.0</string> </resources>
-
把 OpenCV-android-sdk/sdk/native/libs 文件夹下的子文件夹和 OpenCV-android-sdk/sdk/native/3rdparty/libs 文件夹下的子文件夹拷贝 opencv-android/src/main 文件下创建的 jniLibs 文件夹内。
3 app文件内相关文件修改
3.1 修改app/src/main/res/layout/activity_main.xml
为<TextView>
添加id,修改后代码片段如下所示:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="cn.epbox.opencv4android.MainActivity">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
3.2 为app添加opencv-android库
- 点击 File->Project Structure… 打开 Project Structure 对话框;
- 点击 Modules 下的app,再在右侧点击 Dependencies ;
- 点击Dependencies下框附近的
+
号,选择 3 Module Dependency ,在弹出的对话框中,选择 :opencv-android ,最后依次点击 OK,OK。
3.3 修改MainActivity
添加TextView对象,如果点击该对象,则弹出一个短消息!
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView = (TextView) findViewById(R.id.text_view);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "You clicked textView!", Toast.LENGTH_SHORT).show();
if (OpenCVLoader.initDebug()) {
textView.setText("OpenCV-4.6.0 loaded successful!");
}
}
});
}
}
4. 处理 library “libc++_shared.so” not found
- 点击 File -> Settings… ,按照下图定位到SDK Tools,选择NDK最新版本号。依次点击Apply, OK。
- 复制
/home/tianzx/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so
到opencv-android/src/main/jniLibs/arm64-v8a/
- 复制
/home/tianzx/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so
到opencv-android/src/main/jniLibs/armeabi-v7a/
- 复制
/home/tianzx/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/libc++_shared.so
到opencv-android/src/main/jniLibs/x86/
- 复制
/home/tianzx/Android/Sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so
到opencv-android/src/main/jniLibs/x86_64/
5. 运行
点击 Run->Run ‘app’ ,连接手机的界面如下所示:
点击,Hello World!后的界面如下所示:
找到opencv-android库对应的aar文件
在opencv-android/build/outputs/aar文件夹下,生成的debug和release两种格式的aar文件夹。
opencv-android-debug.aar
opencv-android-release.aar
如何导入aar文件
参考这里
Bonus
修改app和opencv-android文件夹内的build.gradle文件中的buildTypes
字段,仅生成适合指定平台的apk文件。
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
// added by JohnTian
splits {
abi {
enable true
reset()
include 'armeabi-v7a', 'arm64-v8a'
universalApk false
}
}
}
参考
- Cannot load info library for OpenCV #15567
- Пишем простейшее приложение под Android для распознавания объектов с камеры