Flutter开发实践五:深入探索一些有趣的原理
1. WidgetsFlutterBinding
这是一个粘合类。
1。Mixins
混入( ̄. ̄)!
是的,Flutter使用Dart来支持Mixin,Mixin可以更好地解决多重继承中容易出现的问题,例如:方法优先级混乱、参数冲突。好复杂等等。
Mixin 的定义解释起来有点混乱,所以我们来看代码。如下代码所示,在Dart中使用 接下来我们继续修改代码。如下所示,我们定义了一个抽象类 从最后的输入可以看出,A,A2,B 说了很多,Mixins在Flutter中还有什么意义呢?此时我们应该看到 Flutter 中的“粘合类”: WidgetsFlutterBinding 当 Flutter 启动时, 从上图中可以看到,WidgetsFlutterBinding本身没有任何代码。主要继承了 和
进行混合。可以看出,G类超过B与A,A2
。执行G的方法a、b、c后,输出A2.a()、A.b()、B.c()。 。所以唯一的结论就是覆盖了同样的方法,后面的方法会覆盖之前的。
。 class A {
a() {
print("A.a()");
}
b() {
print("A.b()");
}
}
class A2 {
a() {
print("A2.a()");
}
}
class B {
a() {
print("B.a()");
}
b() {
print("B.b()");
}
c() {
print("B.c()");
}
}
class G extends B with A, A2 {
}
testMixins() {
G t = new G();
t.a();
t.b();
t.c();
}
/// ***********************输出***********************
///I/flutter (13627): A2.a()
///I/flutter (13627): A.b()
///I/flutter (13627): B.c()
复制代码
Base
,A、A2、B
都被继承,并在之后执行
中的所有方法都被执行了,而且只执行了一次,执行顺序也是一样的。大约。如果您从下面代码中的 A.a() 类方法中删除 super,您将看不到 super。 ()
操作。 B.a()
和 base a()
的输出。
abstract class Base {
a() {
print("base a()");
}
b() {
print("base b()");
}
c() {
print("base c()");
}
}
class A extends Base {
a() {
print("A.a()");
super.a();
}
b() {
print("A.b()");
super.b();
}
}
class A2 extends Base {
a() {
print("A2.a()");
super.a();
}
}
class B extends Base {
a() {
print("B.a()");
super.a();
}
b() {
print("B.b()");
super.b();
}
c() {
print("B.c()");
super.c();
}
}
class G extends B with A, A2 {
}
testMixins() {
G t = new G();
t.a();
t.b();
t.c();
}
///I/flutter (13627): A2.a()
///I/flutter (13627): A.a()
///I/flutter (13627): B.a()
///I/flutter (13627): base a()
///I/flutter (13627): A.b()
///I/flutter (13627): B.b()
///I/flutter (13627): base b()
///I/flutter (13627): B.c()
///I/flutter (13627): base c()
复制代码
2。 WidgetsFlutterBinding
WidgetsFlutterBinding
。 runApp
将被调用。作为App的网关,必须承担各种初始化和功能配置。在这种情况下,Mixins的作用就体现出来了。 。BindingBase
,然后附加到各种Binding,这就是BindingBinding
您是否注意到,这里的每个Binding都可以单独使用,也可以“粘合”到WidgetFlutterBinding。这样做的效果是不是比Level级别的继承结构更清晰?
最后我们打印执行顺序,如下图。所以,果然如此ヽ( ̄▽ ̄)ノ。
2。 InheritedWidget
InheritedWidget是一个抽象类,在Flutter中起着重要的作用。也许你没有直接使用过它,但你应该使用与其相关的包。
如上图所示,Inherited Widget主要实现了两个方法:
- 创建
InheritedElement,Element ❀❀属于特殊Element,主要添加还添加到表映射关系
_inheritedWidgets
[注1],方便后代获取元素;同时,通过notifyClients
方法更新依赖项。 - 添加了方法
updateShouldNotify
。当该方法返回 true 时,Widget 的依赖实例将被更新。
所以我们只能这样理解:InheritedWidget是通过InheritedElement
实现从下往上的搜索支持(因为它是添加到❀❀中的,已经从它的后代Function更新了。? heritedWidget 对应元素之间的映射关系。
然后我们看BuildContext,如上图,BuildContext其实只是一个接口,而元素。 所以如果我们必须共享状态,那么一层一层地遍历状态来获得共享将是非常困难的。那么知道上面的Legacy Widget后会发生什么呢? 是否可以将所有需要共享的状态都放在InheritedWidget中,然后在使用的widget中直接访问?答案是肯定的!所以代码如下: 通常,像焦点、主题颜色、多语言、用户信息等,App中全局共享的所有数据,都会通过BuildContext(InheritedElement)获取。 作为总结,让我们从 如下代码所示,通过将主题数据设置为InheritedElement
是 Element 的子类,因此 的每个 InheritedElement 都是 BuildContext 的实例。同时,我们日常使用的BuildContext也是一个Element。 ///收起键盘
FocusScope.of(context).requestFocus(new FocusNode());
/// 主题色
Theme.of(context).primaryColor
/// 多语言
Localizations.of(context, GSYLocalizations)
/// 通过 Redux 获取用户信息
StoreProvider.of(context).userInfo
/// 通过 Redux 获取用户信息
StoreProvider.of(context).userInfo
/// 通过 Scope Model 获取用户信息
ScopedModel.of<UserInfo>(context).userInfo
复制代码
主题
开始。 MaterialApp
,可以通过Theme.of(context)获取并使用主题数据当主题数据
MaterialApp
发生变化时,对应Widget的颜色也会发生变化。为什么会这样(キ`゚Д゚´)!!?山通过源码搜索层,可以找到这样的嵌套:MateriaLapp->Animatedtheme->Theme->_inheritedTheme Extends InheritedWidget Nested under Inherited小部件
如上图,通过 中获得 上一篇:InheritedWidget中的 最后如下图,在继承 edElement 在 、 updateShouldNotify 近日,闲鱼科技发布了《Flutter之禅 内存优化篇》。文章对Flutter内存做了深入的探索。一个有趣的发现是:Flutter 中的 如上图所示,与图片缓存相关的流程,目前的瓶颈处理是: 可以阅读文章本身以获得更详细的内容。为什么这里提到这个呢?这是因为 你还记得 。 对象,该对象是一个全局单例,由 深入理解闲鱼Flutter Platform Channel技术 中提到:Flutter中主要有四个线程,Platform Task Runner、UI Task Runner、GPU Task Runner和IO Task Runner。 其中, 如下图,如果你在 Flutter 中做过 Dart 和 Native 端的通信,应该知道,通过 未完成的请求。 编译后的 Android 二进制文件位于 iOS?据我所知,动态库、框架之类的引用好像是不能热更新的,除非你不再需要它们了! 作者:连毛德小果Theme.from(context)
获得的主题数据实际上是通过context.inheritFromWidgetOfExactType(_InheritedTheme(_InheritedTheme),
?因为bool updateShouldNotify(_InheritedTheme old) => theme.data != old.theme.data;
复制代码
inheritFromWidgetOfExactType ) 方法BuildContext是在Element
上实现的,如下图:,记住上面的。tedWidgetInheritedElement 已存在于 _inheritedWidgets 中,
InheritedElement
,这个元素是一个特殊的Element,主要是把自己添加到映射表_inheritedWidgets 中定义 › 更新 Client
方法 Widget 继承
,例如,在 主题来自_继承作为主题、Redux、范围模型和本地化的核心,所有
继承的小部件
。3。内存
限制了缓存图像的数量
。 WidgetsFlutterBinding
这个粘合类吗?其中,Mixins 是PaintingBinding
,如下图所示,“粘合”绑定负责图像缓存ImageCache中存在一个对象
PaintingBinding
ImageProvider用来设置图像大小,像图像设置如下:
//缓存个数 100
PaintingBinding.instance.imageCache.maximumSize=100;
//缓存大小 50m
PaintingBinding.instance.imageCache.maximumSizeBytes= 50 << 20;
复制代码
4。线程
Platform Task Runner
是Android和iOS主线程,UI Task Runner
是Flutter UI线程。平台通道
,通信的两端是 平台任务运行器❀ 以及
UI Task Runner
,这里主要总结一下:5。热更新
data/data/packagename/app_flutter/flutter_assets/
下。用过Android的人应该都知道,通过这种方式可以轻松更新,所以你就知道 ̄ω ̄=。
链接:https://juejin.im/post/5bc450dff265da0a951f032b
来源:掘金商业转载请联系作者授权。非商业转载请注明出处。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。