Google 跨平台方案 Flutter 從入門到實戰
本文由 提供寫作贊助
贊助金額:
原作者:
版權聲明:本文版權歸微信公眾號玉剛說所有,未經許可,不得以任何形式轉載
前言
2018年2月27日,在2018世界移動大會上,Google發布了Flutter的第一個Beta版本。Flutter是Google用以幫助開發者在 Android/IOS 兩個平台開發高質量原生應用的全新移動UI框架。
熱重載(Hot Reload),作為一個安卓開發者,能熱重載真的太舒服了,利用Android Studio直接一個ctrl+s就可以保存並重載,模擬器立馬就可以看見效果。
一切皆為Widget的理念,對於Flutter來說,手機應用里的所有東西都是Widget,通過可組合的空間集合、豐富的動畫庫以及分層課擴展的架構實現了富有感染力的靈活界面設計。
藉助可移植的GPU加速的渲染引擎以及高性能本地代碼運行時以達到跨平台設備的高質量用戶體驗。
這段介紹是直接抄下來的,雖然我並不知道什麼叫可移植的GPU加速的渲染引擎,但是最終結果就是利用Flutter構建的應用在運行效率上會和原生應用差不多,那麼我們開始走進 Flutter 的世界吧。
本文章的結構如下:
如何搭建 Flutter 開發環境
Dart的優點和基本用法
如何使用平台特性API
除去UI部分,代碼如何在 Android/IOS 復用
實現一個案例
Flutter進行開發 Android/IOS
tips: 本文在蘋果筆記上開發,因為需要調試 IOS 和 Android
這裡我用 Android Studio 開發 Flutter ,下邊我們來看一下開發步驟。
準備工作
安裝Android Studio 中 Flutter 和 Dart 兩個插件(設置中Plugin搜索即可)
官網下載 fluter sdk(tip: 國內下載地址)
創建工程
安裝Xcode ,啟動一個IOS 模擬器
啟動一個 Android 模擬器
我這裡也是大概描述一下大概流程,為了節省篇幅,官網有更加詳細的步驟:
我首先推薦官網:
Flutter 官網
如果你想快速入門,這裡有
中文官網
Dart 語法
Dart 的優勢
當時我學習 Dart 語言的時候,一直思考 Dart 有什麼優勢?只有 Google 這個親爹的原因嗎?我帶著這個思考查了不少資料,發現 Dart 的優勢有如下幾點:
Dart 支持AOT編譯和JIT編譯兩種方式
Dart 是單線程的,這意味著它根本不允許搶佔
JIT編譯
JIT編譯在開發過程中使用,編譯器速度特別快。然後,當一個應用程序準備發布時,它被AOT編譯。因此,藉助先進的工具和編譯器,Dart具有兩全其美的優勢:極快的開發周期、快速的執行速度和極短啟動時間。
我們討論過一個有助於保持順暢的特性,那就是Dart能AOT編譯為本地機器碼。預編譯的AOT代碼比JIT更具可預測性,因為在運行時不需要暫停執行JIT分析或編譯。
AOT編譯
然而,AOT編譯代碼還有一個更大的優勢,那就是避免了「JavaScript橋樑」。當動態語言(如JavaScript)需要與平台上的本地代碼互操作時,它們必須通過橋進行通信,這會導致上下文切換,從而必須保存特別多的狀態(可能會存儲到輔助存儲)。這些上下文切換具有雙重打擊,因為它們不僅會減慢速度,還會導致嚴重的卡頓。
Dart 的 基本語法
如果你有 java 語言的基礎,發現dart裡邊的 API 幾乎 90% 以上相同, 幾乎很快能上手,這裡我就特別指出他們的不同點。這裡我想最快的入門方法,應該是查看官網的 quick start, 快速正版放心,而且不會過時,一直在更新。
這裡我簡單的介紹一下:
Hello World
變數的聲明
方法的定義
基本類型
條件判斷
循環語句
由於篇幅有限,我這裡列舉一下我認為特別的地方,剩下的可以仔細閱讀
官方文檔。
Hello World
我們萬年老套路 Hello World,熟悉他語言的運行機制。
我們可以以看到一下幾點:
能賦值給變數的所以東西都是對象,包括 numbers, null, function, 都是繼承自 Object 內置類
盡量給變數定義一個類型,會更安全,沒有顯示定義類型的變數在 debug 模式下會類型會是 dynamic(動態的)
dart 在 running 之前解析你的所有代碼,指定數據類型和編譯時的常量,可以提高運行速度
dart 提供了頂級函數(如:main())
dart 沒有 public、private、protected 這些關鍵字,變數名以"_"開頭意味著對它的 lib 是私有的
變數聲明
沒有初始化的變數都會被賦予默認值 null
程序中只當數據類型是為了指出自己的使用意圖,並幫助語言進行語法檢查。但是,指定類型不是必須的,類似於Kotlin 會進行類型推導。
基本類型
number取值範圍:-2^53 to 2^53
string
"""…""","""…"""表示多行字元串
r"…",r"…"表示「raw」字元串
用 $ 或 ${} 來計算字元串中變數的值
示例代碼:
bool布爾類型
Dart 是強 bool 類型檢查,只有bool 類型的值是true 才被認為是true
list列表
map散列表
條件判斷和循環
if…else
for
while do-while
break continue
switch…case 如果 case 後面有表達式但是沒有 break,會拋出異常
assert(僅在checked模式有效),如果條件為假,拋出異常
這裡我介紹了一下基本語法,還有函數、異常、單線程的操作,由於篇幅有限,而且我們也是一個入門教程,我這裡就介紹到這裡,如果想具體查看,可以點擊我推薦的官網教程,用的 dart2 的方式。
Flutter如何使用Android和iOS的平台特性
Flutter使用了一個靈活的系統,允許您調用特定平台的API,無論在Android上的Java或Kotlin代碼中,還是iOS上的ObjectiveC或Swift代碼中均可用。
Flutter平台特定的API支持不依賴於代碼生成,而是依賴於靈活的消息傳遞的方式:
應用的Flutter部分通過平台通道(platform channel)將消息發送到其應用程序的所在的宿主(iOS或Android)。
宿主監聽的平台通道,並接收該消息。然後它會調用特定於該平台的API(使用原生編程語言)並將響應發送回客戶端,即應用程序的Flutter部分。
調用流程如下:
跨端調用流程
電池電量的 banerry(1)創建一個新的應用程序項目
首先創建一個新的應用程序:
方式一:
在終端運行中:
默認情況下,模板支持使用Java編寫Android代碼,或使用Objective-C編寫iOS代碼。要使用Kotlin或Swift,請使用-i和/或-a標誌:
在終端中運行:
方式二:
也可以通過項目new Flutter Project 來創造項目
(2) 創建Flutter平台客戶端
該應用的State類擁有當前的應用狀態。我們需要延長這一點以保持當前的電量
首先,我們構建通道。我們使用MethodChannel調用一個方法來返回電池電量。
通道的客戶端和宿主通過通道構造函數中傳遞的通道名稱進行連接。單個應用中使用的所有通道名稱必須是唯一的;
接下來,我們調用通道上的方法,指定通過字元串標識符調用方法getBatteryLevel。 該調用可能失敗。
例如,如果平台不支持平台API(例如在模擬器中運行時),所以我們將invokeMethod調用包裝在try-catch語句中。
我們使用返回的結果,在setState中來更新用戶界面狀態batteryLevel。
最後,我們在build創建包含一個小字體顯示電池狀態和一個用於刷新值的按鈕的用戶界面。
(3) 在Android平台的代碼實現
接下來,在 ManActivity 中 的 onCreate里創建MethodChannel並設置一個MethodCallHandler。確保使用與在Flutter客戶端使用的通道名稱相同。
到此為止,我們介紹完如何使用兩個平台的特殊 API ,如果你在使用flutter 開發的時候,碰到官方沒有支持的api,你可以自己去實現兩個平台的代碼,來實現你想要的效果。
除去UI部分,代碼如何在 Android/IOS 復用
如果您希望在多個Flutter應用程序中使用特定於平台的代碼,將代碼分離為位於主應用程序之外的目錄中,做一個平台插件會很有用。這樣就可以把 UI 部分刨除掉,復用代碼部分。
我們可以開發插件來來實現我們要的通用的部分,如何開發一個插件呢?這裡我就不班門弄斧了,你可以直接查看官網提高的如何開發一個插件
實例展示
通過上邊的介紹,大家對於Flutter 有一定的理解,下面我們實現一個demo項目,如何我們開始進入實戰階段,我們具體實現的效果如圖下:
主頁(Tab欄+Banner輪播圖+ViewPaper):
主頁
抽屜:
創建一個項目
通過Android Studio new 一個flutter Project 項目,刪除lib/main.dart代碼,我們開始自己實現代碼。
添加 MaterialAPP
MaterialAPP 是一個方便的widget,它封裝了應用程序實現Material Design所需要的一些widget。Material 風格是我們一直想實現的風格,這裡放到最外層就能實現我們想要的效果是不是很 Happy?
StatelessWidget 和 StatefulWidget 的區別
細心的同學已經發現,我們用到的 widget 發現有,StatelessWidget 和 StatefulWidget , 他們的區別如下:
Stateless widgets 是不可變的, 這意味著它們的屬性不能改變 - 所有的值都是最終的.
Stateful widgets 持有的狀態可能在widget生命周期中發生變化. 實現一個 stateful widget 至少需要兩個類:
一個 StatefulWidget類。
一個 State類。 StatefulWidget類本身是不變的,但是 State類在widget生命周期中始終存在.
添加 Scaffold 頁面框架組件
Scaffold 是 Material library 中提供的一個widget, 它提供了默認的導航欄、標題和包含主屏幕widget樹的body屬性
添加 標題
添加標題比較簡單,他的屬性不多,我這裡只添加 appbar 的名稱屬性,因為我們後邊需要添加導航欄,標題名稱會發生改變,我這裡實現代碼如下:
添加 抽屜
添加抽屜,就直接在 中對應的屬相添加組件即可。
由於篇幅,還剩下主內容、抽屜、輪播圖的實現,我就不一一說明了,具體內容我放到了github上,搜索 studylifetime/flutter_demo 就不往文章上貼代碼了。具體實現詳情可以查看源碼,裡邊注釋比較清楚。
總結
對於 Android 開發人員來說,入門比較簡單,dart 與java 非常類似,語言這一關很好過,熟悉一下界面開發,便可快速上手開發了。但是Flutter 現在還不適合商業項目的開發, 平時使用的微信支付、登錄,推送消息,bugly 錯誤上報,這些都需要國內的廠商來適配,推送、錯誤上報、分享如果從頭做一遍的話,會牽扯公司很大精力。
參考引用
Flutter 官網
Flutter 中文網
為什麼Flutter會選擇 Dart ?
TAG:玉剛說 |