Flutter - 生命週期管理

前言

Android開發者應該知道google出了一套管理生命週期的框架,詳細的能夠移步到這裏。在flutter中有沒有相似這種庫呢?筆者找了挺久沒找到,若是有知道的讀者麻煩告知一下。java

最後筆者分析了下Android那邊的實現原理,而後寫了一個flutter的版本,具體細節作了些調整,項目地址:flib_lifecycleandroid

下面將介紹如何利用這個項目進行生命週期的管理。git

如何分發

  1. 首先寫一個LifecycleState,用於分發生命週期,以下:
abstract class LifecycleState<T extends StatefulWidget> extends State<T> implements FLifecycleOwner {
  final FLifecycleRegistry _lifecycleRegistry = SimpleLifecycleRegistry();
  
  @override
  FLifecycle getLifecycle() {
    return _lifecycleRegistry;
  }

  @override
  void initState() {
    super.initState();
    // 分發[FLifecycleEvent.onCreate]事件
    _lifecycleRegistry.handleLifecycleEvent(FLifecycleEvent.onCreate);
  }

  @override
  void dispose() {
    // 分發[FLifecycleEvent.onDestroy]事件
    _lifecycleRegistry.handleLifecycleEvent(FLifecycleEvent.onDestroy);
    super.dispose();
  }
}
複製代碼

上面代碼中分發事件的寫法,也能夠寫爲標記爲某種狀態,一樣能夠通知生命週期事件給觀察者github

// 分發事件
_lifecycleRegistry.handleLifecycleEvent(FLifecycleEvent.XXX);

// 標記爲某種狀態
_lifecycleRegistry.markState(FLifecycleState.XXX);
複製代碼
  1. 繼承LifecycleState,以下:
class _DemoPageState extends LifecycleState<DemoPage> {
  @override
  void initState() {
    super.initState();
    // 添加觀察者
    getLifecycle().addObserver(_lifecycleListener);
  }

  void _lifecycleListener(FLifecycleEvent event, FLifecycle lifecycle) {
    print('_lifecycleListener: ' + event.toString());
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
    );
  }
}
複製代碼

運行後打開此界面,再關閉界面,控制檯日誌以下:bash

I/flutter (26755): _lifecycleListener: FLifecycleEvent.onCreate
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onDestroy
複製代碼

更多的生命週期事件

在Android中,Activity還有更多的生命週期事件,好比onStart(),onResume(),onPause(),onStop()等。
那flutter中的State有沒有像Android那麼詳細的生命週期事件呢?很遺憾,沒有像Android中那麼詳細,可是能夠嘗試實現。markdown

筆者以爲至少要有如下幾個狀態和生命週期:框架

/// 生命週期狀態
enum FLifecycleState {
  /// 銷燬狀態 
  destroyed,
  /// 初始化狀態
  initialized,
  /// 建立狀態
  created,
  /// 活動狀態
  started,
}

/// 生命週期事件
enum FLifecycleEvent {
  /// 分發此事件後處於[FLifecycleState.created]狀態
  onCreate,
  /// 分發此事件後處於[FLifecycleState.started]狀態
  onStart,
  /// 分發此事件後處於[FLifecycleState.created]狀態
  onStop,
  /// 分發此事件後處於[FLifecycleState.destroyed]狀態
  onDestroy,
}
複製代碼

有了以上幾個狀態,才方便後續實現更多的功能,好比處於建立狀態的話就中止定時器,處於活動狀態從新開始定時器等。
那flutter中的State應該如何分發onStart和onStop事件呢?筆者目前的實現方案以下:ide

  1. 寫一個適配器,分發State的生命週期,以下:
class FStateLifecycleAdapter implements FLifecycleOwner, _StateLifecycle {
  final FLifecycleRegistry _lifecycleRegistry;
  bool _started;
  bool _startedMarker;

  FStateLifecycleAdapter({FLifecycleRegistry lifecycleRegistry})
      : this._lifecycleRegistry = lifecycleRegistry ?? SimpleLifecycleRegistry();

