Android 使用so库的遇到的坑

简介: Android 使用so库的遇到的坑

使用so库采坑记录


做Android开发会遇到各种各样的问题,遇到问题不可怕,解决了并且知道为什么,下次遇到能马上解决就好了,今天要说的就是这个so库的使用采坑了。


通常在使用一些第三方的SDK时会有一些so库需要你放入到项目中,这里分为两步,其实,第一步放入,第二步使用。两步都有坑,幸运的是我都踩到了,所以记录一下:


常规的so库是使用C或者C++写的,Android中只要调用就好了,而这些依赖库通常的有好几个版本文件,比如我们来看看百度的文字识别SDK,如下图所示。


20210310153254227.png


上面有四个文件夹arm64-v8a、armeabi、armeabi-v7a、x86,这四个文件表示不同的so库的版本,基本可以满足现在的Android智能机,但是不一定支持虚拟设备,所以当你涉及到使用第三方SDK时,首先就是要使用真机,别用虚拟机,做人不要太头铁了,出问题难受的是你自己。


下面的jar包,就是常规的Java架包,里面封装了一些方法,当你的项目加载这个架包之后,你就可以调用它里面的方法。如何判断这个jar有没有加载到你的项目呢?


就看这个架包能不能展开,如下图所示:


20210310154146972.png


当然也有人是jar包能展开了,但是项目中还是调用不了方法,这个时候,你关掉Android Studio 泡杯茶,然后看看窗外的风景,再打开Android Studio,它就好了。


20210310154339718.png


再说的通俗一点就是你去网吧打游戏,然后打的开心的时候电脑卡死了,此时你关机重启就好了,是一样的,你目前先这么理解就好了,刨根问题是没有好下场滴?反派死于话多!只有打酱油的能活到大结局。


你可以看到我的jar放在libs下,什么?你说的你的项目中没找到libs文件夹?


20210310154829564.png


那你把你的工程切换到Project就可以了,你就能找到,找不到就投诉Google,欺骗消费者,虽然你没有花过钱,都是白嫖。


然后把那包含so库的四个文件夹和jar包都放到这个libs下。


一般来说Android默认是读取jniLibs下的文件的,但是这个文件在项目创建时是没有的,需要开发者手动创建。但是你同样可以省略这一步,就放在libs。这样做你就需要在app下的build.gradle中的android{}闭包下,添加这样一段代码:


  //改变.so的路径到libs下
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }


注释都给你写好了,既然你默认读取jniLibs文件,那么我就改了你的默认读取文件夹到libs下,那就可以了,改完之后记得右上角点一下Sync Now。意思是同步配置资源。


配置完这一步,运行项目,然后调用so库中的代码时。


20210310155514708.png


看到这样的报错,就问你慌不慌?不慌的话你就看不到我这篇文章了,兄嘚!其实上面一堆报错了,最要的就只有一句话:


couldn’t find “libleveldb.so”


你先别管这个libleveldb是什么,你只要知道它现在是一个so库就可以了。刚才我们明明指向了libs文件夹,怎么会找不到这个so库呢?这不是扯呢吗?


其实也很好解决了,so库是属于ndk开发,不同的so库就有不同的配置,因此当你的常规配置解决不了问题的时候,就要尝试新的玩法。


在app模块下的build.gradle中的defaultConfig{}闭包中添加如下代码:


  ndk {
            abiFilters "armeabi-v7a", "x86"
        }


这就是一个ndk的过滤器,然后你再运行,如果还是说找不到,那就再改动一下。


  ndk {
            abiFilters  "armeabi","x86","armeabi-v7a","arm64-v8a"
        }


记得改动后要Sync 或者Sync Now 。否则你的改动无效。


以上操作基本上就可以解决我的第一个找不到so库的问题。


然后我就要调用里面的方法了,再运行一手。


20210310160840228.png


重点同样也是一句话:


