Flutter介绍与基本使用
1、 环境以及工具的准备
1 下载Flutter SDK
https://flutter.dev/docs/get-started/install/macos
并将其bin路径加入系统路径中
java
IDE使用
AndroidStudio使用Flutter
Android Studio 安装插件 Flutter和Dart插件android
GeneratedPluginRegistrant 将Android的Activity注册给Flutter
FlutterActivity/FlutterAppDelegate,是Android的Plugin管理器,它记录了全部的Plugin,并将Plugin绑定到FlutterView/FlutterViewController
ios
Flutter inspector
Flutter Outline
Flutter Performance
web
XCodemacos
VS Code运行Dart
安装Dart SDK缓存
brew tap dart-lang/dart brew install dart dart --version
VS Code安装插件
Dart 和 Code Runner插件
并发
3app
2、Flutter介绍
移动端的UI框架框架
1 能够与原生的Android 和 IOS混合开发
上层FrameWork 使用Dart语言实现 有Material Design(Android)和Cupertino(IOS)风格的Widgets
函数
中间层使用C++编写的 Skia库(二维图形库)
不是经过使用原生控件,而是本身渲染 布局是树结构形式
Skia in Flutter
Flutter用了skia做为自绘制的渲染库,所以能实现很好的跨平台能力,以及有较高的性能。底层仍是使用了OpenGL经过GPU实现硬件渲染
而WebView的软件渲染方式也是用到了skia库,只是多了一层chromium(低版本是webkit)引擎进行渲染
Dart部分主要包括:Dart Runtime,Garbage Collection(GC),若是是Debug模式的话,还包括 JIT(Just In Time) 支持。
Release和Profile模式下,是**AOT(Ahead Of Time)**编译成了原生的arm代码
Text部分用来进行文本渲染
底层的platform为IOS 和 Android平台
经过Platform Channel 与 native的服务进行通讯
JS Bridge
2 Webview跨平台能力最强,可是性能最差 经过JS Bridge操做原生服务
跨平台能力与RN Weex至关 可是性能要优于他们 由于不涉及JS Bridge 控件也是本身渲染的
热重载(Hot Reload),利用Android Studio直接一个ctrl+\就能够保存并热重载
优势:
1 性能高 C++, AOT,skia渲染
目前的缺点
1 安装包过大
2 无webview 要使用插件
3 不支持热更新 热修复
Flutter结构
FrameWork层
Engine层 skia、Dart(DartRuntime,GC、JIT(debug下)、Text
Flutter Application: Flutter的终端应用
Flutter Module: Flutter模块 原生的Android或者IOS能够引入Flutter Module进行混合开发
Flutter Plugin: 封装原生的Android或者IOS 提供API给Flutter使用
Flutter Package: 纯Dart语言的组件 如自定义Widget
Flutter Application
目录结构:
/android Android项目 能够只打开这个项目
有个 io.flutter.plugins的目录 里面有 GeneratedPluginRegistrant
用于
/ios IOS项目 能够只打开这个项目
/.lib 存放dart的代码
C和dart通讯
FFI
DynamicLibrary.open 加载动态库
funtion func = xxLibrary.lookup
去动态库找到指定的函数
将C的函数转为dart的function
怎么与native通讯
Flutter与Android交互原理
1、FlutterActivity
FlutterView getFlutterView()
1 FlutterView extends SurfaceView
经过skia渲染引擎
2 FlutterActivityDelegate
addContentView 将FlutterView加入到Activity中
2、FlutterApplication
经过FlutterMain.java 加载flutter.so flutter的config AOT 和 Resource
编译Dart生成了snapshot(相似jar包)经过函数main作入口
最终生成flutter.jar?
怎么调native API
怎么依附于Activity
怎么打成包
Dart
静态强类型
没有null检查
能够AOT能够JIT
直接编译成本地代码 不须要JS那种的桥 形成上下文频繁的切换 各类保留现场的状态保存 所以启动速度和运行速度快
UI也是直接绘制的 性能高
Dart 避免了抢占式调度和共享内存(于是也不须要锁)
isolate 单线程模型
isolate是Dart对actor并发模式的实现。运行中的Dart程序由一个或多个actor组成,这些actor也就是Dart概念里面的isolate。isolate是有本身的内存和单线程控制的运行实体。isolate自己的意思是“隔离”,由于isolate之间的内存在逻辑上是隔离的。isolate中的代码是按顺序执行的,任何Dart程序的并发都是运行多个isolate的结果。由于Dart没有共享内存的并发,没有竞争的可能性因此不须要锁,也就不用担忧死锁的问题
root isolate进行UI处理
isolate间的通讯
管道:ReceivePort与SendPort一块儿,是隔离区之间惟一的通讯方式
isolate与普通线程的区别
咱们能够看到isolate神似Thread,但实际上二者有本质的区别。操做系统内的线程之间是能够有共享内存的而isolate没有,这是最为关键的区别
dart2js 编译器能够将dart代码直接生成js代码 运行在web中
Dart VM
界面跳转
经过Navigator栈统一管理界面的跳转
Router路由的概念 每一个界面都是一个Router
使用:
经过一个自定义路由命名进行区分跳转,这样更清晰
Router.pushNoParams(BuildContext context, String url) { Navigator.push(context, MaterialPageRoute(builder: (context) { return _getPage(url, null); })); } Router.push(BuildContext context, String url, dynamic params) { Navigator.push(context, MaterialPageRoute(builder: (context) { return _getPage(url, params); })); } static const secondPage = 'app://SecondPage'; Widget _getPage(String url, dynamic params) { if (url.startsWith('https://') || url.startsWith('http://')) { return WebViewPage(url, params: params); } else { switch (url) { case secondPage: return SecondPage(params); 退出调用 Router.pop()便可
若要传递参数 则构造函数的参数里面携带就好
Flutter inspector
Flutter API设计理念
1 Compose not complect 组合而非交织
2 层级式设计
高层API要包裹好底层API 不要实现断崖式设计
即底层API不须要对外暴露 给外边调用或者实现
Flutter命令
是否将输出内容着色显示,在终端,--color是默认值;不然,--no-color是默认值 // 下载相应的flutter库 flutter packages get // dart的pub命令参考:https://dart.cn/tools/pub/cmd // 从命令行运行脚本 // global: 不存在于当前 Package 中的可执行对象 // [arg1] [arg2]为脚本的参数 flutter pub [global] run xx [arg1] [arg2] // 删除`build/`和`.dart_tool/`目录,清除缓存信息,避免以前不一样版本代码的影响 flutter clean // 安装包到设备上 flutter install // 运行应用 flutter run
flutter常见文件
pubspec.yaml
添加库依赖的
有^的第一次会下载最新版本的
dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter intl: ^0.16.1
pubspec.lock
文件中描述的就是你各类依赖包的真实版本和下载地址。固然还有lock的做用,当你下次刷新项目时,pub get会根据lock中的描述去获取依赖包。即便有新的版本也不会跟新到。此时能够经过 pub upgrade来更新
Flutter常见错误
1 Process ‘command ‘/Users/maxshwu/project/FlutterSDK/flutter/bin/flutter’’ finished with non-zero exit value 1
解决: 看Dart Analysis中的dart错误
2 Cause: assert pluginDirectory.exists()
缘由: 删掉了plugin后报的错
解决: 将相关使用plugin的地方删掉
flutter clean
flutter packages get 去下载相应的flutter库
3 Another exception was thrown: NoSuchMethodError: The method ‘-’ was called on null.
能够搜索一下(The relevant error-causing widget was:)看看是哪一个控件可能出现的问题(也有多是这个控件的子控件的问题)
如:The method ‘[]’ was called on null
缘由: 调用[]的对象是空的
解决: 给这个对象作好判空处理
如:The method ‘-’ was called on null
缘由:
1 column嵌套了Row
2 Row嵌套了非标志/非合理的Widget
解决:
1 给row加一层布局
2 使用系统控件或者标志的自定义控件
4 error: The name ‘Image’ is defined in the libraries ‘package:flutter/src/widgets/image.dart’ and ‘package:image/src/image.dart’. — ambiguous_import
缘由: 两个import的文件都包含了这个类,多重定义了
解决: import ‘package:flutter/src/widgets/image.dart’ as MyImg;
MyImg.xxx()
5 No active package intl_utils.
pub global activate intl_utils
6 Entrypoint isn’t within a Flutter pub root
1 https://stackoverflow.com/questions/57000043/error-entrypoint-isnt-within-the-current-project
2 将gtest和gmock从项目中移除
7 点击Flutter Attach 以后长时间不能连接到设备
flutter docotr -v 诊断下 看是否代理问题
export NO_PROXY=localhost,127.0.0.1
8 Could not resolve the package ‘xxx’ in ‘xxx/xxx.dart’. 1 flutter packages get 2 从新build一下flutter的module flutter build aar