胡琪

为今天工作,为明天投资,为未来孵化一些东西

安卓ndk开发使用so注意事项集锦

今天在使用so库的时候出现了一个如下错误,简单记录下。

java.lang.UnsatisfiedLinkError/findLibrary returned null

《安卓ndk开发使用so注意事项集锦》错误详情如图,出现java.lang.UnsatisfiedLinkError错误,这个错误一般是调用本地接口时会出现,在loadLibary时找不到so库而导致findLibrary returned null。这个原因就是so库未被打包到apk中,出现这个错误可以用压缩软件打开apk看下lib目录下是否存在要load的so文件。

出错场景:

自己的项目工程的目录结构如图:

《安卓ndk开发使用so注意事项集锦》

其中的jni目录存放的是C++代码和android.mk/application.mk文件,使用ndk-build命令编译C++代码之后会自动生成libs目录,且会在该目录下自动生成so文件,然后运行安卓程序但是运行就报上述那个错误,也就是so未被打包进apk中。

解决方案:

刚开始百思不得其解,明明在libs目录下已经有so文件了,为何却不能被自动打包进apk呢?后来才发现自己忘记进行so目录相关配置了,忘记在build.gradle文件andrid选项下增加如下配置:

因为android studio默认的so打包路径是src/main/jniLibs或者src/main/jnilibs,也就是说如果你的so文件不是位于这个目录下就需要在build.gradle中指定so文件夹路径。

这一句就是用来指定jniLibs目录的路径的。如果你在src/main/目录下创建一个jniLibs目录,然后将so放到该目录下的话就无需配置,因为这个是android studio默认的路径。否则就需要使用该语句来配置so路径。

Android NDK: Could not find application project directory !

一般如果我们在安卓工程中按照规范建好了相应的目录结构是不会出现这个错误的,出现这个错误的原因就是当我们执行ndk-build命令的时候系统找不到Android.mk文件的路径。此时错误提示如下:

《安卓ndk开发使用so注意事项集锦》

从错误第二行提示可以看到需要定义一个NDK_PROJECT_PATH指向这个app工程目录,这里所说的app工程目录即是指包含jni目录的上一级目录,其中我们的jni代码和Android.mk和Application.mk文件都位于jni目录下,例如如果想在任意一个目录下编译so,比如在so这个目录下编译c++代码产生so,这时我们可以在so目录下创建一个jni目录,然后将c++代码和Android.mk,Application.mk文件都放到这个目录下,然后可以在任意目录执行以下命令即可:

举个例子:如果想在e盘的so目录下编译一个so文件,那么我们需要在so目录下创建一个jni目录,然后把前面提到的相关文件放到jni目录下,此时目录结构如下图所示:

《安卓ndk开发使用so注意事项集锦》

然后在命令行执行以下命令即可:

执行完该命令后会系统会自动在jni目录的同级目录下创建一个libs目录,生成好的so就是放在了该libs目录下。还会自动创建一个objs目录,生成的.o文件就是在这个目录的相关子目录下,此时的目录层级结果如下:

《安卓ndk开发使用so注意事项集锦》

 

当然也可以直接cd到so目录,然后直接执行ndk-build命令也可以达到同样的效果。注意创建的目录名称必须为jni,这是系统默认查找路径,指向NDK_PROJECT_PATH的路径必须为jni的上一级目录,即其父目录,而不能是jni目录,这是因为系统会默认从jni目录查找Android.mk文件,如果执行ndk-build NDK_PROJECT_PATH=E:\example\so\jni命令将会出现以下错误:

《安卓ndk开发使用so注意事项集锦》

从这个错误可以看到系统是会默认从当前目录的jni目录下查找Android.mk文件的,所以NDK_PROJECT_PATH的指向的路径必须为jni目录的上一级目录。

 

打赏

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注