安卓模拟器运行PN532读卡器JNI应用:32位libnfc共享库编译方法咨询
安卓模拟器运行PN532读卡器JNI应用:32位libnfc共享库编译方法咨询
先给你吃个定心丸——你Java代码里加载JNI库的方式是完全正确的!System.loadLibrary("pn532_jni")会自动适配当前设备/模拟器的ABI架构,去对应的目录找编译好的.so文件,不用手动写死路径,这点没问题。
接下来看你遇到的核心问题:java.lang.UnsatisfiedLinkError提示libnfc.so是64位,但模拟器需要32位。这是因为你之前编译的是ARM架构的库,而Android Studio默认的x86模拟器是32位的(或者你选了32位的x86镜像),架构不匹配导致的。下面分两种场景给你解决方法:
场景1:编译32位x86架构库,给x86模拟器用(推荐,运行速度快)
x86模拟器性能远优于ARM模拟器,所以优先推荐编译对应x86 32位的库:
- 清理旧编译痕迹:避免之前的ARM编译配置干扰
make distclean rm -rf $HOME/libnfc-android-install
- 生成32位x86的NDK独立工具链
替换/path/to/ndk为你本地NDK的实际路径,API等级选你需要的(比如21):
python3 "/path/to/ndk/make_standalone_toolchain.py" --arch x86 --api 21 --install-dir $HOME/android-x86-toolchain
- 设置编译环境变量
指定用x86 32位的编译工具:
export PATH=$HOME/android-x86-toolchain/bin:$PATH export CC=i686-linux-android-clang export LD=i686-linux-androideabi-ld export AR=i686-linux-androideabi-ar export AS=i686-linux-androideabi-as export RANLIB=i686-linux-androideabi-ranlib export STRIP=i686-linux-androideabi-strip
- 配置并编译libnfc
./configure --host=i686-linux-android --prefix=$HOME/libnfc-x86-32-install --with-drivers=pn532_uart make -j4 make install
同步编译JNI的pn532_jni.so
用同样的x86 32位工具链编译你的pn532_jni.cpp,确保生成的libpn532_jni.so也是32位x86架构。把库放到应用对应目录
将编译好的libnfc.so和libpn532_jni.so放到项目的src/main/jniLibs/x86/目录下,Android Studio会自动打包对应架构的库。
场景2:编译32位ARM架构库,给ARM模拟器用(性能较慢)
如果你非要用ARM架构的库测试,可以创建ARM 32位的模拟器镜像,同时确保编译的是ARM 32位库:
- 生成ARM 32位的NDK工具链
python3 "/path/to/ndk/make_standalone_toolchain.py" --arch arm --api 21 --install-dir $HOME/android-arm-toolchain
- 设置环境变量(和你之前的类似,但确保工具链是32位)
export PATH=$HOME/android-arm-toolchain/bin:$PATH export CC=arm-linux-androideabi-clang export LD=arm-linux-androideabi-ld export AR=arm-linux-androideabi-ar export AS=arm-linux-androideabi-as export RANLIB=arm-linux-androideabi-ranlib export STRIP=arm-linux-androideabi-strip
- 配置编译libnfc
make distclean ./configure --host=arm-linux-androideabi --prefix=$HOME/libnfc-arm-32-install --with-drivers=pn532_uart make -j4 make install
- 创建ARM 32位模拟器
打开Android Studio的AVD Manager,创建新模拟器时选择ABI为armeabi-v7a的系统镜像,这样模拟器会加载ARM 32位的库。
额外注意事项
- 确保你的App的
build.gradle(Module级别)里配置了支持的ABI,比如:
android { defaultConfig { ndk { abiFilters "x86", "armeabi-v7a" // 包含你需要的32位架构 } } }
这样打包时会包含对应架构的库,避免只打包64位库导致的不兼容。
- 可以用
file命令检查编译好的.so文件是32位还是64位,比如:file libnfc.so,如果输出包含32-bit就是正确的。
内容来源于stack exchange
相关产品推荐
相关产品推荐

