三、Flutter之GetX的依赖管理
学习目标
- 掌握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类
可以将路由、状态管理器、依赖管理器集成到一块。
基本用法:
- 实现一个
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());
}
}
- 使用
HomeBinding
类
GetMaterialApp(
getPages: [
GetPage(
name: '/',
page: () => const Home(),
binding: HomeBinding(), // 使用 HomeBinding
)
],
);
- 访问的时候自动挂载
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