Flutter介绍与基本使用

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

相关文章
相关标签/搜索