Flutter github#5259是一樣的問題
二話不說肠仪,先上代碼肖抱,下面這樣可以解決問題
void main(){
runApp(MyApp());
}
改為
import 'dart:ui';//window需要import ui庫
void main(){
//如果size是0,則設(shè)置回調(diào)异旧,在回調(diào)中runApp
if(window.physicalSize.isEmpty){
window.onMetricsChanged = (){
//在回調(diào)中意述,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).
也就是當(dāng)devicePixelRatio、physicalSize匹涮、padding天试、viewInsets
這幾個東西變化時會觸發(fā)的回調(diào),其中屏幕大小就是physicalSize
第二個是physicalSize
然低,上面說了這個是屏幕大小喜每,但是它一開始是0*0,直到Flutter初始化時將它賦值為屏幕大小才能獲取到非0的值
好了雳攘,說完了上面兩個東西带兜,就來說說問題。問題的坑點在于吨灭,mian()
方法并不是在Flutter給physicalSize
賦值后才運行的刚照,兩者并沒有固定的先后順序,從測試來看喧兄,跟設(shè)備的性能有關(guān)
之前的錯誤解法
之前是下面這樣寫的无畔,然后在新ipad air的profile模式下以及所有機型的debug模式下都會白屏啊楚,只有比較舊的mini4不會白屏
void main(){
window.onMetricsChanged = (){
runApp(MyApp());
window.onMetricsChanged = null;
};
}
經(jīng)排查,發(fā)現(xiàn)原因是mini夠慢浑彰,在設(shè)置了onMetricsChanged回調(diào)后flutter還沒有讀取到屏幕size恭理,也就還沒出觸發(fā)onMetricsChanged。
然而在新air上郭变,則是幾率性的颜价,有時和mini一樣,有時在設(shè)置onMetricsChanged之前flutter就已經(jīng)讀取了屏幕size了诉濒,所以后面一段時間都不會觸發(fā)onMetricsChanged周伦,導(dǎo)致白屏。更奇怪的是循诉,有時設(shè)置的onMetricsChanged倍觸發(fā)后横辆,仍然是白屏,排查后發(fā)現(xiàn)air上不止一次resize茄猫,而只有最后一次非0狈蚤。
所以完整的代碼中有這一段保護(hù):
window.onMetricsChanged = (){
//這里仍然有可能是0
if(!window.physicalSize.isEmpty){
window.onMetricsChanged = null;
runApp(MyApp());
}
};
更多
Flutter設(shè)計成這樣目的應(yīng)該是想加快應(yīng)用啟動速度,不用等size賦值划纽。這樣的話0*0的問題就要開發(fā)者自己去考慮了脆侮,按照上面的代碼,可能會導(dǎo)致應(yīng)用啟動速度稍微慢一丟丟勇劣,單可以通過一些辦法例如加一個固定大小的閃屏頁來彌補上面解法的不足