widget state重新整理介面原理揭祕

code4flutter發表於2019-07-20

0x00 無狀態元件和狀態元件

widget是fltter介面開發中的基礎控制元件,如同ios中的uiview這種地位,所謂萬物皆widget。

widget有分為statelessWidget和statefulWidget,這兩者是什麼區別呢。一句話就是說statelesswidget用來展示無狀態的檢視,而statefulwidget用來展示可互動的,動態的檢視。

到此基本的結論已經出來了,那麼state究竟是怎麼實現狀態的更新的?

原文發表地址 flutterdev.top

0x01 UI程式設計正規化

iOS和安卓開發採用的是指令式程式設計正規化,而flutter、前端的VUE,小程式開發採用的是宣告式。

如 ios

UILable * lable  = [UILable new];
label.text = "hello world";
複製程式碼

這就是命令式,直接對控制元件中的屬性進行精準高效的賦值控制。

然而flutter如下


class BgChangeView extends StatefulWidget {
  @override
  _BgChangeViewState createState() => _BgChangeViewState();
  Color color = Colors.red;
}

class _BgChangeViewState extends State<BgChangeView> {
  int count = 10;

  void _incrementCounter() {
    setState(() {
      count = count>255 ? 0 :count + 10;
      widget.color = Color.fromARGB(count, 0x00, 0xff, 0xff);
      print("state refresh count ${count}");

    });
  }
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 100,
      height: 100,
      child: RaisedButton(onPressed: _incrementCounter,
        color: widget.color,
      ),
    );
  }
}

複製程式碼

flutterdev.top

將color指定給raisebutton,color在state中更新了,從而更新了raisebuttom的背景顏色

0x02 如何實現

state是表示檢視的狀態,當setState觸發當前檢視及其子檢視的銷燬重建,從父檢視到子檢視,從上到下的順序重建。

flutterdev.top

猜測內部state的實現

其實state是負責銷燬重建的,在重建的過程中重新對widget樹一級級生成,並把外部的資料重新對widget進行賦值操作,因為內部機制小部件重建的效率很高,幾乎肉眼看不到它銷燬的過程,但是如果對於root檢視頻繁進行state的操作,會帶來很大的效能開銷,卡頓,cpu,gpu使用率過高等情況。這也是宣告式程式設計一個弊端。使用中需要進來避免過多的setState的操作。

flutter engine內部當然會優化這部分的效能,每次重建之後之前申請的widget或randerobject使用的空間不會一個個的清空釋放,而是採取一直滑動壓縮的方式進行清理。如下圖所示

code4fluttter

  • flutter將記憶體區域分為兩部分,活躍空間和不活躍空間
  • 使用者使用app,flutter在活躍空間不斷申請記憶體空間
  • 直到獲取空間分配滿了
  • 檢查活躍空間中活躍的物件,將活躍的和其所依賴的物件一併標誌
  • 在app空閒時將活躍的物件移動到不活躍區域,此時活躍的物件中間沒有不活躍的區域了
  • 將不活躍的區域和活躍區域交換狀態

參考文章

相關文章