【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案
相信很多小伙伴都在android开发中遇到调用jni的各种巨坑,因为我们不得不在很多地方用到第三方库so文件,然而第三方官方通常都只会给出ADT环境下的集成方式,而谷歌亲儿子android studio默认采用的却是gradle方式,与ADT编辑的方式大不相同,那再andorid studio中如何导入so文件呢?
在android studio 中我们可能会用到jar包和so文件的方式,对于jar包可能接触更多,只需要我们把工程转换为project显示方式,打开app下的libs文件夹,导入即可。随后再添加jar包为我们的工程依赖即可。
好吧,楼主不想跑题。对于so文件也非常简单,只需要在app/src/main下面建立一个jniLibs,再把我们的第三方so文件拷贝进去即可,需要重点注意的是,我们安卓一般有几种CPU,而不再是以前的只有armv5,目前有7种。ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI。在Android系统上,每一个CPU架构对应一个ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。而这些包的名字是不能随便更改的。
而我们在开发中,应该尽可能的得到每一种ABI优化过的.so文件,而不应该混合着使用,其实为每一种ABI提供对应的.so文件其实也是SDK提供方应该做的,不过或许你不会这么好运,也许你的SDK提供方就会像和楼主遇到的一样,只给你提供一个armeabi方式的.so文件,额,是的,你写一个小demo测试SDK的功能可能是可用的,然后当你把你写的demo引入到你的项目中后,你或许总能遇到这样那样的问题,比如,最常见的就是UnsatisfiedLinkError,当然你还可能遇到dlopen: failed以及其它各种形式的crash或者低下的性能。而你或许在有的手机上运行却是不报任何错误的。比如楼主得到的第三方SDK,只提供了armeabi下的so文件,楼主导入到项目中后,(楼主项目之前支持了arm64-v8a等其他方式的ABI)使用相对版本老一点的手机运行,Ok,no problem!然而当用到小米系列的任何一款手机的时候,运行,直接Crash,原因在初始化的时候直接找不到某些.so文件,导致无法使用System.loadLabray的方式加载,不知道遇上的小伙伴是怎么解决的,不过就这么一个问题,让楼主和一些同样的开发人员也是抓破了脑袋,楼主是知其原因,而不知其解决方案,这是最令人头疼的。
下面是android studio的报错信息。
08-21 11:12:48.413 7971-7971/com.hkyc.shouxinteacher.ischool E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.hkyc.shouxinteacher.ischool, PID: 7971
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.hkyc.shouxinteacher.ischool-2/base.apk"],nativeLibraryDirectories=[/data/app/com.hkyc.shouxinteacher.ischool-2/lib/arm64, /vendor/lib64, /system/lib64]]] couldn't find "libgnustl_shared.so"
at java.lang.Runtime.loadLibrary(Runtime.java:366)
at java.lang.System.loadLibrary(System.java:988)
at com.idtechinfo.shouxiner.App.onCreate(App.java:92)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1012)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4580)
at android.app.ActivityThread.access$1500(ActivityThread.java:154)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1376)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5283)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
好吧,真真令人头疼,楼主采用了各种解决方式都没有解决,因为android studio默认是会把所有ABI支持都打包到apk的,由于楼主得到的第三方SDK并不全面,所以遇上这样的奇葩问题也是难免。
那么,到底如何解决呢?
楼主通过网上提供的一些解决办法说,可以在gradle中添加配置如下:
android {
...
splits {
abi {
enable true
reset()
include 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' //select ABIs to build APKs for
universalApk true //generate an additional APK that contains all the ABIs
}
}
// map for the version code
project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]
android.applicationVariants.all { variant ->
// assign different version code for each output
variant.outputs.each { output ->
output.versionCodeOverride =
project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI), 0) * 1000000 + android.defaultConfig.versionCode
}
}
}
可事实是:找不到包名!!到底什么鬼?
楼主在各种碰壁后,希望大家不要再在这种低级问题上碰的头破血流,楼主的解决方案是通过build.gradle设置让apk打包只打包armeabi包下的.so文件,
添加代码为:
android{
.......
defaultConfig {
ndk {
abiFilters 'armeabi'
}
}
}
当然,这样虽然投机取巧在aremabi下的可以支持所有的CPU机型,但是无疑使用不到各种机型特定的性能优化,为了让其不会闪退,楼主也只能暂时采用此类方法。如果大家有更好的方法,也希望能在评论区共享,谢谢。
转载请在醒目位置附上本文链接:http://www.cnblogs.com/liushilin/p/5792505.html
2017-03-06补充
如果你作这样的更改后依然不行的话,可能是你的.so文件采用了较低版本的SDK编译,此时通常可以将targetSdkVersion设置为22就可以解决了,如果还是不能解决,可以尝试继续降低targetSdkVersion的版本。
另外,楼主在后面专门更新了.so文件库的解读,可以去看看:【开发必备】今天我们来谈谈Android NDK动态链接库(so文件)的一些见解
【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案的更多相关文章
- VS C# xamarin 开发android 调试正常 发布分发后运行闪退出错
我强烈推荐大家如果不是很有必要就不要引用一些.NET STD的库,比如json库newtonsoft.JSON,直接引用官方的system.Json就足够了,否则会导致体积变得巨大 好了废话不多说,这 ...
- Android Studio通过JNI调用NDK程序
NDK开发,其实是为了项目需要调用底层的一些C/C++的一些东西:另外就是为了效率更加高些,安全性更高. 如果你在Eclipse+ADT下开发过NDK就能体会到要么是配置NDK还要下载Cygwin,配 ...
- Android studio 下JNI编程实例并生成so库
Android studio 下JNI编程实例并生成so库 因为公司需要为Android相机做美颜等图像后期处理,需要使用JNI编程,最近学了下JNI,并且在Android Studio下实现了一个小 ...
- Android studio 配置JNI环境
Android studio配置jni开发环境,主要配置是两个build文件,以及新建一个jni文件,放c代码. 代码如下1: apply plugin: 'com.android.model.app ...
- Android Studio 编写 JNI
之前一直都不知怎么编写JNI,今天刚好学习一下,感谢梦真的指教,以及提供的文档. 参考链接 http://blog.csdn.net/u011168565/article/details/518781 ...
- 呕心沥血Android studio使用JNI实例
发现网上很多JNI的使用教程,也很详细,不过有的地方有些缺漏,导致很多小问题难以解决的,今天就来总结一下. 准备工作:下载NDK. 简单的说,要用到C/C++,就要用NDK.直接百度搜索然后去官网下载 ...
- Android图片加载库的理解
前言 这是“基础自测”系列的第三篇文章,以Android开发需要熟悉的20个技术点为切入点,本篇重点讲讲Android中的ImageLoader这个库的一些理解,在Android上最让人头疼是 ...
- Android图片加载库:最全面的Picasso讲解
前言 上文已经对当今 Android主流的图片加载库 进行了全面介绍 & 对比 如果你还没阅读,我建议你先移步这里阅读 今天我们来学习其中一个Android主流的图片加载库的使用 - Pica ...
- fackbook的Fresco (FaceBook推出的Android图片加载库-Fresco)
[Android开发经验]FaceBook推出的Android图片加载库-Fresco 欢迎关注ndroid-tech-frontier开源项目,定期翻译国外Android优质的技术.开源库.软件 ...
随机推荐
- 读书笔记:《HTML5开发手册》--HTML5新的结构元素
读书笔记:<HTML5开发手册> (HTML5 Developer's CookBook) 虽然从事前端开发已有很长一段时间,对HTML5标签也有使用,但在语义化上面理解还不够清晰.之前在 ...
- C# 中参数验证方式的演变
一般在写方法的时候,第一步就是进行参数验证,这也体现了编码者的细心和缜密,但是在很多时候这个过程很枯燥和乏味,比如在拿到一个API设计文档的时候,通常会规定类型参数是否允许为空,如果是字符可能有长度限 ...
- 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一)
相关连接导航 在windows下安装gulp —— 基于 Gulp 的前端集成解决方案(一) 执行 $Gulp 时发生了什么 —— 基于 Gulp 的前端集成解决方案(二) 常用 Gulp 插件汇总 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(76)-微信公众平台开发-网页授权
前言 网页授权是:应用或者网站请求你用你的微信帐号登录,同意之后第三方应用可以获取你的个人信息 网上说了一大堆参数,实际很难理解和猜透,我们以实际的代码来演示比较通俗易懂 配置 实现之前我们必须配置用 ...
- FragmentTabHost的基本用法
开通博客以来已经约莫1个月了.几次想提笔写写东西,但总是由于各种各样的原因并没有开始.现在,年假刚结束,项目也还没有开始,但最终促使我写这篇博客的是,看了一篇博友写的新年计划,说是要在新的一年中写50 ...
- 一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
在目前的软件项目中,都会较多的使用到对文档的操作,用于记录和统计相关业务信息.由于系统自身提供了对文档的相关操作,所以在一定程度上极大的简化了软件使用者的工作量. 在.NET项目中如果用户提出了相关文 ...
- 云瓣影音网站&&微信端(已开源)
随着该项目的发布到线上(小打小闹),即将又要开启另一段崭新的旅程.强迫自己停下来写写所学所得,个人认为总结和分享是一种很棒的学习方式.那让我们先来瞧瞧项目长的什么样.如果着急要源码的朋友,可以下拉到最 ...
- Web安全相关(五):SQL注入(SQL Injection)
简介 SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据 ...
- JAVA的内存模型(变量的同步)
一个线程中变量的修改可能不会立即对其他线程可见,事实上也许永远不可见. 在代码一中,如果一个线程调用了MyClass.loop(),将来的某个时间点,另一个线程调用了MyClass.setValue( ...
- iOS - 模态Model视图跳转和Push视图跳转的混合需求实现原理
在研发中总会遇到一些莫名的需求,本着存在即合理的态度跟大家分享一下"模态Model视图跳转和Push视图跳转的需求实现",本文仅仅传授研发技术不传授产品以及UE的思想,请大家合理对 ...