一吞杭、flutter與原生通信龟虎,三種通道的區(qū)別
1.1 MethodChannel
Flutter與Native端相互調用河爹,調用后返回結果
可以Native端主動調用匠璧,也可以Flutter主動調用,屬于雙向通信
此種方式最為常見咸这,Native端調用需要在主線程中執(zhí)行
1.2 BasicMessageChannel
用于使用指定的編解碼器對消息進行編碼和解碼
屬于雙向通信夷恍,可以以Native端主動調用,也可以Flutter主動調用
1.3 EventChannel
用于數(shù)據(jù)流(event stream)的通信媳维,Native端主動發(fā)送數(shù)據(jù)給Flutter
通常用于狀態(tài)端監(jiān)聽酿雪,比如網(wǎng)絡變化、傳感器數(shù)據(jù)等
原文鏈接:https://blog.csdn.net/Calvin_zhou/article/details/118888030
二侄刽、flutter自定義組件指黎,生命周期
Flutter的生命周期包含一下幾個階段:
CreateState 該函數(shù)為StatefulWidget創(chuàng)建State時調用的方法,當StatefulWidget被調用時候會立即調用此方法州丹。
initState 該方法為State初始化調用醋安,因此在此期間可以執(zhí)行變量的初始化,還可以進行與服務端的初始化墓毒,獲取到服務端數(shù)據(jù)之后調用setState方法更新組件茬故。
didChangeDependencies 該函數(shù)是在該組件依賴的全局State發(fā)生變化的時候調用。
build 該函數(shù)主要是渲染W(wǎng)idget蚁鳖,會被調用多次磺芭,最好只做返回Widget相關的事情。
reassemble 只要是提供開發(fā)階段使用醉箕,只有在debug模式下熱重載才會調用钾腺。可以添加一些代碼來調試讥裤。
didUpdateWidget 此方法在組件重新構建放棒,比如熱更新,父組件發(fā)生Build時候調用此方法己英,其次此方法會導致本組件的build方法被調用间螟。
deactivate 在組件被移除時候調用,如果組件被移除损肛,未被插入到其他組件厢破。那么會調用dispose永久移除。
1治拿、initState
調用次數(shù):1次
插入渲染樹時調用摩泪,只調用一次,widget創(chuàng)建執(zhí)行的第一個方法劫谅,這里可以做一些初始化工作见坑,比如初始化State的變量嚷掠。
2、didChangeDependencies
調用次數(shù):多次
初始化時荞驴,在initState()之后立刻調用
當依賴的InheritedWidget rebuild,會觸發(fā)此接口被調用
實測在組件可見狀態(tài)變化的時候會調用
3不皆、build
調用次數(shù):多次
初始化之后開始繪制界面
setState觸發(fā)的時候會
4、didUpdateWidget
調用次數(shù):多次
組件狀態(tài)改變時候調用
5熊楼、deactivate
當State對象從樹中被移除時霹娄,會調用此回調,會在dispose之前調用孙蒙。
頁面銷毀的時候會依次執(zhí)行:deactivate > dispose
6项棠、dispose
調用次數(shù):1次
當State對象從樹中被永久移除時調用悲雳;通常在此回調中釋放資源挎峦。
7、reassemble
在熱重載(hot reload)時會被調用合瓢,此回調在Release模式下永遠不會被調用
原文鏈接:https://blog.csdn.net/yoonerloop/article/details/121003373
1.WidgetsBindingObserver
和App生命周期有關AppLifecycleState
1坦胶、resumed
可見并能響應用戶的輸入,同安卓的onResume
2晴楔、inactive
處在并不活動狀態(tài)顿苇,無法處理用戶響應,同安卓的onPause
3税弃、paused
不可見并不能響應用戶的輸入纪岁,但是在后臺繼續(xù)活動中,同安卓的onStop
下面是生命周期:
初次打開widget時则果,不執(zhí)行AppLifecycleState的回調幔翰;
按home鍵或Power鍵, AppLifecycleState inactive---->AppLifecycleState pause
從后臺到前臺:AppLifecycleState inactive--->ApplifecycleState resumed
back鍵退出應用: AppLifecycleState inactive--->AppLifecycleState paused
原文鏈接:https://blog.csdn.net/yoonerloop/article/details/121003373</blockcode>
//初始化一些變量
void onCreate() {}
//onResume 只要頁面切換到棧頂西壮,都會調用此方法
void onResume() {
_isResume = true;
_isPause = false;
}
//頁面被覆蓋遗增,暫停
void onPause() {
_isResume = false;
_isPause = true;
}
void onDestroy() {}</blockcode>
LifeCycleInnerState
2.RouteAware
監(jiān)聽路由變化
RouteObserver 是一個配合RouteAware的一個類,通過這個類可以通知到當前頁面應該執(zhí)行那種生命周期方法款青,否則只混入RouteAware是不能執(zhí)行的做修。另外還有RouteObserver需要注冊在MaterialApp中,這樣才能在導航的過程中執(zhí)行到對應的生命周期方法抡草。navigatorObservers
@override
void didPush() {
super.didPush(); //從其他頁面跳轉到當前頁面
log("didPush");
_isTop = true;
}
@override
void didPushNext() { //從當前頁面跳轉到下一頁之后才會調用饰及?
super.didPushNext();
log("didPushNext");
onPause(); //在本頁面執(zhí)行onPause()
_isTop = false;
}
@override
void didPop() { //從當前頁面退回當上一頁面
super.didPop(); //pop
onPause();//在當前頁執(zhí)行onPause()
}
@override
void didPopNext() {
super.didPopNext();//從其他頁面Pop之后,進入到當前頁面
onResume();//在當前頁面執(zhí)行onResume()
_isTop = true;
}
原文鏈接:https://blog.csdn.net/happiness365/article/details/122782217</blockcode>
三康震、flutter樹結構
Widget樹旋炒、Element樹、RenderObject樹
并不是所有的Widget都會被獨立渲染签杈!只有繼承RenderObjectWidget的才會創(chuàng)建RenderObject對象
每一個Widget都會創(chuàng)建一個Element對象
隱式調用createElement方法瘫镇。Element加入Element樹種
它會創(chuàng)建三種Element
1.RenderElement主要是創(chuàng)建RenderObject對象
繼承RenderObjectWidget的Widget會創(chuàng)建RenderElement
創(chuàng)建RanderElementFlutter會調用mount方法鼎兽,調用createRanderObject方法
2.StatefulElement繼承ComponentElement
StatefulWidget會創(chuàng)建StatefulElement
調用createState方法,創(chuàng)建State將Widget賦值給state調用state的build方法 并且將自己(Element)傳出去
build里面的context就是Widget的Element铣除!
3.StatelessElement繼承ComponentElement
StatelessWidget會創(chuàng)建StatelessElement
主要就是調用build方法 并且將自己(Element)傳出去</blockcode>
四谚咬、flutter 狀態(tài)管理,provider
狀態(tài)管理就是一些變量的管理尚粘,而這些變量需要在多個路由界面中重復使用择卦,所以就有了狀態(tài)管理。
如果多個界面需要重復數(shù)據(jù)時郎嫁,當這些界面頻繁跳轉時秉继,沒有全局狀態(tài)管理,那就需要每次跳轉路由界面都需要傳值一次達到保存數(shù)據(jù)的目的泽铛,當有了全局狀態(tài)管理尚辑,每次需要讀取或者改變這些數(shù)據(jù)時,則可以調用公用方法獲取或修改盔腔,因此可以大大減少工作量并提升應用性能
一個model類可以有多個屬性杠茬,一個app可以有多個model類
全局管理類,不見得用model結尾弛随,但是我個人喜歡用model來存儲數(shù)據(jù)
model類必須要繼承ChangeNotifier類瓢喉,否則無法刷新數(shù)據(jù)
model管理的狀態(tài),只有get方法舀透,修改他的值是通過單獨的方法進行修改的栓票,在修改后要調用notifyListeners方法
鏈接:http://www.reibang.com/p/7d392f696de3
五、Future是什么
Future代表異步執(zhí)行
async:在方法體前面是使用愕够,定義該方法為一個異步方法走贪。
await:等待并獲得異步表達式的執(zhí)行結果,并且給關鍵字只能在async修飾的方法中链烈。
Future是單線程厉斟,先執(zhí)行完全部微任務,再執(zhí)行隊列任務
Future修飾的關鍵字强衡,會將事件加入到隊列任務中
Future如何獲取異步的值:通過then()方法
Future如何處理異常:通過catchError()或者在then()中傳入命名參數(shù)onError
async和wait的關鍵的作用是什么:async聲明一個異步方法擦秽,wait等待異步任務完成;簡單來講就是同步的方式編寫異步代碼漩勤。
如何捕獲和處理async中的異常:需要使用try/catch來捕獲以及處理程序運行中的異常感挥。
原文鏈接:https://blog.csdn.net/mrRuby/article/details/122563629
六、UI或文本溢出
文本用TextOverflow進行溢出屬性處理
列表溢出越败,使用Wrap(//流式布局處理
在text 外層包裹一個Expanded 它會將寬高設定為余下空間
1,Row報overflowed的解決辦法
在要展示內(nèi)容外包一層Expanded
2,Column報overflowed的解決辦法
在Column外包一層SingleChildScrollView
在Scaffold下設置resizeToAvoidBottomInset : false
七触幼、flutter性能優(yōu)化
1.widget build()方法避免執(zhí)行重復耗時的非必要操作
避免在widget或者state的build()方法中進行重復且耗時的非必要工作,因為當父 widget 重建時究飞,子 widget 的 build() 方法會被頻繁地調用置谦。因此確保非必要的耗時工作不放在build()方法中堂鲤。
2.控制widget setState()的重建范圍
在StatefulWidget中調用setState()會引起該widget的重建,會調用state的build()方法媒峡。當一個頁面只有一個StatefulWidget瘟栖,把全部widget的狀態(tài)都放在這個StatefulWidget,并且該StatefulWidget為頁面最頂端的父widget時谅阿,setState方法會讓整個頁面的widget重建半哟。因此,將一個頁面中的widget進行多個StatefulWidget的狀態(tài)劃分签餐,每個StatefulWidget只負責自己的狀態(tài)維護寓涨,將大大縮小flutter頁面繪制范圍。
3.控制widget重建次數(shù)
不會改變的widget使用const氯檐,如Text戒良、Icon、Image等男摧,這樣可以復用這部分widget蔬墩,不會導致widget重建
動畫使用AnimatedBuilder時译打,將不需要動的子widget賦值給child參數(shù)耗拓,builder方法中使用該child,可以做到復用子widget奏司,以避免在動畫過程中重建其后代 widget乔询。
使用CustomPaint自定義組件的時候,使用重寫shouldRepaint方法韵洋,返回false即不重繪竿刁,true為重繪,我們可以根據(jù)條件返回true搪缨,減少自定義組件的重繪次數(shù)
4.盡量避免saveLayer操作
saveLayer方法是Flutter框架中最重量的操作之一食拜。更新屏幕時這個方法很有用,但它可能使應用變慢副编,如果不是必須的話负甸,應該避免使用這個方法。即便沒有顯式地調用saveLayer,也可能在其他操作中間接調用了該方法痹届。
有兩個方法可以檢查頁面是否使用saveLayer呻待,
1.可以使用在MeterialApp中時使用checkerboardOffscreenLayers屬性開關來檢查當前界面是否使用了saveLayer,打開開關之后队腐,運行應用并檢查是否有圖像的輪廓閃爍蚕捉。如果有新的幀渲染的話,容器就會閃爍柴淘;
2.使用flutter screenshot --type=skia --observatory-url=這里填timeline的觀察臺地址迫淹,生成skp文件秘通,再上傳到https://debugger.skia.org/,就可詳細分析頁面中的saveLayer的調用敛熬,推薦該方法充易,第一種方法有的saveLayer無法檢查出來。
在官網(wǎng)中可以看到荸型,以下組件會觸發(fā)saveLayer盹靴,應盡量避免使用,尋找其他代替瑞妇。透明度(Opacity)稿静、裁剪(clipping)、陰影(shadows)以及文字(Text)
5.使用懶加載辕狰、按需加載模型Slive
滾動列表中SingleChileScrollView不支持Slive改备,會直接加載整個子widget,如果滑動部分很長蔓倍,請使用ListView悬钳、gridView等支持按需加載模型的列表,并且使用ListView.builder或者ListView.separated加載子項偶翅。
6.使用RepaintBoundary
使用RepaintBoundary默勾,給頁面設置重繪范圍,將提高我們的性能聚谁。比如頁面滑動不需要重繪動畫母剥,使用RepaintBoundary包住我們的動畫widget,頁面滑動將不會導致動畫重繪形导。還可以用該widget包住我們的圖片环疼,做圖片緩存,ListView里面就使用了RepaintBoundary來包住item朵耕,緩存item炫隶。
7.復用Element
element tree是flutter三棵樹之一,我個人把他當作渲染樹的manager阎曹,widget內(nèi)部有個canUpdate方法伪阶。
原文鏈接:https://blog.csdn.net/weixin_42468452/article/details/120534954
八、flutter插件開發(fā)芬膝,原生混合開發(fā)
iOS用framework或pod
安卓用aar包接入
使用flutterBooost框架
解決跳轉全屏flutter會出現(xiàn)引導頁
路由問題望门,pod的時候將flutterBooost的監(jiān)聽和flutterController釋放調
九、flutter網(wǎng)絡請求锰霜,dio優(yōu)點
dio是一個強大的Dart Http請求庫筹误,支持Restful API、FormData癣缅、攔截器厨剪、請求取消哄酝、Cookie管理、文件上傳/下載祷膳、超時陶衅、自定義適配器等...可以說是覆蓋了所有涉及到的網(wǎng)絡請求。
原生HttpClient發(fā)起網(wǎng)絡請求非常的復雜直晨,很多東西還需自己手動處理搀军。如果涉及到上傳、下載勇皇、斷點續(xù)傳等那肯定非常繁瑣
每個 Dio 實例都可以添加任意多個攔截器罩句,他們組成一個隊列,攔截器隊列的執(zhí)行順序是FIFO先進先出原則敛摘。通過攔截器你可以在請求之前门烂、響應之后和發(fā)生異常時(但還沒有被then或catchError處理)做一些統(tǒng)一的預處理操作。