Nexus7 无法加载原生库
Nexus7 can't load native library
我尝试构建本机库(在我的例子中是 SQLite)以将它们添加到我的 Android 项目中。
我的问题:我的 Android 6.0.1 的 Nexus7 试图从 ../lib/arm/libsqlite3.so
路径加载它。但是这条路不存在。
从头开始:
在这个文件夹中,我创建了一个 CMakeLists.txt
文件,内容如下:
cmake_minimum_required(VERSION 3.4.1)
add_definitions(-DSQLITE_DQS=0)
add_definitions(-DSQLITE_DEFAULT_MEMSTATUS=0)
add_definitions(-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1)
add_definitions(-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1)
add_definitions(-DSQLITE_MAX_EXPR_DEPTH=0)
add_definitions(-DSQLITE_OMIT_DECLTYPE=1)
add_definitions(-DSQLITE_OMIT_DEPRECATED=1)
add_definitions(-DSQLITE_OMIT_PROGRESS_CALLBACK=1)
add_definitions(-DSQLITE_USE_ALLOCA=1)
add_library(
# Specifies the name of the library.
sqlite3
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
shell.c
sqlite3.c
sqlite3.h
sqlite3ext.h
)
- 我用这个命令构建了库(后跟
make
):
~/development/sdks/android-sdk/cmake/3.10.2.4988404/bin/cmake \
-DANDROID_NDK=~/development/sdks/android-sdk/ndk/21.0.6113669 \
-DCMAKE_TOOLCHAIN_FILE=~/development/sdks/android-sdk/ndk/21.0.6113669/build/cmake/android.toolchain.cmake \
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=armeabi-v7a \
-DANDROID_TOOLCHAIN=clang \
-DANDROID_ABI=armeabi-v7a \
-DANDROID_NATIVE_API_LEVEL=29
我为这 4 个 ABI 做了这个:armeabi-v7a
、arm64-v8a
、x86
和 x86_64
。
之后,我将 .so
个文件复制到 app/src/main/jniLibs/<abi>
文件夹中,文件夹结构如下所示:
.
├── app
│ └── src
│ ├── main
│ │ ├── jniLibs
│ │ │ ├── arm64-v8a
│ │ │ │ └── libsqlite3.so
│ │ │ ├── armeabi-v7a
│ │ │ │ └── libsqlite3.so
│ │ │ ├── x86
│ │ │ │ └── libsqlite3.so
│ │ │ └── x86_64
│ │ │ └── libsqlite3.so
当我现在 运行 应用程序时,我收到以下错误消息:
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__aeabi_memcpy"
referenced by "/data/app/com.example.myapplication-2/lib/arm/libsqlite3.so"...
为什么 Android 尝试从 lib/arm
文件夹而不是 lib/armeabi-v7a
加载库?当我对 Android 7.1.1.
的不同设备执行相同操作时,它会起作用
顺便说一句,Android Native Lib 演示项目也可以。当我查看它的 apk 时,本机库位于 lib/armeabi-v7a
文件夹中。那么,为什么它在 Android Studio 编译本机代码时有效,但在我添加预编译的本机库时却不起作用?
正如迈克尔所写,我必须设置正确的DANDROID_NATIVE_API_LEVEL
。要在 Android 6.0.1 上获得 运行,我必须使用 API 级别 23 或以下。所以 cmake
命令应该是这样的:
~/development/sdks/android-sdk/cmake/3.10.2.4988404/bin/cmake \
-DANDROID_NDK=~/development/sdks/android-sdk/ndk/21.0.6113669 \
-DCMAKE_TOOLCHAIN_FILE=~/development/sdks/android-sdk/ndk/21.0.6113669/build/cmake/android.toolchain.cmake \
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=armeabi-v7a \
-DANDROID_TOOLCHAIN=clang \
-DANDROID_ABI=armeabi-v7a \
-DANDROID_NATIVE_API_LEVEL=19
我尝试构建本机库(在我的例子中是 SQLite)以将它们添加到我的 Android 项目中。
我的问题:我的 Android 6.0.1 的 Nexus7 试图从 ../lib/arm/libsqlite3.so
路径加载它。但是这条路不存在。
从头开始:
在这个文件夹中,我创建了一个
CMakeLists.txt
文件,内容如下:
cmake_minimum_required(VERSION 3.4.1)
add_definitions(-DSQLITE_DQS=0)
add_definitions(-DSQLITE_DEFAULT_MEMSTATUS=0)
add_definitions(-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1)
add_definitions(-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1)
add_definitions(-DSQLITE_MAX_EXPR_DEPTH=0)
add_definitions(-DSQLITE_OMIT_DECLTYPE=1)
add_definitions(-DSQLITE_OMIT_DEPRECATED=1)
add_definitions(-DSQLITE_OMIT_PROGRESS_CALLBACK=1)
add_definitions(-DSQLITE_USE_ALLOCA=1)
add_library(
# Specifies the name of the library.
sqlite3
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
shell.c
sqlite3.c
sqlite3.h
sqlite3ext.h
)
- 我用这个命令构建了库(后跟
make
):
~/development/sdks/android-sdk/cmake/3.10.2.4988404/bin/cmake \
-DANDROID_NDK=~/development/sdks/android-sdk/ndk/21.0.6113669 \
-DCMAKE_TOOLCHAIN_FILE=~/development/sdks/android-sdk/ndk/21.0.6113669/build/cmake/android.toolchain.cmake \
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=armeabi-v7a \
-DANDROID_TOOLCHAIN=clang \
-DANDROID_ABI=armeabi-v7a \
-DANDROID_NATIVE_API_LEVEL=29
我为这 4 个 ABI 做了这个:armeabi-v7a
、arm64-v8a
、x86
和 x86_64
。
之后,我将 .so
个文件复制到 app/src/main/jniLibs/<abi>
文件夹中,文件夹结构如下所示:
.
├── app
│ └── src
│ ├── main
│ │ ├── jniLibs
│ │ │ ├── arm64-v8a
│ │ │ │ └── libsqlite3.so
│ │ │ ├── armeabi-v7a
│ │ │ │ └── libsqlite3.so
│ │ │ ├── x86
│ │ │ │ └── libsqlite3.so
│ │ │ └── x86_64
│ │ │ └── libsqlite3.so
当我现在 运行 应用程序时,我收到以下错误消息:
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__aeabi_memcpy"
referenced by "/data/app/com.example.myapplication-2/lib/arm/libsqlite3.so"...
为什么 Android 尝试从 lib/arm
文件夹而不是 lib/armeabi-v7a
加载库?当我对 Android 7.1.1.
顺便说一句,Android Native Lib 演示项目也可以。当我查看它的 apk 时,本机库位于 lib/armeabi-v7a
文件夹中。那么,为什么它在 Android Studio 编译本机代码时有效,但在我添加预编译的本机库时却不起作用?
正如迈克尔所写,我必须设置正确的DANDROID_NATIVE_API_LEVEL
。要在 Android 6.0.1 上获得 运行,我必须使用 API 级别 23 或以下。所以 cmake
命令应该是这样的:
~/development/sdks/android-sdk/cmake/3.10.2.4988404/bin/cmake \
-DANDROID_NDK=~/development/sdks/android-sdk/ndk/21.0.6113669 \
-DCMAKE_TOOLCHAIN_FILE=~/development/sdks/android-sdk/ndk/21.0.6113669/build/cmake/android.toolchain.cmake \
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=armeabi-v7a \
-DANDROID_TOOLCHAIN=clang \
-DANDROID_ABI=armeabi-v7a \
-DANDROID_NATIVE_API_LEVEL=19