1. 第三方native library无法加载

由于我们的 flutter 应用中要集成第三方的 sdk 来实现一些特殊功能,该 sdk 中集成了一些 native library ,而且只有 32位 的。目前在 flutterandroid 工程中添加了这些 library , 如下图所示:

随后在 android 工程的 build.gradle 文件中手动指定 jniLibs 目录的路径,如下图所示:

现在正常在 flutter 工程中执行 debug 启动工程,如下图所示:

点击界面按钮,调用第三方 native library 后立马出现报错,随后 App 闪退。报错内容如下:

通过日志可以看出来,我们前面添加的 native library 没有被加载。

当时首先怀疑的是打包时是否将 native library 有打包到 apk 中,所以采用 android studioanalyze apk 命令分析,发现确实是已经打包到 apk 文件中了。如下图所示:

仔细回顾上面的日志,不难发现,没有被加载的原因是因为它寻找 library 的路径不对,根本没有包含我们需要的 armeabi-v7a 这个目录。如下图所示,加载的路径基本上都是 arm64 相关的目录,很显然是因为我的真机是 arm64 架构的,所以可能导致这个问题。

关于这个问题,在文章 https://medium.com/codechai/flutter-app-couldnt-find-libflutter-so-c95ad81cbccd 中有详细的说明。大体情况如下:

当apk安装时,首先会标记当前应用是32位的还是64位的,这决定了后面在哪个目录寻找本地库。

  1. 首先在 lib/arm64-v8a 目录中寻找是否有 native libraray,如果有就标记为 64位 。(在上面的情况中,arm64-v8a文件夹中是包含有 libflutter.so 的,所以该应用被标记为 64 位)
  2. 如果没有在 lib/arm64-v8a 中找到 native libraray,则随后在 lib/armeabi-v7alib/armeabi 中寻找,有则标记为 32位
  3. 如果在上述目录中都没有找到 native library 则说明当前应用没有使用本地库,对 32 位还是 64位 并不敏感。此时会默认标记为 64位

此时可以在网上找到的大多数回答是在 build.gradle 文件中指定 ndkabiFilter ,如下图所示:

这个配置的意思是指定一个 filter ,让 Gradle 在打包 apk 时只添加 armeabi-v7a 下的 library ,其它的都不添加。
根据上面的寻找 library 的规则,这么做确实只保证 armeabi-v7a 的库被加载到。

添加这项配置后,再继续执行 debug ,又抛出了 couldn't find "libflutter.so" 这个报错信息。详细内容如下所示:

E/FlutterLoader( 8399): java.util.concurrent.ExecutionException: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.dm.pcbd-A-gAqiQOV9EjRIg7TZRvKw==/base.apk"],nativeLibraryDirectories=[/data/app/com.dm.pcbd-A-gAqiQOV9EjRIg7TZRvKw==/lib/arm, /data/app/com.dm.pcbd-A-gAqiQOV9EjRIg7TZRvKw==/base.apk!/lib/armeabi-v7a, /system/lib, /product/lib]]] couldn't find "libflutter.so"

采用 analyze apk 查看了下生成的 apk 包,发现确实没有将 libflutter.so 打包到 apk 中,如下图所示:

翻了 flutter 的很多 issue 后发现有很多类似的问题,例如这个 issue https://github.com/flutter/flutter/issues/29710

2. debug下 libflutter.so 无法加载

根据 issue https://github.com/flutter/flutter/issues/29710 的描述,只要 armeabi-v7a 下添加了其它库,就会出现 libflutter.so 打包不进去的问题。

经过多次尝试后,发现使用 flutter build 命令行生成出来的包中是有 libflutter.so 的,具体命令如下:

// 生成debug包
flutter build apk --debug// 生成release包
flutter build apk --release// 安装软件包(在生成debug或release包之后运行)
flutter install

build 生成的 debug 包中包含 libflutter.so

build 生成的 release 包中也包含 libflutter.so

但是直接使用 Android Studio 上的 debug 运行时就是不打包 libflutter.soarmeabi-v7a 中。

Android Studio 上的 debug 等同于命令行 flutter run --debug -v

说实话,到这一步时觉得 flutter 还是不太成熟,差点想弃坑了。

仔细翻阅了 https://github.com/flutter/flutter/issues/29710 这个issue,发现有网友提到命令行手动指定 target-platform 来强制指定目标平台为 arm 32位,例如:

flutter build apk --debug --target-platform=android-arm
flutter run --use-application-binary=build/app/outputs/apk/debug/app-debug.apk

但是 target-platform 这个参数在新版本的 flutter 中不能直接用在 flutter run 上(即上述的 debug 上),只能用在 flutter build 上。那这就导致平常调试时很不方便了,不能直接按 debug 按钮启动启用,得用命令行手动启动,太不方便了。

在上面的 issue 中,又有网友提到直接在 gradle 中配置 target-platform 。具体是在 settings.gradle 文件中添加配置,如下所示:

具体添加的代码如下:

gradle.beforeProject({ project->if (project.hasProperty("target-platform") && !project.getProperty("target-platform").split(",").contains("android-arm")) {project.setProperty("target-platform", "android-arm")}
})

添加这段配置后,就可以 正常使用 界面上的 debug 按钮了,其生成的 apk 包中 armeabi-v7a 文件夹下确实是包含了 libflutter.so

3. Release下出现闪退问题

上面解决 debug 正常后,为了看下 release 下的效果,随即用命令行 flutter build apk --release 生成了 release 包,安装后点击按钮访问第三方sdk内容时出现闪退。

这就出现了 release 下和 debug 下行为不一致的问题

这种直接安装 apk 的方式,出现闪退或报错等问题,在 Android Studio 中看不到任何日志,非常不利于问题的排查。

这里可以采用 flutter run --release -v 的方式来启动 release 包,这样在控制台至少可以看到一些日志。flutter run --release -v 在界面上也可以配置出来,如下图所示:

再点击界面上的 Rundebug 按钮就可以启动这个 release 包了。(此时 debug 或 Run 按钮不影响运行方式)

通过这种方式运行后,得到 Release包闪退 的报错信息如下:

E/AndroidRuntime(22800): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dm.pcbd/com.micropattern.sdk.ext.MPFaceQualityDetectActivity}: android.content.res.Resources$NotFoundException: Resource ID #0x0
E/AndroidRuntime(22800):    at .................省略一些无关的日志
E/AndroidRuntime(22800): Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x0
E/AndroidRuntime(22800):    at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:292)
E/AndroidRuntime(22800):    at android.content.res.Resources.loadXmlResourceParser(Resources.java:2390)
........... 省略一些无关的日志
com.android.internal.policy.HwPhoneWindow.setContentView(HwPhoneWindow.java:342)
E/AndroidRuntime(22800):    at android.app.Activity.setContentView(Activity.java:2941)
E/AndroidRuntime(22800):    at com.micropattern.sdk.ext.MPFaceQualityDetectActivity.onCreate(Unknown Source:36)
E/AndroidRuntime(22800):    at android.app.Activity.performCreate(Activity.java:7458)
E/AndroidRuntime(22800):    at android.app.Activity.performCreate(Activity.java:7448)
E/AndroidRuntime(22800):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
E/AndroidRuntime(22800):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409)
E/AndroidRuntime(22800):    ... 11 more

出现这个问题,猜测是release打包时 shrink 压缩导致的问题。首先考虑到可能是 flutter官方文档中提到的 Shrinking your code with R8 导致的问题,遂在命令行打包时尝试关闭 shrinking ,命令如下所示:

flutter build apk --release --no-shrink

不过这个包打出来后,还是存在上面的资源问题。

上面那个是 android 中获取资源的问题,那么有可能是 Gradle 打包时出现的问题,所以考虑应该直接在 Gradle 中关闭 shrink 。具体操作如下,在 build.gradle 中添加如下配置

关于shrink,官方文档中有详细介绍: https://developer.android.com/studio/build/shrink-code?utm_source=android-studio#shrink-resources

到这里,再 Release 后就可以正常使用本地库了。

4. 总结

解决这个问题耗了一整天,基于上都是停留在各种尝试中。经过这一番折腾,确实了解到 flutter 这个坑有些大…

  • 第一次为了解决 libflutter.so 无法加载的问题,甚至尝试过手动将 libflutter.so 拷贝到 armeabi-v7a 文件夹下。这样确实解决了 debug 下的问题,但是最后做出来的 release 包一直卡在空白界面。在这里浪费了很多时间。
  • 目前 flutter 并不是特别成熟,关于这个问题在 issue 中说法有很多,这也导致了各种尝试,花费了很多时间。

经过这次折腾,也确实了解到了很多东西,例如:

  • ndk abiFilter 配置
  • 对 native library 加载机制有些许了解
  • flutter工程和android工程的关系也终于弄明白了一些

5. 关于作者

作者是一个热爱学习、开源、分享,传播正能量,头发还很多的程序员-。-
热烈欢迎大家关注、点赞、评论交流!

  • csdn: https://blog.csdn.net/u010920692
  • 掘金: https://juejin.cn/user/3237392838298663
  • 博客园: https://www.cnblogs.com/zhangzhxb/

Flutter 添加 armeabi-v7a 本地库出现的一些问题相关推荐

  1. Flutter 添加APP启动 Story View

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5HxSK6LS-1620177370066)(https://ducafecat.tech/2021/05/05/tra ...

  2. Flutter 添加页面渲染完毕回调

    WidgetsBinding.instance.addPostFrameCallback((mag) {print(" 页面渲染完毕"); });

  3. Flutter开发之搭建Flutter开发环境(三)

    回首demo.之前的工程突然,无法iOS上运行了.重装了最新的Xcode.然后VS Code 终端运行 flutter packages get 再打开Xcode 设置开发证书.再在iOS真机或者模拟 ...

  4. 浅谈跨平台框架 Flutter 的优势与结构

    作者:个推iOS工程师 伊泽瑞尔 一.背景 目前,移动开发技术主要分为原生开发和跨平台开发两种.其中,原生应用是指在某个特定的移动平台上,使用平台所支持的开发工具和语言,直接调用系统提供的API所开发 ...

  5. Flutter - International 国际化,Localization 本地化, 使用Intl

    新建项目,得到一个示例工程.本例中使用intl包来管理文字资源. 项目地址: https://github.com/RustFisher/localization_demo 步骤: 添加依赖项 - i ...

  6. VS Code 集成 flutter dart 开发

    一.关于Flutter Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面. Flutter可以与现有的代码一起工作.在全世界,Flutter正在被越来越多 ...

  7. Google 要用 Flutter 一统移动、桌面开发江湖?

    "Flutter 的核心是一个独立的可执行二进制文件,所以它不仅能改变移动开发的世界,也能改变桌面开发的世界.你只需编写一次代码,就可以在 Android.iOS.Windows.Mac 和 ...

  8. flutter屏幕适配

    现在的手机品牌和型号越来越多,导致我们平时写布局的时候会在个不同的移动设备上显示的效果不同, 比如我们的设计稿一个View的大小是300px,如果直接写300px,可能在当前设备显示正常,但到了其他设 ...

  9. Flutter 1.17版本重磅发布

    Flutter 1.17 是2020年的第一个稳定版本,此版本包括iOS平台Metal支持(性能更快),新的Material组件,新的Network跟踪工具等等! 对所有人来说,今年是充满挑战的一年. ...

  10. Flutter Web 支持现已进入稳定版

    作者 / Mariam Hasnany, Product Manager, Flutter 我们对 Flutter 的愿景是成为一个可移植的 UI 框架,在全平台上构建精美的应用体验.做为 Flutt ...

最新文章

  1. TF 2.1.0-rc2发布,2020年停止支持Python 2
  2. 网络游戏性能测试的几点想法
  3. HttpMessageConverter转换类型
  4. VSS 2005 客户端和服务器端配置总结
  5. Struts2 注解中跳转 action
  6. git中fatal: Authentication failed的问题
  7. shell中的比较(if运算)
  8. java创建临时文件夹_java创建临时文件
  9. 【算法分析与设计】查找第K大/小元素问题
  10. Java 游戏报错 看不懂求教
  11. Python实现好友信息管理系统 添加、删除、修改、备注、查询好友信息
  12. 3.7V转5V电路图芯片,3.7V升压5V的升压芯片
  13. java开源图像处理ku_我是这么设计高性能海量数(ku)据(zi)查询系统的(一)
  14. HCI_Inquiry
  15. 自己封装特定的Windows系统镜像
  16. SpringSecurity,jwt oathu sso,YeZiJie
  17. python手机壁纸高清_python爬取手机壁纸
  18. 计算第n个素数到第m个素数之间所有的素数的和,包括第n个素数和第m个素数
  19. 大数据项目实施风险(一)
  20. 让Python学起来更轻松 | 寻找C站宝藏

热门文章

  1. 必看的经典金融书籍推荐zz
  2. PHP调用MYSQL存储过程实例
  3. 软件设计师考试大纲(2004版)
  4. Android 打开URL
  5. 推荐:学习人工智能(AI)的一些网站及教程资源
  6. wap网站制作教程,Github标星5.3K
  7. 悲催的一下午:怎么删除360。。。
  8. android无法解码avcmp4,android - Android中的MediaCodec编码的H.264 avc视频无法播放 - 堆栈内存溢出...
  9. spss因子分析结果解读_SPSS统计结果P=0.000,我该如何解读呢?
  10. multisim中pwl_(Multisim电子电路仿真教程)第3章Multisim仿真元件库与虚拟仪器.ppt