flutter 编译报错总结(不断更新)
1、Cannot fit requested classes in a single dex file#
问题
Cannot fit requested classes in a single dex file (# methods: 66370 > 65536)
原因分析
主要原因是你的项目貌似有点大,已经超过 65k 个方法。一个 dex 已经装不下了,需要个多个 dex,也就是 multidex ,因为 Android 系统定义总方法数是一个 short int,short int 最大值为 65536。
解决方案
- 在 app module 中的 build.gradle 中添加依赖
implementation 'com.android.support:multidex:1.0.3' // dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' //添加到此处 implementation 'com.android.support:multidex:1.0.3' }
- 在 app module 中的 build.gradle 中的 defaultConfig 中添加以下代码
android { compileSdkVersion 28 defaultConfig { applicationId "com.example.demo" minSdkVersion 16 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" //添加到此处 multiDexEnabled true } }
2、Flutter 在 profile 和 release 模式下的白屏问题#
import 'dart:ui';//window需要import ui库
void main(){
//如果size是0,则设置回调,在回调中runApp
if(window.physicalSize.isEmpty){
window.onMetricsChanged = (){
//在回调中,size仍然有可能是0
if(!window.physicalSize.isEmpty){
window.onMetricsChanged = null;
runApp(MyApp());
}
};
} else{
//如果size非0,则直接runApp
runApp(MyApp());
}
}
分析#
这段代码里有两个东西需要了解一下的,第一个是 window.onMetricsChanged
,源码的注释是这样写的
/// A callback that is invoked whenever the [devicePixelRatio],\
/// [physicalSize], [padding], or [viewInsets] values change, for example\
/// when the device is rotated or when the application is resized (e.g. when\
/// showing applications side-by-side on Android).
也就是当 devicePixelRatio、physicalSize、padding、viewInsets
这几个东西变化时会触发的回调,其中屏幕大小就是 physicalSize
第二个是 physicalSize
,上面说了这个是屏幕大小,但是它一开始是 0*0,直到 Flutter 初始化时将它赋值为屏幕大小才能获取到非 0 的值
好了,说完了上面两个东西,就来说说问题。问题的坑点在于,mian()
方法并不是在 Flutter 给 physicalSize
赋值后才运行的,两者并没有固定的先后顺序,从测试来看,跟设备的性能有关
之前的错误解法#
之前是下面这样写的,然后在新 ipad air 的 profile 模式下以及所有机型的 debug 模式下都会白屏,只有比较旧的 mini4 不会白屏
void main(){
window.onMetricsChanged = (){
runApp(MyApp());
window.onMetricsChanged = null;
};
}
经排查,发现原因是 mini 够慢,在设置了 onMetricsChanged 回调后 flutter 还没有读取到屏幕 size,也就还没出触发 onMetricsChanged。
然而在新 air 上,则是几率性的,有时和 mini 一样,有时在设置 onMetricsChanged 之前 flutter 就已经读取了屏幕 size 了,所以后面一段时间都不会触发 onMetricsChanged,导致白屏。更奇怪的是,有时设置的 onMetricsChanged 倍触发后,仍然是白屏,排查后发现 air 上不止一次 resize,而只有最后一次非 0。
所以完整的代码中有这一段保护:
window.onMetricsChanged = (){
//这里仍然有可能是0
if(!window.physicalSize.isEmpty){
window.onMetricsChanged = null;
runApp(MyApp());
}
};
链接:https://www.jianshu.com/p/4f0651241956\
本作品采用《CC 协议》,转载必须注明作者和本文链接