Fluttify網站:fluttify.comandroid
系列文章:ios
(一)Flutter插件開發必備 原生SDK->Dart接口生成引擎Fluttify
介紹git
(二)如何利用Fluttify開發一個新的Flutter插件github
(三)Fluttify輸出Flutter插件工程詳解api
(四)Fluttify編譯器原理介紹xcode
從原生SDK生成Fluttify
產物,本質上也是一個構建的過程,因此Fluttify
採用了Gradle
插件的形式。和android
構建相似,構建Fluttify
也須要提供一個build.gradle
,輸入必須的參數後運行gradle fluttify
,便可以生成出一個原生SDK對應的Flutter插件。 這篇文章會以極光統計SDK做爲示例。bash
以JAnalytics SDK的初始化方法爲例:markdown
./lib
文件夾下新建dart
文件夾(這一步是可選的,爲了避免弄亂文件夾而已);./dart/janalytics_service.dart
文件(名字隨你喜歡,只是找個地方放初始化代碼);JAnalyticsInterface.init(Context context);
; 4.2 ios: [JANALYTICSService setupWithConfig:config];
;import 'package:flutter/cupertino.dart'; import 'package:janalytics_fluttify/src/android/android.export.g.dart'; // 這是生成的代碼 import 'package:janalytics_fluttify/src/ios/ios.export.g.dart'; // 這是生成的代碼 class JAnalyticsService { static Future<void> init({@required String iosKey}) async { // `platform`方法封裝了一些方便多平臺調用的邏輯,若是你喜歡也能夠直接if else判斷平臺而後各自調用各平臺的代碼 await platform( // pool參數是須要釋放的原生對象的集合,在platform方法執行結束後會自動釋放原生對象,具體能夠看本篇下面的說明 android: (pool) async { await cn_jiguang_analytics_android_api_JAnalyticsInterface .init(await android_app_Application.get()); }, ios: (pool) async { final config = await JANALYTICSLaunchConfig.create__(); await config.set_appKey(iosKey); await config.set_channel('developer-default'); await JANALYTICSService.setupWithConfig(config); pool.add(config); }, ); } } 複製代碼
能夠看到在Fluttify
的加持下,編寫插件變成了一件很是輕鬆的事情,想要寫方法的時候就是查官方文檔,而後寫對應的dart
代碼,徹底屏蔽了原生接口。你不用再一次次的打開android studio
和xcode
,一次次地在原生和dart
之間跳來跳去,不再用爲了在dart
和原生之間傳對象寫那一大坨的字段,跟原生有關的,Fluttify
都(盡力)爲你提供好dart
接口,這就是Fluttify
的目標。app
接下來大體介紹下生成的插件的結構以及怎麼調用生成的接口。異步
Fluttify
的產物是一個標準的Flutter的插件工程,因此lib
文件夾之上的結構都和普通插件同樣。lib
文件夾下會分紅android
和ios
文件夾,分別放置各平臺SDK中的類(枚舉/接口等)對應的Dart類(枚舉/接口等)。android
/ios
文件夾下還會各自生成:
function.g.dart
文件:生成的全部頂層函數;type_op.g.dart
文件:全部的as和is方法,用來判斷類型和造型;ios/android.export.g.dart
文件:導出全部的ios/android類型;platformview
文件夾:生成的全部PlatformView
;習慣上會在lib
文件夾下再加一個dart
文件夾,放置對各平臺進行抽象的代碼,而且最後對外export
的時候,只export
這個文件夾下的文件。
lib
文件夾結構概覽:
.
├── janalytics_fluttify.dart
└── src
├── android
│ ├── android.export.g.dart
│ ├── cn ... android端對應的dart接口
│ └── type_op.g.dart
├── dart
│ └── janalytics_service.dart
└── ios
├── JANALYTICSBrowseEvent.g.dart
├── ...其餘生成文件
├── functions.g.dart
├── ios.export.g.dart
└── type_op.g.dart
複製代碼
Fluttify
中建立對象主要是使用create
方法。這個方法在dart端以靜態的異步方法XX.create__xx
的形式提供,其中xx
是構造器的參數。形如:
class JANALYTICSLaunchConfig extends NSObject { static Future<JANALYTICSLaunchConfig> create__() async { // ...調用原生建立對象 } } 複製代碼
若是構造器沒有參數,那麼就直接XX.create__
,後面跟兩個下劃線是爲了避免與SDK中的create方法衝突。
Fluttify
中的全部方法都是異步的,因此你想要看起來像同步代碼的話,就要對每一個調用都加await
。其餘的就沒什麼好說的,由於Fluttify
的目的就是爲了讓原生調用起來跟dart
調用起來如出一轍,原生怎麼調用,dart
這邊就怎麼調用。
Fluttify
會生成SDK中的公開類,公開方法,以及常量。
全部Fluttify
生成的工程都會依賴一個基礎設施插件,也就是foundation_fluttify
。
這個插件提供了系統類的dart接口,而且是手寫的。曾經我也嘗試過直接對android.jar和ios的系統framework進行生成,雖然理論上可以實現,可是效果並很差,生成出來的文件很是多,光這一個插件編譯進app的話就要增大好幾Mb,因此放棄了,仍是碰到須要的再去手動編寫一下就ok了。
另外foundation_fluttify
還提供了一些便利方法,好比platform
方法簡化多平臺的調用,kNativeObjectPool
存放原生對象的dart引用,等等。
Fluttiy
生成的dart代碼在調用過程當中產生的原生對象,都會被放入一個叫HEAP
的全局鍵值對類型中,android端爲HashMap,ios端爲NSDictionary。因爲存放在全局變量中,若是不手動釋放的話,那麼這些對象會一直被強引用,沒法釋放。foundation_fluttify
中的Ref
類(dart)有一個release
方法,調用它會把對應的原生對象充HEAP
中刪除,從而解除強引用。
以上就是使用Fluttify開發一個插件的介紹。janalytics_fluttify已經上傳到fluttify-project組織下,若是有老鐵對這個插件感興趣的話能夠聯繫我(382146139@qq.com),我能夠把你設置爲維護者,固然有空閒時間時,我也會進一步開發這個插件。
若是有想要生成插件的老鐵也能夠聯繫我,目前Fluttify還處於內測階段,不會收取任何費用,有任何反饋均可以往fluttify-feedback提issue,歡迎各位的反饋。