flutter_boost和Getx混用下路由管理

3,978 阅读2分钟

背景

为了在现有的项目中扩展Flutter模块,在常用的几种Flutter混合栈的方式FlutterEngineGroupflutter_boostflutter_thrio等中选择了flutter_boost的方式。此外还集成了Getx作为Flutter项目状态管理工具。在业务上,原生有多个入口打开Flutter页面,并且各个入口对应的Flutter页面不一致。

路由方案的选择

Getxflutter_boost都具有路由功能,考虑到原生端和Flutter端的路由的映射关系,所以就放弃了Getx的路由管理。在项目中只使用Getx状态管理、国际化等功能。

GetxController的释放问题

因为在项目中使用flutter_boost管理页面路由,所以Getx失去了页面的生命周期的控制,导致在页面关闭时无法感知页面的pop,从而导致该页面对应controller无法销毁。

解决方案

在文章Flutter GetX使用---简洁的魅力!中讲到几种解决方案,其中最优解就是在外部监听页面的生命周期,手动去释放。我们在使用flutter_boost的时候也可以用同样的方式来释放GetxController。 我们在集成flutter_boost时,会在main函数中添加全局声明周期的监听:

void main() {
  ///添加全局生命周期监听类
  PageVisibilityBinding.instance.addGlobalObserver(AppLifecycleObserver());
  runApp(MyApp());
}

在监听类AppLifecycleObserveronPagePushonPagePop方法中添加处理:

import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'package:get/get_navigation/src/router_report.dart';

///全局生命周期监听示例
class AppLifecycleObserver with GlobalPageVisibilityObserver {
  @override
  void onBackground(Route route) {
    super.onBackground(route);
    print("AppLifecycleObserver - onBackground");
  }

  @override
  void onForeground(Route route) {
    super.onForeground(route);
    print("AppLifecycleObserver - onForground");
  }

  @override
  void onPagePush(Route route) {
    super.onPagePush(route);
    RouterReportManager.reportCurrentRoute(route);
    print("AppLifecycleObserver - onPagePush");
  }

  @override
  void onPagePop(Route route) {
    super.onPagePop(route);
    RouterReportManager.reportRouteDispose(route);
    print("AppLifecycleObserver - onPagePop");
  }

  @override
  void onPageHide(Route route) {
    super.onPageHide(route);
    print("AppLifecycleObserver - onPageHide");
  }

  @override
  void onPageShow(Route route) {
    super.onPageShow(route);
    print("AppLifecycleObserver - onPageShow");
  }
}

如果在引用import 'package:get/get_navigation/src/router_report.dart';时报没有文件: 请尝试更换Getx版本。
page中的处理:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'test_one_controller.dart';

class TestOnePage extends StatelessWidget {
  const TestOnePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    TestOneController controller = Get.put(TestOneController());
    return Scaffold(
      body: Center(
        child: GetBuilder<TestOneController>(builder: (controller) {
          return Text("${controller.count.value}");
        }),
      ),
    );
  }
}

注意:controller的声明一定要放在build的方法里,放到外面的话也是没办法释放的。