注:目前Fluttify本身並不對外開放,但是內測階段可以免費為你生成外掛,只要提供android端的jar/aar和ios端的framework/.h+.a,或者maven座標和cocoapods名稱即可。
系列文章:
(一)Flutter外掛開發必備 原生SDK->Dart介面生成引擎Fluttify
介紹
(二)如何利用Fluttify開發一個新的Flutter外掛
使用Fluttify生成外掛
從原生SDK生成Fluttify
產物,本質上也是一個構建的過程,所以Fluttify
採用了Gradle
外掛的形式。和android
構建類似,構建Fluttify
也需要提供一個build.gradle
,輸入必須的引數後執行gradle fluttify
,便能夠生成出一個原生SDK對應的Flutter外掛。
這篇文章會以極光統計SDK作為示例。
快速開始
以JAnalytics SDK的初始化方法為例:
- 聯絡我(382146139@qq.com)生成外掛;
- 在
./lib
資料夾下新建dart
資料夾(這一步是可選的,為了不弄亂資料夾而已); - 建立
./dart/janalytics_service.dart
檔案(名字隨你喜歡,只是找個地方放初始化程式碼); - 去官網整合指南找初始化程式碼:
4.1 android:
JAnalyticsInterface.init(Context context);
; 4.2 ios:[JANALYTICSService setupWithConfig:config];
; - 編寫Dart程式碼:
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
的目標。
接下來大致介紹下生成的外掛的結構以及怎麼呼叫生成的介面。
Fluttify產物工程結構
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,歡迎各位的反饋。