前言
Android開發者應該知道google出了一套管理生命週期的框架,詳細的可以移步到這裡。那在flutter中有沒有類似這種庫呢?筆者找了挺久沒找到,所以最終決定研究下Android那邊的實現原理,然後寫一個flutter的版本,具體細節做了些調整,專案地址:flib_lifecycle
如何分發
- 首先寫一個用於分發生命週期的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);
複製程式碼
- 繼承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事件呢?筆者目前的實現方案如下:
- 寫一個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();
}
複製程式碼
- 使用介面卡改造一下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();
}
}
複製程式碼
- 繼承改造後的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');
},
),
);
}
}
複製程式碼
執行後按如下操作後日志如下:
- 開啟DemoPage
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onCreate State: FLifecycleState.created
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStart State: FLifecycleState.started
複製程式碼
- 跳轉到MainPage
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStop State: FLifecycleState.created
複製程式碼
- 關閉MainPage
I/flutter (26755): _lifecycleListener: FLifecycleEvent.onStart State: FLifecycleState.started
複製程式碼
- 關閉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。