今天看啥  ›  专栏  ›  Sunday1990

Flutter - 生命周期监听和管理

Sunday1990  · 掘金  ·  · 2019-05-16 15:50

文章预览

阅读 46

Flutter - 生命周期监听和管理

前言

Android开发者应该知道google出了一套管理生命周期的框架,详细的可以移步到这里。那在flutter中有没有类似这种库呢?笔者找了挺久没找到,所以最终决定研究下Android那边的实现原理,然后写一个flutter的版本,具体细节做了些调整,项目地址:flib_lifecycle

如何分发

  1. 首先写一个用于分发生命周期的State基类,如下:
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();
  }
}
复制代码

上面代码中分发事件的写法,也可以写为标记为某种状态,同样可以通知生命周期事件给观察者

// 分发事件
_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() +
        ' State: ' +
        lifecycle.getCurrentState().toString());
  }

  @override
  void dispose() {
    super.dispose();
    // 移除观察者
    getLifecycle().removeObserver(_lifecycleListener);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
    );
  }
}
复制代码

运行后打开此界面,再关闭界面,控制台日志如下:

I/flutter (26755): _lifecycleListener: FLifecycleEvent.onCreate State: FLifecycleState.created
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onDestroy State: FLifecycleState.destroyed
复制代码

更多的生命周期事件

在Android中,Activity还有更多的生命周期事件,比如onStart(),onResume(),onPause(),onStop()等,那flutter中的State有没有像Android那么详细的生命周期事件呢?很遗憾,没有像Android中那么详细,但是可以尝试实现。

笔者觉得至少要有以下几个状态和生命周期:

/// 生命周期状态
enum FLifecycleState {
  /// 销毁状态 
  destroyed,
  /// 初始化状态
  initialized,
  /// 创建状态
  created,
  /// 活动状态
  started,
}

/// 生命周期事件
enum FLifecycleEvent {
  /// 分发此事件后处于[FLifecycleState.created]状态
  onCreate,
  /// 分发此事件后处于[FLifecycleState.started]状态
  onStart,
  /// 分发此事件后处于[FLifecycleState.created]状态
  onStop,
  /// 分发此事件后处于[FLifecycleState.destroyed]状态
  onDestroy,
}
复制代码

有了以上几个状态,才方便后续实现更多的功能,比如处于创建状态的话就停止定时器,处于活动状态重新开始定时器等。那flutter中的State应该如何分发onStart和onStop事件呢?笔者目前的实现方案如下:

  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;
      _notifyStartOrStop();
    }

    return null;
  }

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

    final bool expected = !_started;
    if (expected) {
      _startedMarker = true;
      // 等待build
    } else {
      _started = false;
      _notifyStartOrStop();
    }
  }

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

  void _notifyStartOrStop() {
    if (_started == null) {
      return;
    }
    if (_started) {
      _lifecycleRegistry.handleLifecycleEvent(FLifecycleEvent.onStart);
    } else {
      _lifecycleRegistry.handleLifecycleEvent(FLifecycleEvent.onStop);
    }
  }
}

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() +
        ' State: ' +
        lifecycle.getCurrentState().toString());
  }

  @override
  void dispose() {
    super.dispose();
    getLifecycle().removeObserver(_lifecycleListener);
  }

  @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 State: FLifecycleState.created
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStart State: FLifecycleState.started
复制代码
  1. 跳转到MainPage
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStop State: FLifecycleState.created
复制代码
  1. 关闭MainPage
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStart State: FLifecycleState.started
复制代码
  1. 关闭DemoPage
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStop State: FLifecycleState.created
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onDestroy State: FLifecycleState.destroyed
复制代码

后续我们就可以通过生命周期的监听实现更多的功能, 例如Android中的LiveData,可以设置观察者监听值的变化,生命周期分发销毁事件后自动释放观察者。

flutter版本的LiveData笔者已经写好了,有兴趣的读者移步到这里,后面也会专门写一篇文章介绍怎么使用。

结束语

文章中没有对flutter中State原本的生命周期做过多的介绍,如果需要了解大家可以去搜索一下,有很多相关的文章。由于笔者也是刚接触flutter不久,还有很多需要学习的地方,如果文章中有错误的地方,还请读者帮忙指正。

关于这个库有疑问的,或者需要探讨的可以和我联系,大家一起学习。
笔者邮箱:565061763@qq.com。

………………………………

原文地址:访问原文地址
快照地址: 访问文章快照
总结与预览地址:访问总结与预览