- path_provider,获取常用文件路径。
- quick_actions,App图标添加快捷方式,iOS的eponymous concept和Android的App Shortcuts。
- sensors,访问设备的加速度和陀螺仪传感器。
- shared_preferences,App KV存储功能。
- url_launcher,启动URL,包括打电话、发短信和浏览网页等功能。
- video_player,播放视频文件或者网络流的控件。
在Flutter中,依赖包由Pub堆栈管理,项目依赖设置在pubspec.yaml文件中声明即可(雷同于NPM的版本声明Pub Versioning Philosophy),对于未发布在Pub堆栈的插件可以使用git堆栈地址或文件路径:
dependencies: url_launcher: “>=0.1.2 <0.2.0” collection: “^0.1.2” plugin1: git: url: “git://github.com/flutter/plugin1.git” plugin2: path: …/plugin2/
以shared_preferences为例,在pubspec中添加代码:
dependencies: flutter: sdk: flutter shared_preferences: “^0.4.1”
脱字号“^”开头的版本表示和当前版本接口保持兼容的最新版,^1.2.3 等效于 >=1.2.3 <2.0.0而 ^0.1.2 等效于 >=0.1.2 <0.2.0,添加依赖后点击“Packages get”按钮即可下载插件到本地,在代码中添加import语句就可以使用插件提供的接口:
import ‘package:shared_preferences/shared_preferences.Dart’;class _MyAppState extends State { int _count = 0; static const String COUNTER_KEY = ‘counter’; _MyAppState() { init(); } init() async { var pref = await SharedPreferences.getInstance(); _count = pref.getInt(COUNTER_KEY) ?? 0; setState(() {}); } increaseCounter() async { SharedPreferences pref = await SharedPreferences.getInstance(); pref.setInt(COUNTER_KEY, ++_count); setState(() {}); }…
Dart
Dart是一种强类型、跨平台的客户端开发语言。具有专门为客户端优化、高生产力、快速高效、可移植(兼容ARM/x86)、易学的OO编程风格和原生支持相应式编程(Stream & Future)等优秀特性。Dart主要由Google负责开发和维护,在2011年10启动项目,2017年9月发布第一个2.0-dev版本。
Dart自己提供了三种运行方式:
- 使用Dart2js编译成JavaScript代码,运行在常规浏览器中(Dart Web)。
- 使用DartVM直接在下令行中运行Dart代码(DartVM)。
- AOT方式编译成机器码,比方Flutter App框架(Flutter)。
Flutter在筛选了20多种语言后,最终选择Dart作为开发语言主要有几个缘故原由:
- 健全的类型系统,同时支持静态类型检查和运行时类型检查。
- 代码体积优化(Tree Shaking),编译时只保留运行时需要调用的代码(不允许反射这样的隐式引用),所以庞大的Widgets库不会造成发布体积过大。
- 丰富的底层库,Dart自身提供了非常多的库。
- 多生代无锁垃圾接纳器,专门为UI框架中常见的大量Widgets对象创建和销毁优化。
- 跨平台,iOS和Android共用一套代码。
- JIT & AOT运行模式,支持开发时的快速迭代和正式发布后最大水平发挥硬件性能。
在Dart中,有一些紧张的根本概念需要相识:
- 所有变量的值都是对象,也就是类的实例。甚至数字、函数和null也都是对象,都继承自Object类。
- 虽然Dart是强类型语言,但是显式变量类型声明是可选的,Dart支持类型推断。如果不想使用类型推断,可以用dynamic类型。
- Dart支持泛型,List表示包罗int类型的列表,List则表示包罗恣意类型的列表。
- Dart支持顶层(top-level)函数和类成员函数,也支持嵌套函数和本地函数。
- Dart支持顶层变量和类成员变量。
- Dart没有public、protected和private这些关键字,使用下划线“_”开头的变量或者函数,表示只在库内可见。参考库和可见性。
DartVM的内存分配计谋非常简单,创建对象时只需要在现有堆上移动指针,内存增长始终是线形的,省去了查找可用内存段的过程:
Dart中雷同线程的概念叫做Isolate,每个Isolate之间是无法共享内存的,所以这种分配计谋可以让Dart实现无锁的快速分配。
Dart的垃圾接纳也接纳了多生代算法,新生代在接纳内存时接纳了“半空间”算法,触发垃圾接纳时Dart会将当前半空间中的“活泼”对象拷贝到备用空间,然后整体开释当前空间的所有内存:
整个过程中Dart只需要操作少量的“活泼”对象,大量的没有引用的“殒命”对象则被忽略,这种算法也非常适合Flutter框架中大量Widget重建的场景。
Flutter Framework
Flutter的框架部分完全使用Dart语言实现,并且有着清晰的分层架构。分层架构使得我们可以在调用Flutter提供的便捷开发功能(预界说的一套高质量Material控件)之外,还可以直接调用甚至修改每一层实现(由于整个框架都属于“用户空间”的代码),这给我们提供了最大水平的自界说本领。Framework底层是Flutter引擎,引擎主要负责图形绘制(Skia)、笔墨排版(libtxt)和提供Dart运行时,引擎全部使用C++实现,Framework层使我们可以用Dart语言调用引擎的强大本领。
分层架构
Framework的最底层叫做Foundation,其中界说的多数是非常基础的、提供给其他所有层使用的工具类和方法。绘制库(Painting)封装了Flutter Engine提供的绘制接口,主要是为了在绘制控件等固定样式的图形时提供更直观、更方便的接口,比如绘制缩放后的位图、绘制文本、插值生成阴影以及在盒子四周绘制边框等等。
Animation是动画相关的类,提供了雷同Android系统的ValueAnimator的功能,并且提供了丰富的内置插值器。Gesture提供了手势识别相关的功能,包括触摸事故类界说和多种内置的手势识别器。GestureBinding类是Flutter中处理手势的抽象服务类,继承自BindingBase类。
Binding系列的类在Flutter中充当着雷同于Android中的SystemService系列(ActivityManager、PackageManager)功能,每个Binding类都提供一个服务的单例对象,App最顶层的Binding会包罗所有相关的Bingding抽象类。如果使用Flutter提供的控件进行开发,则需要使用WidgetsFlutterBinding,如果不使用Flutter提供的任何控件,而直接调用Render层,则需要使用RenderingFlutterBinding。
Flutter自己支持Android和iOS两个平台,除了性能和开发语言上的“native”化之外,它还提供了两套设计语言的控件实现Material & Cupertino,可以资助App更好地在不同平台上提供原生的用户体验。
渲染库(Rendering)
Flutter的控件树在实际表现时会转换成对应的渲染对象(RenderObject)树来实现布局和绘制操作。一般环境下,我们只会在调试布局,或者需要使用自界说控件来实现某些特殊结果的时候,才需要思量渲染对象树的细节。渲染库主要提供的功能类有:
abstract class RendererBinding extends BindingBase with ServicesBinding, SchedulerBinding, HitTestable { … }abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin implements HitTestTarget {abstract class RenderBox extends RenderObject { … }class RenderParagraph extends RenderBox { … }class RenderImage extends RenderBox { … }class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, FlexParentData>, RenderBoxContainerDefaultsMixin<RenderBox, FlexParentData>, DebugOverflowIndicatorMixin { … }
RendererBinding是渲染树和Flutter引擎的胶水层,负责管理帧重回、窗口尺寸和渲染相关参数变化的监听。RenderObject渲染树中所有节点的基类,界说了布局、绘制和合成相关的接口。RenderBox和其三个常用的子类RenderParagraph、RenderImage、RenderFlex则是详细布局和绘制逻辑的实现类。
在Flutter界面渲染过程分为三个阶段:布局、绘制、合成,布局和绘制在Flutter框架中完成,合成则交由引擎负责:
控件树中的每个控件通过实现RenderObjectWidget#createRenderObject(BuildContext context) → RenderObject方法来创建对应的不同类型的RenderObject对象,组成渲染对象树。由于Flutter极大地简化了布局的逻辑,所以整个布局过程中只需要深度遍历一次:
渲染对象树中的每个对象都会在布局过程中接受父对象的Constraints参数,决定自己的巨细,然后父对象就可以按照自己的逻辑决定各个子对象的位置,完成布局过程。
子对象不存储自己在容器中的位置,所以在它的位置发生改变时并不需要重新布局或者绘制。子对象的位置信息存储在它自己的parentData字段中,但是该字段由它的父对象负责维护,自身并不关心该字段的内容。同时也由于这种简单的布局逻辑,Flutter可以在某些节点设置布局边界(Relayout boundary),即当边界内的任何对象发生重新布局时,不会影响边界外的对象,反之亦然:
布局完成后,渲染对象树中的每个节点都有了明白的尺寸和位置,Flutter会把所有对象绘制到不同的图层上:
由于绘制节点时也是深度遍历,可以看到第二个节点在绘制它的配景和远景不得不绘制在不同的图层上,由于第四个节点切换了图层(由于“4”节点是一个需要独占一个图层的内容,比如视频),而第六个节点也一起绘制到了红色图层。这样会导致第二个节点的远景(也就是“5”)部分需要重绘时,和它在逻辑上绝不干系但是处于同一图层的第六个节点也必须重绘。为了制止这种环境,Flutter提供了别的一个“重回边界”的概念:
在进入和走出重绘边界时,Flutter会逼迫切换新的图层,这样就可以制止边界表里的相互影响。典型的应用场景就是ScrollView,当滚动内容重绘时,一般环境下其他内容是不需要重绘的。虽然重绘边界可以在任何节点手动设置,但是一般不需要我们来实现,Flutter提供的控件默认会在需要设置的地方主动设置。
控件库(Widgets)
Flutter的控件库提供了非常丰富的控件,包括最根本的文本、图片、容器、输入框和动画等等。在Flutter中“一切皆是控件”,通过组合、嵌套不同类型的控件,就可以构建出恣意功能、恣意复杂度的界面。它包罗的最主要的几个类有:
class WidgetsFlutterBinding extends BindingBase with GestureBinding, ServicesBinding, SchedulerBinding, PaintingBinding, RendererBinding, WidgetsBinding { … }abstract class Widget extends DiagnosticableTree { … }abstract class StatelessWidget extends Widget { … }abstract class StatefulWidget extends Widget { … }abstract class RenderObjectWidget extends Widget { … }abstract class Element extends DiagnosticableTree implements BuildContext { … }class StatelessElement extends ComponentElement { … }class StatefulElement extends ComponentElement { … }abstract class RenderObjectElement extends Element { … }…
最后
给各人分享一份移动架构大纲,包罗了移动架构师需要掌握的所有的技术体系,各人可以对比一下自己不足或者欠缺的地方有方向的去学习提升;
最后
给各人分享一份移动架构大纲,包罗了移动架构师需要掌握的所有的技术体系,各人可以对比一下自己不足或者欠缺的地方有方向的去学习提升;
[外链图片转存中…(img-fEwHp87B-1726045317777)]
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |