likes
comments
collection
share

三、Flutter之GetX的依赖管理

作者站长头像
站长
· 阅读数 36

学习目标

  • 掌握GetX依赖管理实例方法
  • 掌握GetX中的依赖注入的工作原理
  • 掌握Bindings类的使用以及工作原理
  • 了解它的使用的场景

实例方法

Get.put()

同步插入一个依赖,这个是最常用的方法

Get.put<SomeClass>(SomeClass());
Get.put<LoginController>(LoginController(), permanent: true);
Get.put<ListItemController>(ListItemController, tag: "some unique string");

参数解释:

Get.put<T>(
  // T表示可以是任何类型,一般是控制器
  T dependency,

  // 依赖的唯一标识(这是可选值)
  String? tag,

  // 是否跟随实例销毁
  bool permanent = false,

  // 可选:允许你在测试中使用一个抽象类后,用另一个抽象类代替它,然后再进行测试。
  bool overrideAbstract = false,
  
  // 可选:允许你使用函数而不是依赖(dependency)本身来创建依赖。
  // 这个不常用
  InstanceBuilderCallback<S> builder,
);

Get.lazyPut()

只用Get.find<xxx>()的时候依赖才会被加载

Get.lazyPut<ApiMock>(() => ApiMock());

参数解释:

Get.lazyPut<S>(
  // 强制性:当你的类第一次被调用时,将被执行的方法。
  InstanceBuilderCallback builder,
  
  // 依赖的唯一标识(这是可选值)
  String tag,

  // 开启后页面实例销毁后只会被丢弃,不会销毁它,如果后面用到了会重新创建
  bool fenix = false
)

Get.putAsync

异步注册依赖

Get.putAsync<SharedPreferences>(() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setInt('counter', 12345);
  return prefs;
});

Get.putAsync<YourAsyncClass>(() async => await YourAsyncClass())

参数解释:

Get.putAsync<T>(
  // 必备:一个将被执行的异步方法,用于实例化你的类。
  AsyncInstanceBuilderCallback<T> builder,

  // 依赖的唯一标识(这是可选值)
  String tag,

  // 是否跟随实例销毁
  bool permanent = false
)

Get.find

Get会帮你找到你想要的依赖,然后你就可以使用它了

final controller = Get.find<Controller>();

controller.xxx // 使用控制器的值,记住需要Obx包裹才成为响应式哦

Get.create

创建一个实例出来,它是针对单个页面局部状态的。每次创建出来的实例都是全新的!

Get.create对比Get.put方法的区别是:在切换页面后是共享了之前的实例,不会创建新的实例

Get.Create<SomeClass>(() => SomeClass());
Get.Create<LoginController>(() => LoginController());
Get.create<S>(
  // 需要:一个返回每次调用"Get.find() "都会被新建的类的函数。
  // 示例: Get.create<YourClass>(()=>YourClass())
  FcBuilderFunc<S> builder,

  // 可选:就像Get.put()一样,但当你需要多个同类的实例时,会用到它。
  // 需要是一个唯一的字符串。只要把标签改成名字
  String name,

  // 和Get.put一致,但是默认为开启
  bool permanent = true
}

Get.delete

Get.delete<Controller>(); //通常你不需要这样做,因为GetX已经删除了未使用的控制器。

Bindings类

可以将路由、状态管理器、依赖管理器集成到一块。

基本用法:

  1. 实现一个Bindings
class HomeController extends GetxController {
  final name = "Camila".obs;

  changeName(String n) {
    name.value = n;
  }
}


class HomeBinding implements Bindings {
  @override
  void dependencies() {
    Get.put(HomeController());
  }
}
  1. 使用HomeBinding
GetMaterialApp(
  getPages: [
    GetPage(
      name: '/',
      page: () => const Home(),
      binding: HomeBinding(), // 使用 HomeBinding
  	)
  ],
);
  1. 访问的时候自动挂载HomeController
class Home extends StatelessWidget {
  const Home({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GetBuilder<HomeController>(
        builder: (context) {// context => HomeController
          return Column(
            children: [
              Obx(() => Text("${context.name}")),
              TextButton(
                onPressed: () {
                  context.changeName();
                },
                child: const Text("change name"),
              ),
            ],
          );
        },
      ),
    );
  }
}

第二步可以看到我们还需要再声明一个HomeBinding,这样很麻烦可以直接用一下的写法

GetMaterialApp(
  getPages: [
    GetPage(
      name: '/',
      page: () => const Home(),
      binding: BindingsBuilder(() { // 一种更加方便的写法
        Get.put(HomeController());
      }),
  	)
  ],
);

GetX管理依赖的机制

GetX默认情况下会将未使用的控制器从内存移除,但是如果我们不想用这种方式是可以通过SmartManagement改变它的机制的

基于SmartManagement选择对应的类型

void main () {
  runApp(
    GetMaterialApp(
      smartManagement: SmartManagement.onlyBuilders // 选择类型
      home: Home(),
    )
  )
}

SmartManagement一共有三种类型

SmartManagement.full

默认选项:销毁那些没有被使用的、没有被设置为永久的类。

SmartManagement.onlyBuilders

这个选项的特殊之处在于:只有在initialBinding:中启动的控制器或是Get.lazyPut()加载到Binding中的控制器才会被销毁。

GetMaterialApp(
  initialBinding: SampleBind(), // 例子
  home: Home(),
);

SmartManagement.keepFactory

和默认选项的不同之处在于它删除依赖关系后会保留工厂,下次使用实例的时候只会重新创建关系

Bindings的工作原理

在进入页面那一刻会创建工厂,然后换屏动画发生就会被销毁。比起重新创建一个工厂然后调用SmartManagement.keepFactory会更加靠谱,因为它不需要重新创建一个工厂。

转载自:https://juejin.cn/post/7234322782057791549
评论
请登录