为了弄懂Flutter的状态管理,-我用10种方法改造了counter-app(1)
import ‘package:scoped_model/scoped_model.dart’;
class CounterModel extends Model {
int _counter = 0;
int get counter => _counter;
void increment() {
_counter++;
notifyListeners();
}
void decrement() {
_counter–;
notifyListeners();
}
}
其中数据变化的部分会通知listeners, 它们收到通知后会rebuild.
在上层初始化并提供数据类, 用ScopeModel.
访问数据有两种方法:
- 用
ScopedModelDescendant包裹widget. - 用
ScopedModel.of静态方法.
使用的时候注意要提供泛型类型, 会帮助我们找到离得最近的上层ScopedModel.
ScopedModelDescendant(
builder: (context, child, model) {
return Text(
model.counter.toString(),
);
}),
数据改变后, 只有ScopedModelDescendant会收到通知, 从而rebuild.
ScopedModelDescendant有一个rebuildOnChange属性, 这个值默认是true.
对于button来说, 它只是控制改变, 自身并不需要重绘, 可以把这个属性置为false.
ScopedModelDescendant(
rebuildOnChange: false,
builder: (context, child, model) {
return FloatingActionButton(
onPressed: model.increment,
tooltip: ‘Increment’,
child: Icon(Icons.add),
);
},
),
scoped model这个库帮我们解决了数据访问和通知的问题, 但是rebuild范围需要自己控制.
- access state
- notify other widgets
- minimal rebuild -> X -> 因为需要开发者自己来决定哪一部分是否需要被重建, 容易被忘记.
代码分支: scoped-model
Provider
Provider是官方文档的例子用的方法.
去年的Google I/O 2019也推荐了这个方法.
和BLoC的流式思想相比, Provider是一个观察者模式, 状态改变时要notifyListeners().
有一个counter版本的sample: https://github.com/flutter/samples/tree/master/provider_counter
Provider的实现在内部还是利用了InheritedWidget.
Provider的好处: dispose指定后会自动被调用, 支持MultiProvider.
Provider实现
- model类继承
ChangeNotifer, 也可以用with.
class CounterModel extends ChangeNotifier {
int value = 0;
void increment() {
value++;
notifyListeners();
}
void decrement() {
value–;
notifyListeners();
}
}
- 数据提供者:
ChangeNotifierProvider.
void main() => runApp(ChangeNotifierProvider(
create: (context) => CounterModel(),
child: MyApp(),
));
- 数据消费者/操纵者, 有两种方式:
Consumer包裹, 用Provider.of.
Consumer(
builder: (context, counter, child) => Text(
‘${counter.value}’,
),
),
FAB:
FloatingActionButton(
onPressed: () =>
Provider.of(context, listen: false).increment(),
),
这里listen置为false表明状态变化时并不需要rebuild FAB widget.
Provider性能相关的实现细节
Consumer包裹的范围要尽量小.- listen变量.
- child的处理.
Consumer中builder方法的第三个参数.
可以用于缓存一些并不需要重建的widget:
return Consumer(
builder: (context, cart, child) => Stack(
children: [
// Use SomeExpensiveWidget here, without rebuilding every time.
child,
Text(“Total price: ${cart.totalPrice}”),
],
),
// Build the expensive widget here.
child: SomeExpensiveWidget(),
);
代码分支: provider.
BLoC
BLoC模式的全称是: business logic component.
所有的交互都是a stream of asynchronous events.Widgets + Streams = Reactive.
BLoC的实现的主要思路: Events in -> BloC -> State out.
Google I/O 2018上推荐的还是这个, 2019就推荐Provider了.
当然也不是说这个模式不好, 架构模式本来也没有对错之分, 只是技术选型不同.
BLoC手动实现
不添加任何依赖可以手动实现BLoC, 利用:
- Dart SDK > dart:async >
Stream. - Flutter的
StreamBuilder: 输入是一个stream, 有一个builder方法, 每次stream中有新值, 就会rebuild.
可以有多个stream, UI只在自己感兴趣的信息发生变化的时候重建.
BLoC中:
- 输入事件:
Sink<Event> input. - 输出数据:
Stream<Data> output.
CounterBloc类:
class CounterBloc {
int _counter = 0;
final _counterStateController = StreamController();
StreamSink get _inCounter => _counterStateController.sink;
Stream get counter => _counterStateController.stream;
final _counterEventController = StreamController();
Sink get counterEventSink => _counterEventController.sink;
CounterBloc() {
_counterEventController.stream.listen(_mapEventToState);
}
void _mapEventToState(CounterEvent event) {
if (event is IncrementEvent) {
_counter++;
} else if (event is DecrementEvent) {
_counter–;
}
_inCounter.add(_counter);
}
void dispose() {
_counterStateController.close();
_counterEventController.close();
}
}
有两个StreamController, 一个控制state, 一个控制event.
读取状态值要用StreamBuilder:
StreamBuilder(
stream: _bloc.counter,
initialData: 0,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return Text(
‘${snapshot.data}’,
);
},
)
而改变状态是发送事件:
FloatingActionButton(
onPressed: () => _bloc.counterEventSink.add(IncrementEvent()),
),
实现细节:
- 每个屏幕有自己的BLoC.
- 每个BLoC必须有自己的
dispose()方法. -> BLoC必须和StatefulWidget一起使用, 利用其生命周期释放.
代码分支: bloc
BLoC传递: 用InheritedWidget
手动实现的BLoC模式, 可以结合InheritedWidget, 写一个Provider, 用来做BLoC的传递.
代码分支: bloc-with-provider
BLoC rxdart实现
用了rxdart package之后, bloc模块的实现可以这样写:
class CounterBloc {
int _counter = 0;
final _counterSubject = BehaviorSubject();
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。






既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
尾声
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。
当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。
进阶学习视频

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!**](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
更多推荐



所有评论(0)