在 Android 开发中,生成 .so 动态库通常需要使用 Android NDK(Native Development Kit)。下面是一个简单的示例,演示如何创建一个包含 C/C++ 代码的 .so 库并在 Android 应用中使用它。
步骤 1:安装 Android NDK
首先,确保你已经安装了 Android NDK。如果还没有安装,可以通过 Android Studio 的 SDK Manager 进行安装。
步骤 2:创建一个新的 Android 项目
如果还没有项目,可以通过 Android Studio 创建一个新的项目。
步骤 3:添加 C/C++ 源文件
在项目的 app/src/main
目录下创建一个 cpp
文件夹,并在其中创建一个名为 native-lib.cpp
的文件。该文件将包含我们的 C/C++ 代码。
// app/src/main/cpp/native-lib.cpp
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
步骤 4:配置 CMake 构建脚本
在 app
目录下创建一个 CMakeLists.txt
文件,用于配置 CMake 构建脚本。
# app/CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp)
find_library(
log-lib
log)
target_link_libraries(
native-lib
${log-lib})
步骤 5:修改 build.gradle
文件
在 app/build.gradle
文件中添加 NDK 和 CMake 支持。
// app/build.gradle
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags ""
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
步骤 6:加载本地库
在你的 MainActivity
中加载本地库,并调用 C++ 函数。
// app/src/main/java/com/example/myapplication/MainActivity.java
package com.example.myapplication;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}
public native String stringFromJNI();
}
步骤 7:构建并运行项目
现在,构建并运行你的项目。你应该会在应用中看到 “Hello from C++” 的文本,这表示 .so 库已经成功生成并被加载。
通过这些步骤,你可以创建一个简单的 Android 项目,其中包含一个 C/C++ 编写的 .so 动态库,并在 Java 代码中调用它。这个示例演示了基本的流程,实际项目中可能需要更复杂的配置和代码。
java.lang.UnsatisfiedLinkError: dlopen failed: library “libnative-lib.so” not found 请选择 Build > Rebuild Project
就有库, 用Run 'app’就没有库
在 Android 开发中,出现 java.lang.UnsatisfiedLinkError: dlopen failed: library "libnative-lib.so" not found
错误通常意味着应用程序在运行时无法找到或加载指定的 .so 动态库。以下是一些常见的原因和解决方法:
检查库名称
确保在 CMakeLists.txt
中指定的库名称和在 Java 代码中加载的库名称一致。例如:
# CMakeLists.txt
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp)
在 Java 代码中加载库时,名称应为 native-lib
而不是 libnative-lib
:
static {
System.loadLibrary("native-lib");
}
检查生成目录
确保生成的 .so 文件位于正确的目录中。你可以在 Android Studio 中检查 build
文件夹,路径通常为:
app/build/intermediates/cmake/debug/obj/<ABI>/libnative-lib.so
这里 <ABI>
代表你的目标架构,例如 armeabi-v7a
、arm64-v8a
等。
检查 NDK 配置
确保在 build.gradle
文件中正确配置了 NDK 和 CMake 支持:
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags ""
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
确保应用支持目标 ABI
确保应用支持的 ABI 与生成的 .so 文件相匹配。可以在 build.gradle
文件中添加 ndk
配置来指定目标 ABI:
android {
...
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}
}
清理并重建项目
有时,构建缓存可能会导致问题。尝试清理并重建项目:
- 在 Android Studio 中,选择
Build > Clean Project
。 - 然后选择
Build > Rebuild Project
。
确保 .so 文件被包含在 APK 中
在生成的 APK 中检查 .so 文件是否被包含。你可以解压 APK 文件并检查 lib
文件夹中是否包含目标架构的 .so 文件:
unzip app/build/outputs/apk/debug/app-debug.apk -d output_dir
检查 output_dir/lib/<ABI>/
目录下是否存在 libnative-lib.so
。
日志检查
检查 logcat 日志以获取更多信息,可能会提供有关问题的更多线索。你可以通过 Android Studio 的 Logcat 工具查看运行时日志。
通过以上步骤,你应该能够解决 java.lang.UnsatisfiedLinkError: dlopen failed: library "libnative-lib.so" not found
错误。
armeabi-v7a就是正常的 ,arm64-v8a就提示缺少库
加全了:abiFilters ‘armeabi-v7a’, “arm64-v8a”, “x86”, “x86_64”
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.ftpos.productiontoolandroid"
minSdkVersion 23
targetSdkVersion 29
versionCode 32215
versionName "3.22.15_240531.00"
externalNativeBuild{
cmake{
abiFilters 'armeabi-v7a', "arm64-v8a", "x86", "x86_64"
}
}
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}