Dart语言都是值传递,每次调用函数都是传递对象的内存地址,而不是复制对象
优点:热重载(Hot Reload)
缺点:不支持热更新,三方库有限,需要自己造轮子
Flutter的FrameWork层是用Drat编写的框架(SDK),它实现了一套基础库,组件库,比Engine上层
Flutter的Engine层是Skia 2D的绘图引擎库,跟GPU交互
StatelessWidget: 一旦创建就不关心任何变化,在下次构建之前都不会改变;
StatefulWidget: 在生命周期内,该类Widget所持有的数据可能会发生变化,这样的数据被称为State;
1.生命周期:
StatefulWidget ----> initState -----> didChangeDependencies ----> build (中间会插入 didUpdateWidget) ----> deactivate ----> dispose
2. 这个就是Flutter面向对象
继承 extends 混入mixins 接口实现 implements
优先继承,其次混入,最后接口实现
mixins不能有构造函数,其实也是单继承;
抽象类abstract:父类可以只声明,不实现;由子类去实现;
私有变量加_,其他默认公开
3.Flutter渲染三棵树
WidgetTree:存放渲染内容,只是一个配置数据结构;
Element:中间层,同时持有Widget和RenderObject,会去遍历视图树;
RenderObject:负责真正的界面布局和渲染,包含大小和布局等信息,实例化RenderObject很耗时;
4.Widget分类
组合类:StatefulWidget和StatelessWidget
代理类:inheritedWidget和parentDataWidget:通过context获取共享状态
绘制类:RenderObjectWidget:布局相关方法调用顺序:layout(准备布局) --->performResize(计算大小) ---> performLayout(开始布局) ---> markNeedPaints(是否需要重绘)
5.单订阅和多订阅(Stream)
single和broadcast;Stream 默认处于单订阅模式,所以同一个 stream 上的 listen 和其它大多数方法只能调用一次,调用第二次就会报错。但 Stream 可以通过 transform() 方法(返回另一个 Stream)进行连续调用。通过 Stream.asBroadcastStream() 可以将一个单订阅模式的 Stream 转换成一个多订阅模式的 Stream
6.Widget State Context
Widget:Widget就是可视化组件,里面的结构是树状的,所以说是WidgetTree,父Widget和子Widget;
State:是StatefulWidget的实例化行为,可以交互和干预Widget的状态和布局,任何变更都会触发重建Widget;
Context:每一个Widget都会有对应的Widget,用来描述它的位置引用,是Widget树的一部分;
7.Isolate执行顺序和Future,Stream的区别
Main(主事件) ---> MicroTask(微事件) ----> EventQueue(事件循环);
最后就在微事件和事件循环中反复循环,并且遵循先进先出
Isolate实际是一个隔离的Dart上下文环境(容器)。并且不同的Isolate线程之间的通信通过port来异步进行,在内存上是隔离开的
耗时长的并且影响应用流畅性的就用Isolate(比如图片处理,JSON解析),如果耗时短的就用Future;
Isolate.spawn() 和Isolate.exit()
Future表示延迟运行的对象,用来表示一个潜在的值返回或错误返回,这个返回值将在未来的某个时刻才可用。Future的调用者可以注册回调,一旦返回值或错误可用,就可以通过回调函数对其进行处理。
Future.delayed:创建在延迟一定时间后运行的Future
Future.microtask:创建包含使用scheduleMicrotask异步调用计算的结果的Future
Future.value:创建一个有值返回的Future
Future.sync:返回包含立即调用计算结果的future
Stream:在Dart中,Stream 和 Future 一样,都是用来处理异步编程的工具。它们的区别在于,Stream 可以接收多个异步结果,而Future 只有一个。多个是asBroadcastStream()。
await for 如何使用?
await for是不断获取stream流中的数据,然后执行循环体中的操作。它一般用在直到stream什么时候完成,并且必须等待传递完成之后才能使用,不然就会一直阻塞
8.组件渲染怎么完成的
通过代码来构建视图结构数据,然后通过Skia图像引擎加工成GPU数据,最后通过OpenGL提供给GPU渲染
9.PlatformView原理
Platform view 就是 AndroidView 和 UIKitView 的总称,允许将native view嵌入到Widget体系中,完成Dart对native view的控制;
Platform view 是在 native 侧渲染的,并且底层实际是使用texture实现,通过_textureId来展示,所以Platform view开销很大。因为需要从GPU切换到CPU,然后再切换到GPU,所以尽量避免使用Platform view;一般使用是webView;
Platform view大小由父节点的大小来控制,所以需要用Expanded包裹,不然就是父视图的大小;
10.Flutter 线程管理模型
线程管理模型:Flutter Engine会创建一个isolate,dart代码运行在这个主isolate上,新创建的isolate由flutter进行统一管理。
Flutter的线程管理由一个叫Embeder的中间层组件控制,Embeder提供了四个Task,分别是UITaskRunner、IOTaskRunner、GPUTaskRunner、platformTaskRunner
UITaskRunner:负责绑定渲染相关的操作,如timer,microtask,异步io操作;
IOTaskRunner:处理图片数据,为gpu渲染做准备,比如读取磁盘压缩图片的格式,将解压成gpu能处理的格式,并传给gpu,因其比较消耗性能所以单独开一个线程。
GPUTaskRunner:用于执行gpu指令,负责将layer tree提供的信息转换为平台可执行的gpu指令
platformTaskRunner:所有接口调用都使用该接口,长时间卡顿将会被watchdog强杀。
11.Flutter状态管理
状态管理:
view:界面层,主要是UI
Logic:逻辑层,主要处理业务逻辑
State:状态层,主要处理页面所需数据状态
Action:行为层,主要处理交互事件
Reducer:这个层级,是专门用于处理数据变化的
Provider:是最为推荐的状态管理库,对InheritedWidget进行了上层封装,解决原生setState方案的props臃肿、展示与逻辑耦合问题;Provider将页面分为业务和视图两层,并定义Notifier、Consumer两个核心概念
Notifier负责实现业务逻辑,且在数据更新时发出通知。
Consumer负责实现界面逻辑,并在数据更新时更新自身,以及用户交互时调用Notifier方法。
12.Flutter如何与原生Android,iOS进行通信
Flutter通过PlatformChannel与原生进行交互,总共有三种:
BasicMessageChannel:传递字符串和半结构化信息;
MethodChannel:传递方法调用;一般就是MethodChannel.result;
EventChannel:传递数据流(event streams);
13.Flutter的热重载
基于JIT编译模式的代码增量同步,总共分为五步:
扫描工程改动;增量编译;推送更新;代码合并;Widget重建;
所以并不会让APP重新启动,缩短时间;
14.Flutter布局
Row (行布局)
Column (列布局)
Container (容器)
ListView(类似iOS中的UITableView):GlobalKey,通过 key 去获取到控件对象的 BuildContext(其实就是RenderObject);
15.Flutter集成声网
在initState方法里初始化RtcEngine对象,通过initAgoraRtc和addAgoraEventHandlers,和joinChannel;
在回调中有加入频道,离开频道,用户加入频道,第一次个视频帧渲染回调;
聊天相关的是单独的createClient,通过AgoraRtmClient来管理用户聊天等相关信息
-------------------------------------------------------------------------------------------------
Dart相关
1.Dart是类型安全的语言,它会自动做类型转换;并且会有静态检查和运行时检查;
所以它的维护性高,编译器就可以显示类型错误;
2.类型
Number String Bool List Set Map Null