简介
A
阿里技术-简书博客
Android Flutter 内存机制初探 -2018.05.23
[移动开发新利器 | 一文深入了解 Flutter 界面开发 -2018.06.06](https://www.jianshu.com/p/fe604938df0a) |
深入理解 Flutter 的编译原理与优化 - 2018.07.06
阿里闲鱼公众号(Flutter技术)
Flutter Plugin调用Native APIs - 2018.06.23
GMTC-闲鱼Flutter实践效果访谈 - 2018.06.29
Release Flutter的最后一公里 - 2018.07.10
京东金融技术公众号(Flutter技术)
京东金融客户端初探Flutter框架 -2018.03.05
B
C
D
E
F
Flutter中文网
Flutter文档说明
Flutter掘金论坛
Flutter提供的基础库集合
Flutter提供的Widget 索引集合
Flutter的API文档
Flutter整体框架图
1.选择库
2.选择Class
3.查看 Method 和 Property
CONSTRUCTORS 构造函数 PROPERTIES 属性 METHODS 方法 OPERATORS 操作符 STATIC METHODS 静态方法 CONSTANTS 常数
Flutter 开源项目
dio 一个强大的Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时等
CookieJar 一个实现HTTP协议标准Cookie管理策略的Cookie管理器,他可以自动帮您自动管理http请求cookie,并支持本地持久化
Flutter中文开发者论坛
G
H
I
J
简书Flutter
Flutter学习总结系列—-第一章、Flutter基础全面详解-2018.06.21
掘金社区文章
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
语句
import 'package:flutter/material.dart';
void main() {
runApp( new XXXX);
}
1.
runApp函数接受给定的Widget参数,并使其成为widget树的根
2.
框架强制根widget覆盖整个屏幕
3.
widget是无状态的StatelessWidget或者是有状态的StatefulWidget, 具体取决于您的widget是否需要管理一些状态
为了构建更复杂的体验(根据用户输入改变widget) - 例如,以更有趣的方式对用户输入做出反应 - 应用程序通常会携带一些状态。
Flutter使用StatefulWidgets来满足这种需求。StatefulWidgets是特殊的widget,它知道如何生成State对象,然后用它来保持状态。
4.
为什么StatefulWidget和State是单独的对象?
在Flutter中,这两种类型的对象具有不同的生命周期: Widget是临时对象,用于构建当前状态下的应用程序,
而State对象在多次调用build()之间保持不变,允许它们记住信息(状态)。
自定义 CustomWidget 继承自StatefulWidget,这意味着这个widget可以存储状态。 当 CustomWidget 首次插入到树中时,
框架会调用其 createState 函数以创建一个新的 _CustomWidgetState 状态实例
来与该树中的相应位置关联(请注意,我们通常命名State子类时带一个下划线,这表示其是私有的)。
当这个 CustomWidget 的父级Widget重建时,父级Widget将创建一个新的 CustomWidget 实例,
但是Flutter框架将重用已经在树中的 _CustomWidgetState 实例,而不是再次调用createState创建一个新的。
为什么build()方法在State(而不是StatefulWidget)上?
将 Widget build(BuildContext context)方法放在State上而不是StatefulWidget上是为了在继承StatefulWidget时能更加灵活
5.
widget的主要工作是实现一个build函数,用以构建自身
6.
一个widget通常由一些较低级别widget组成。Flutter框架将依次构建这些widget,直到构建到最底层的子widget时,这些最低层的widget通常为【RenderObject】,它会计算并描述widget的几何形状。
7.
基础 Widget:
Text:该 widget 可让创建一个带格式的文本。
Row、 Column: 这些具有弹性空间的布局类Widget可让您在水平(Row)和垂直(Column)方向上创建灵活的布局
Stack: 取代线性布局 (译者语:和Android中的LinearLayout相似),Stack允许子 widget 堆叠
Container: Container 可让您创建矩形视觉元素。container 可以装饰为一个BoxDecoration, 如 background、一个边框、或者一个阴影。 Container 也可以具有边距(margins)、填充(padding)
8.
在Flutter中,Widget树中,事件流是“向上”传递的 (从叶子节点触发 目标节点》父节点》根节点),而状态流是“向下”传递的 (从根节点》父节点》子节点)
9.
当我们跑起整个Flutter应用时:
void main() {
runApp(new MyApp());
}
runApp其实就会执行WidgetsFlutterBinding.ensureInitialized方法初始化各个Binding:
void runApp(Widget app) {
WidgetsFlutterBinding.ensureInitialized() 【初始化】
..attachRootWidget(app) 【 attachRootWidget 初始化完成后 把参数 Widget 放到 Root根节点】
..scheduleWarmUpFrame();
}
void attachRootWidget(Widget rootWidget) { 【attachRootWidget 详情】
_renderViewElement = new RenderObjectToWidgetAdapter<RenderBox>(
container: renderView, 【Flutter的实际的根节点 我们传递runApp()的Widget是 该节点的子节点 】
debugShortDescription: '[root]',
child: rootWidget
).attachToRenderTree(buildOwner, renderViewElement);
}
10. State的 initState 函数和 dispose 函数
在StatefulWidget调用createState之后,框架将新的状态对象插入树中,然后调用状态对象的initState。
子类化State可以重写 initState,以完成仅需要执行一次的工作
当一个状态对象不再需要时,框架调用状态对象的 dispose。 您可以覆盖该dispose方法来执行清理工作。
11.
在Flutter中,widget由其底层的RenderBox对象渲染。 渲染框由它们的父级给出约束,并且在这些约束下调整自身大小。
通常,按照widget如何处理他们的约束来看,有三种类型的盒子: 所谓的“盒”即指自身的渲染框。
尽可能大。 例如 Center 和 ListView 的渲染盒
跟随子widget大小。 例如, Transform 透明度和 Opacity 模糊度 的渲染盒。
指定尺寸。 例如, Image 和 Text的渲染盒
一些widget,例如Container, 会根据构造函数参数的不同而不同。Container默认是尽可能大的占用空间, 但是如果你给它指定一个width,那它就会采用指定的值。
Flex 弹性盒自身(Row和Column) 的行为有所不同,这取决于它们在给定的方向上是处于有边界的限制还是无边界的限制下。在有边界的限制下,他们在这个方向上会尽可能大。
12.手势
手势表示可以从多个单独的指针事件(甚至可能是多个单独的指针)识别的语义动作(例如,轻敲,拖动和缩放)。 完整的一个手势可以分派多个事件,对应于手势的生命周期(例如,拖动开始,拖动更新和拖动结束):
Tap
onTapDown 指针已经在特定位置与屏幕接触
onTapUp 指针停止在特定位置与屏幕接触
onTap tap事件触发
onTapCancel 先前指针触发的onTapDown不会在触发tap事件
双击
onDoubleTap 用户快速连续两次在同一位置轻敲屏幕.
长按
onLongPress 指针在相同位置长时间保持与屏幕接触
垂直拖动
onVerticalDragStart 指针已经与屏幕接触并可能开始垂直移动
onVerticalDragUpdate 指针与屏幕接触并已沿垂直方向移动.
onVerticalDragEnd 先前与屏幕接触并垂直移动的指针不再与屏幕接触,并且在停止接触屏幕时以特定速度移动
水平拖动
onHorizontalDragStart 指针已经接触到屏幕并可能开始水平移动
onHorizontalDragUpdate 指针与屏幕接触并已沿水平方向移动
onHorizontalDragEnd 先前与屏幕接触并水平移动的指针不再与屏幕接触,并在停止接触屏幕时以特定速度移动
要从widget层监听手势,请使用 GestureDetector.
如果您使用的是Material Components,那么大多数widget已经对tap或手势做出了响应。 例如 IconButton和 FlatButton 响应presses(taps),ListView响应滑动事件触发滚动
手势消歧
在屏幕上的指定位置,可能会有多个手势检测器。所有这些手势检测器在指针事件流经过并尝试识别特定手势时监听指针事件流。 GestureDetectorwidget决定是哪种手势。
当屏幕上给定指针有多个手势识别器时,框架通过让每个识别器加入一个“手势竞争场”来确定用户想要的手势。“手势竞争场”使用以下规则确定哪个手势胜出
在任何时候,识别者都可以宣布失败并离开“手势竞争场”。如果在“竞争场”中只剩下一个识别器,那么该识别器就是赢家
在任何时候,识别者都可以宣布胜利,这会导致胜利,并且所有剩下的识别器都会失败
例如,在消除水平和垂直拖动的歧义时,两个识别器在接收到指针向下事件时进入“手势竞争场”
13.Flutter和Android中的View
在Android中,View是屏幕上显示的所有内容的基础, 按钮、工具栏、输入框等一切都是View。
在Flutter中,View相当于是Widget。然而,与View相比,Widget有一些不同之处。
首先,Widget仅支持一帧,并且在每一帧上,Flutter的框架都会创建一个Widget实例树(译者语:相当于一次性绘制整个界面)
比之下,在Android上View绘制结束后,就不会重绘,直到调用invalidate时才会重绘。
与Android的视图层次系统不同(在framework改变视图),而在Flutter中的widget是不可变的,这允许widget变得超级轻量。
14.
在Flutter中您可以通过挂接到WidgetsBinding观察并监听didChangeAppLifecycleState更改事件来监听生命周期事件
您可以监听到的生命周期事件是
resumed - 应用程序可见并响应用户输入。这是来自Android的onResume
inactive - 应用程序处于非活动状态,并且未接收用户输入。此事件在Android上未使用,仅适用于iOS
paused - 应用程序当前对用户不可见,不响应用户输入,并在后台运行。这是来自Android的暂停
suspending - 该应用程序将暂时中止。这在iOS上未使用
import 'package:flutter/widgets.dart';
class LifecycleWatcher extends StatefulWidget {
@override
_LifecycleWatcherState createState() => new _LifecycleWatcherState();
}
class _LifecycleWatcherState extends State<LifecycleWatcher> with WidgetsBindingObserver {
AppLifecycleState _lastLifecyleState;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
_lastLifecyleState = state;
});
}
@override
Widget build(BuildContext context) {
if (_lastLifecyleState == null)
return new Text('This widget has not observed any lifecycle changes.', textDirection: TextDirection.ltr);
return new Text('The most recent lifecycle state this widget observed was: $_lastLifecyleState.',
textDirection: TextDirection.ltr);
}
}
void main() {
runApp(new Center(child: new LifecycleWatcher()));
}
15.
Android将内存分为Java虚拟机内存和Native内存,各大厂商都对Java虚拟机内存有一个上限限制,到达上限就会触发OOM异常,而对Native内存的使用没有太严格的限制,现在的手机内存都很大,一般有较大的Native内存富余
使用Android profiler来观察内存
Java虚拟机内存: 从Java或者Kotlin 代码分配的对象的内存
Native内存: 从C C++ 代码分配对象的内存
Graphics: 图形缓冲区队列向屏幕显示像素所使用的内存
Android原生的ImageView在6.0和7.0版本中使用的Java虚拟机内存,而在Android 8.0中则使用的Native内存。
Flutter Image使用的内存既不属于Java虚拟机内存也不属于Native内存,而是Graphics内存