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 协议》,转载必须注明作者和本文链接