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

相關文章
相關標籤/搜索