No implementation found for boolean com.abc.LevelDB.open(java.lang.String) (tried Java_com_abc_LevelDB_open and Java_com_abc_LevelDB_open__Ljava_lang_String_2


这句话是什么意思呢?就是说无法实现你的这个类型的方法,在这个包下的类中。这个错误是比较奇葩的,一般的第三方是不会因为你的包名有变化就出问题的,但是巧妙就巧妙在这里了,如果你的这个so库是个人编写的,那么就有这种可能,那么你就不能去随意的改变它的类的包名,比如说。


20210310161240956.png


上面这个图有一个包名,两个实现类,实现类里面调用了so库里面的代码。这是原本的样子,而我觉得这个包名太长了没有什么意义,因此我改成下面这样。

20210310161412345.png


然后就报错了,这就说明了这个so库在写的时候就规定要在什么包名下,不能改变包名,改了就找不到这个下面的类了,里面的方法也就是用不了,然后程序就崩溃了。就好比钥匙和锁的关系,钥匙还是那个钥匙,锁换了,钥匙就打不开了。


这么一说你就理解了,所以说当你出现 No implementation found for 这种开头,后面是下划线分割的包名类名,又涉及到so库,那么你可以通过这样的方式来试着解决的,我写的是我真实解决问题的过程。但是每个人的项目环境都有不同,因此很多事情你需要尝试一下才知道行不行,对吧。


如果你有不同的解决方法不妨告诉我,我也会添加到文章中,上高水长,后会有期~


相关文章
|
6月前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
228 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
5月前
|
存储 缓存 Android开发
安卓Jetpack Compose+Kotlin, 使用ExoPlayer播放多个【远程url】音频,搭配Okhttp库进行下载和缓存,播放完随机播放下一首
这是一个Kotlin项目,使用Jetpack Compose和ExoPlayer框架开发Android应用,功能是播放远程URL音频列表。应用会检查本地缓存,如果文件存在且大小与远程文件一致则使用缓存,否则下载文件并播放。播放完成后或遇到异常,会随机播放下一首音频,并在播放前随机设置播放速度(0.9到1.2倍速)。代码包括ViewModel,负责音频管理和播放逻辑,以及UI层,包含播放和停止按钮。
|
6月前
|
存储 Java API
Android 浅度解析:mk预置AAR、SO文件、APP包和签名
Android 浅度解析:mk预置AAR、SO文件、APP包和签名
805 0
|
6月前
|
Unix Linux Shell
FFmpeg开发笔记(八)Linux交叉编译Android的FFmpeg库
在Linux环境下交叉编译Android所需的FFmpeg so库,首先下载`android-ndk-r21e`,然后解压。接着,上传FFmpeg及相关库(如x264、freetype、lame)源码,修改相关sh文件,将`SYSTEM=windows-x86_64`改为`SYSTEM=linux-x86_64`并删除回车符。对x264的configure文件进行修改,然后编译x264。同样编译其他第三方库。设置环境变量`PKG_CONFIG_PATH`,最后在FFmpeg源码目录执行配置、编译和安装命令,生成的so文件复制到App工程指定目录。
336 9
FFmpeg开发笔记(八)Linux交叉编译Android的FFmpeg库
|
23天前
|
安全 Java 网络安全
Android远程连接和登录FTPS服务代码(commons.net库)
Android远程连接和登录FTPS服务代码(commons.net库)
20 1
|
27天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
75 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
1月前
|
Ubuntu Shell API
Ubuntu 64系统编译android arm64-v8a 的openssl静态库libssl.a和libcrypto.a
Ubuntu 64系统编译android arm64-v8a 的openssl静态库libssl.a和libcrypto.a
|
3月前
|
编解码 测试技术 Android开发
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
本文详细介绍了如何利用CameraX库实现高质量的照片及视频拍摄功能,包括添加依赖、初始化、权限请求、配置预览与捕获等关键步骤。此外,还特别针对不同分辨率和帧率的视频拍摄提供了性能优化策略,确保应用既高效又稳定。
293 1
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
|
3月前
|
监控 Java API
Android经典实战之OkDownload:一个经典强大的文件下载开源库,支持断点续传
本文介绍的 OkDownload 是一个专为 Android 设计的开源下载框架,支持多线程下载、断点续传和任务队列管理等功能,具备可靠性、灵活性和高性能特点。它提供了多种配置选项和监听器,便于开发者集成和扩展。尽管已多年未更新,但依然适用于大多数文件下载需求。
344 1
|
3月前
|
API Android开发
Android项目架构设计问题之选择和使用合适的UI库如何解决
Android项目架构设计问题之选择和使用合适的UI库如何解决
47 0