如何利用Fluttify開發一個新的Flutter插件

Fluttify網站:fluttify.comandroid

系列文章:ios

(一)Flutter插件開發必備 原生SDK->Dart接口生成引擎Fluttify介紹git

(二)如何利用Fluttify開發一個新的Flutter插件github

(三)Fluttify輸出Flutter插件工程詳解api

(四)Fluttify編譯器原理介紹xcode

使用Fluttify生成插件

從原生SDK生成Fluttify產物,本質上也是一個構建的過程,因此Fluttify採用了Gradle插件的形式。和android構建相似,構建Fluttify也須要提供一個build.gradle,輸入必須的參數後運行gradle fluttify,便可以生成出一個原生SDK對應的Flutter插件。 這篇文章會以極光統計SDK做爲示例。bash

快速開始

以JAnalytics SDK的初始化方法爲例:markdown

  1. 前往網站 fluttify.com 生成插件;
  2. ./lib文件夾下新建dart文件夾(這一步是可選的,爲了避免弄亂文件夾而已);
  3. 建立./dart/janalytics_service.dart文件(名字隨你喜歡,只是找個地方放初始化代碼);
  4. 去官網集成指南找初始化代碼: 4.1 android: JAnalyticsInterface.init(Context context);; 4.2 ios: [JANALYTICSService setupWithConfig:config];;
  5. 編寫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);
      },
    );
  }
}
複製代碼
  1. 插件的一個方法編寫完畢。

能夠看到在Fluttify的加持下,編寫插件變成了一件很是輕鬆的事情,想要寫方法的時候就是查官方文檔,而後寫對應的dart代碼,徹底屏蔽了原生接口。你不用再一次次的打開android studioxcode,一次次地在原生和dart之間跳來跳去,不再用爲了在dart和原生之間傳對象寫那一大坨的字段,跟原生有關的,Fluttify都(盡力)爲你提供好dart接口,這就是Fluttify的目標。app

接下來大體介紹下生成的插件的結構以及怎麼調用生成的接口。異步

Fluttify產物工程結構

Fluttify的產物是一個標準的Flutter的插件工程,因此lib文件夾之上的結構都和普通插件同樣。lib文件夾下會分紅androidios文件夾,分別放置各平臺SDK中的類(枚舉/接口等)對應的Dart類(枚舉/接口等)。android/ios文件夾下還會各自生成:

  • function.g.dart文件:生成的全部頂層函數;
  • type_op.g.dart文件:全部的asis方法,用來判斷類型和造型;
  • 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,歡迎各位的反饋。

相關文章
相關標籤/搜索