  @override
  FLifecycle getLifecycle() {
    return _lifecycleRegistry;
  }

  @override
  void initState() {
    _lifecycleRegistry.handleLifecycleEvent(FLifecycleEvent.onCreate);
  }

  @override
  Widget build(BuildContext context) {
    if (_startedMarker == null) {
      _startedMarker = true;
    }

    if (_startedMarker) {
      _startedMarker = false;
      _started = true;
      _lifecycleRegistry.handleLifecycleEvent(FLifecycleEvent.onStart);
    }

    return null;
  }

  @override
  void deactivate() {
    assert(_startedMarker == false);

    final bool expected = !_started;
    if (expected) {
      _startedMarker = true;
      // 等待build
    } else {
      _started = false;
      _lifecycleRegistry.handleLifecycleEvent(FLifecycleEvent.onStop);
    }
  }

  @override
  void dispose() {
    _started = null;
    _startedMarker = null;
    _lifecycleRegistry.handleLifecycleEvent(FLifecycleEvent.onDestroy);
  }
}

abstract class _StateLifecycle {
  void initState();

  Widget build(BuildContext context);

  void deactivate();

  void dispose();
}
複製代碼
  1. 使用適配器改造一下LifecycleState,以下:
abstract class LifecycleState<T extends StatefulWidget> extends State<T> implements FLifecycleOwner {
  final FStateLifecycleAdapter _stateLifecycleAdapter = FStateLifecycleAdapter();

  @override
  FLifecycle getLifecycle() {
    return _stateLifecycleAdapter.getLifecycle();
  }

  @override
  void initState() {
    super.initState();
    _stateLifecycleAdapter.initState();
  }

  @override
  void deactivate() {
    super.deactivate();
    _stateLifecycleAdapter.deactivate();
  }
  
  @override
  Widget build(BuildContext context) {
    _stateLifecycleAdapter.build(context);
    return buildImpl(context);
  }
  
  /// 因爲須要佔用build方法,因此這邊從新定了一個buildImpl方法用於返回Widget。
  Widget buildImpl(BuildContext context);

  @override
  void dispose() {
    _stateLifecycleAdapter.dispose();
    super.dispose();
  }
}
複製代碼
  1. 繼承改造後的LifecycleState,以下:
class _DemoPageState extends LifecycleState<DemoPage> {
  @override
  void initState() {
    super.initState();
    getLifecycle().addObserver(_lifecycleListener);
  }

  void _lifecycleListener(FLifecycleEvent event, FLifecycle lifecycle) {
    print('_lifecycleListener: ' + event.toString());
  }

  @override
  Widget buildImpl(BuildContext context) {
    return Container(
      color: Colors.white,
      child: GestureDetector(
        child: Text('打開MainPage'),
        onTap: () {
          Navigator.of(context).pushNamed('MainPage');
        },
      ),
    );
  }
}
複製代碼

日誌以下:學習

  1. 打開DemoPage
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onCreate
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStart
複製代碼
  1. 跳轉到MainPage
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStop
複製代碼
  1. 關閉MainPage
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStart
複製代碼
  1. 關閉DemoPage
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStop
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onDestroy
複製代碼

後續咱們就能夠經過生命週期的監聽實現更多的功能, 例如Android中的LiveData,能夠設置觀察者監聽值的變化,生命週期分發銷燬事件後自動釋放觀察者。ui

flutter版本的LiveData筆者已經寫好了,有興趣的讀者移步到這裏,後面也會專門寫一篇文章介紹怎麼使用。

結束語

文章中沒有對flutter中State本來的生命週期作過多的介紹,若是讀者須要瞭解的話,能夠去搜索一下,有不少相關的文章。

因爲筆者也是剛接觸flutter不久,還有不少須要學習的地方,若是文章中有錯誤的地方,還請讀者幫忙指正。

關於這個庫,有疑問的,或者須要探討的能夠和筆者聯繫,你們一塊兒學習。 郵箱:565061763@qq.com

相關文章
相關標籤/搜索