【ReactNative】关于32位和64位SO库混合引入Crash解决方案


问题描述

  现有项目集成ReactNative后,在你的个别测试机上运行成功,只是踏入RN大门的第一步,对于已经进入稳定迭代期的产品,集成后需要对各种机型进行测试,保证原有逻辑的基础上,去验证会不会由于集成RN引发新的问题。
  很幸运的是,当使用Smartisan M1测试我的项目时,出现如下的Crash信息。

java.lang.UnsatisfiedLinkError: dlopen failed: "xxx/libgnustl_shared.so" is 32-bit instead of 64-bit

  在解决问题的过程中,有同学也遇到的了如下的问题,和上述的Crash,属于同一原因导致,也可以用下面将会介绍的方法解决。

java.lang.UnsatisfiedLinkError: could find DSO to load: libreactnativejni.so

思路分析

  上面的两种Error,反馈给我们的信息就是当程序要使用相应的so库时,在当前installed apk中并没有找到。为什么没有找到?另外还不是必现的问题,只是在个别的手机上会出现。好的,准备好和慧兄一起来分析这个问题。

Native Libs Monitor

  首先,推荐一个神器,名称Native Libs Monitor是一款手机App下载地址,也可以在国内应用市场下载。她是一个本地库监视器,可以查看应用信息、应用直接添加的so库,应用使用的依赖库中添加的so。省去解包的过程,并且能够帮助分析问题,以我的App为例进行分析。

Crash出现时SO库情况展示

上图是当Crash出现的时候,使用Native Libs Monitor分析的本地库的包含情况。

Native Libraries inside APK:APK内部应该包含的所有so库的展示列表
Native Libraries installed : 安装包的Libs目录下,包含的so库。

  上图中可以明显看出,标示为2的区域,成功打入到安装包Libs目录下的so库只有libimagepipeline.so。这里留下一个疑问,为什么会出现这种情况?
正常区域2和区域3的so库应该是相同的,这样程序才能正常运行,如同优酷APK的分析结果。

优酷的so库结果

使用的所有依赖库,都会成批打入到APK的Libs文件夹下。

手机ABI/CPU型号

  上面的问题,我们先预留,然后分享一条命令用来查看手机的ABI/CPU型号。

adb shell  cat /system/build.prop | grep “product”

Smartisan M1手机上执行命令的结果如下:

锤子ABI型号

OK,可以看到

ro.product.cpu.abilist64=arm64-v8a
ro.product.cpu.abilist32=armeabi-v7a,armeabi

小结论

  通过上面的分析,可以预测一个结论:
  Android不能同时加载32和64位本机库。 如果您至少有一个依赖库使用ARM64支持编译的扩展,而另外一些依赖库仅支持ARM32,就会出现问题。 系统将检测ARM64依赖关系,加载它,然后拒绝加载仅ARM32的so库,就可能导致应用程序崩溃。
  项目中只有libimagepipeline.soarm64-v8a支持编译的扩展,Smartisan M1手机发现有64位的本机库,就不会再去加载32位的本机库,所以在Native Libraries installed区就只能看到libimagepipeline.so一个so库。也因此会报我们开篇提到的两个缺省so库的Error,也因此回复了为什么只有一个so库的问题。


解决方案

  既然找到了问题所在,就好解决了,两种方案。

第一种方案

所有引入的第三方依赖库,都需要提供arm64-v8a型号的支持。目前这种比较难以实现。

第二种方案

在project的root目录下的build.gradle中添加如下代码。

defaultConfig {
        minSdkVersion 16
        targetSdkVersion 21
        ndk{
            abiFilters "armeabi-v7a","x86"
        }
        packagingOptions {
            exclude "lib/arm64-v8a/libimagepipeline.so"
        }
    }

注:需要exclude的so库,是项目中arm64-v8a文件夹中的,例如通过上面的分析,我的项目中64位支持的是libimagepipeline.so,所以通过如上代码进行编译排除。

OK,问题解决。如果你发现文章中有表示不准确的地方,欢迎留言指正,3Q。

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Android原生崩溃(android native crash)是指在Android平台上,由于代码执行错误或者资源耗尽等原因,导致应用程序无法正常运行而崩溃或者闪退的现象。原生崩溃产生的原因可能是由于C或者C++代码编写错误、内存溢出、线程竞争等。针对原生崩溃问题,开发人员需要使用调试工具进行定位和修复。 ### 回答2: Android Native Crash发生在安卓应用程序运行时,由于C或C++的错误或者其他原因导致应用程序崩溃。有时候Native Crash可能会影响整个设备,尤其是当Native Crash发生在系统级别的代码中时。 产生Native Crash的原因通常包括以下几个方面: 1. 内存管理问题:Native Crash通常与内存管理问题相关,这可能是由于访问未初始化的内存,使用错误的指针或释放已释放的内存等原因引起的。 2. 硬件问题:Native Crash也可能与设备相关的硬件问题有关,例如访问不可用的硬件资源或硬件设备故障。 3. 应用程序代码问题:Native Crash可能发生在应用程序代码的错误、资源泄漏、堆栈溢出等问题引起的。 4. 第三方问题:Native Crash也可能由第三方中的错误或bug引起。这些可能没有经过充分的测试,或者与设备硬件不兼容。 为了更好地解决Native Crash问题,开发者可以通过日志或崩溃报告(Crash Report)来检测和分析崩溃日志,并查看堆栈跟踪信息来确定导致Native Crash的来源。在开发过程中,经常使用除了自己编写的代码之外的第三方时,还可以考虑使用崩溃的回溯工具,如Firebase Crashlytics等。 总之,Native Crash是Android应用程序开发过程中经常遇到的问题,它可能会对用户体验和开发进度产生重大影响,因此开发者需要强化对Native Crash的理解和分析能力,以更好地解决Native Crash的问题。 ### 回答3: Android Native Crash,指的是在 Android 系统中发生的本地崩溃。本地崩溃是指应用程序使用本地代码,而不是 Java 代码,导致应用程序崩溃的问题。本地代码可以是编写在 C/C++ 等语言中的,或是应用程序本身所编写的 Native 代码。 本地代码崩溃后,会在应用程序崩溃的同时发生。本地崩溃可发生在 Android 应用程序中的任何部分,比如,应用程序本地、Android 系统等等。大多数情况下,本地崩溃是由于访问无效内存、访问不合法指针、数组越界等问题引起的。 为了解决本地崩溃问题,Android 提供了一些工具和技术。比如,使用 ndk-stack 工具可以解析本地崩溃日志。Android Studio 也提供了一些工具来分析应用程序崩溃的原因。同时,我们也可以在应用程序中添加自定义的日志跟踪信息,以便更好地了解应用程序的崩溃原因。 还有一些其他的技术可以使用,如使用 Google 的 Crashlytics 来跟踪应用程序的崩溃问题。这个平台可以帮助开发者收集和分析应用程序在用户设备上的崩溃信息,并彻底解决这些问题。此外,Android 还提供了一些实用工具和技术,如 ANR(Application Not Responding)错误处理器、Tracer for OpenGL ES 和 Traceview 示例等。 总之,Android Native Crash 是 Android 系统中常见的崩溃问题之一。了解它的原因并采用适当的解决方案可以使得我们更好地保持我们的应用程序的稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值