天问

  • Blog
  • 热修复与动态加载
  • python爬虫
  • 专栏
    • 热修复与动态加载
    • NDK开发
    • 设计模式与架构
    • React Native
  • 好文转载
    • 计算机技术
    • 投资理财
    • 摄影与拍照技巧
  • 投稿
  • 关于本站及隐私政策
  • Github
StevenQ
为今天工作,为明天投资,为未来孵化一些东西!
  1. 首页
  2. 计算机技术
  3. 安卓开发
  4. 正文

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

2017年8月25日 787点热度 3人点赞 0条评论

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

java.lang.UnsatisfiedLinkError/findLibrary returned null

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

出错场景:

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

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

解决方案:

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

sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}

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

jniLibs.srcDirs = ['libs']

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

任意路径通过ndk-build命令编译时提示:Android NDK: Could not find application project directory

大部分情况下我们都是在AS工程中编译so这时一般是不会出现这个错误,但是如果有时候要在脚本文件中,在任意目录下编译我们的native代码,而不是在Android Studio中,那么这个时候如果出现这个错误提示的话,原因就是当我们执行ndk-build命令的时候系统找不到Android.mk文件的路径。此时错误提示如下:

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

ndk-build NDK_PROJECT_PATH=ndk_project_path //其中ndk_project_path是包含jni目录的父目录的绝对路径

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

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

ndk-build NDK_PROJECT_PATH=E:\example\so\

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

 

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

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

 

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: ndk
最后更新:2018年1月1日

天问

追梦追自由,穷则独善其身,达则兼济天下

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2022 天问 ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang