最近学习 Flutter,遇到的问题记录一下
开发 Flutter 版本的产品时,在集成阿里云播放器之后一直正常开发。结果发现打了 Release 的包之后,在进入到播放器页面时,App 会直接 Crash。
Flutter 的报错信息也不是很明显。
JNI DETECTED ERROR IN APPLICATION: java_class == null
in call to GetFieldID
from java.lang.String java.lang.Runtime.nativeLoad(java.lang.String, java.lang.ClassLoader, java.lang.Class)
Runtime aborting…
Dumping all threads without mutator lock held
说是 JNI 调用返回了 null,但是我想着也没动过这一层。
刚开始按照堆栈信息研究了半天,一直没有结果。就我一个移动端,没有大佬带的菜鸡。难受
后来仔细想了一下,这种 debug 正常,release Crash 的问题,应该跟配置有关系,然后根据配置分别排查。
1. 签名问题 (失败)
首先考虑到的是签名问题,release 和 debug 签名不同,因为没有创建 release 的签名。flutter 默认会使用 debug 的签名。
创建 release 签名, 重新设置。失败
2. 版本问题 (失败)
由于是 Flutter 项目,很多东西不会提示,例如 gradle。所以在 Android Studio 界面以 Android 项目打开。
检查了阿里云播放器的版本。项目的 Gradle Plugin 版本。修改后重试。仍然失败。
但是得到了一个相对有用的信息,在更改 Gradle 版本的时候,有提示说 AliPlayer 的 Gradle 在 5.0 之后不再禁止 R8。突然就想到了混淆压缩
3. 混淆压缩 (成功)
第一个 Flutter 项目,根本没有去混淆代码,刚开始也没有考虑到这个方面。
后来突然想到之前在 Android 开发者上看到 Google 分享的文章,关于 R8 压缩的详解。又查询到 release 版本是默认开启 R8 压缩的。
然后就在 build.gradle 中修改配置
buildTypes {
release {
minifyEnabled false
shrinkResources false
signingConfig signingConfigs.release
}
}
使用 Flutter 的 build apk 功能重试,但是还是不行。就很奇怪,明明关闭了压缩和移除无用资源。
万万没想到。我用命令 flutter build apk --release 编译了 release 的包。成功了。后来重试,发现应该是缓存的问题。
至此,该问题就解决了。就因为不够仔细,花费了我两天的时间。留下了没有知识的泪水。