Flutter Plugin開發流程

吹個大氣球發表於2018-05-12

這篇文章主要介紹了Flutter Plugin開發流程,包括如何利用Android Studio開發以及釋出等。

本文主要給大家介紹如何開發Flutter Plugin中Android的部分。有關Flutter以及Flutter Plugin的概念,感興趣的可以從官網檢視相關資料。

簡介

筆者的環境是Mac下Android Studio進行的開發,AS也是谷歌官推的,安裝flutter外掛後,開發起來相對於其他IDE來說,方便很多,自帶了三種模板:

  • Flutter Application: Flutter應用
  • Flutter Plugin:Flutter外掛
  • Flutter Package:純Dart元件

Plugin其實就是一個特殊的Package。Flutter Plugin提供Android或者iOS的底層封裝,在Flutter層提供元件功能,使Flutter可以較方便的調取Native的模組。很多平臺相關性或者對於Flutter實現起來比較複雜的部分,都可以封裝成Plugin。其原理如下

Flutter Plugin開發流程

訊息在client和host之間通過平臺通道(platform channels)來進行的,之間的通訊都是非同步的。

建立元件

直接在Android Studio中新建一個Flutter Plugin的工程,當然也可以使用命令列來進行,例如建立一個flutter_text_plugin。

flutter create --org com.example --plugin flutter_text_plugin

如果想支援swift或者kotlin,可以用如下命令進行建立:

flutter create --org com.example --plugin -i swift -a kotlin flutter_text_plugin

更多的引數選項,大家可以 檢視幫助文件,當然還是比較推薦直接用AS進行建立,簡單直觀。用AS開啟專案,可以看到專案的組織結構

root
	android
	example
	ios
	lib
	...
複製程式碼

android以及ios資料夾是我們將要編寫外掛的native層的地方,lib資料夾是編寫與native層對映的地方,native與flutter之間不能直接通訊,必須通過MethodChannel來間接呼叫。example資料夾則是例子工程,編寫的外掛可以直接在這個專案中進行驗證。在本文中,我們主要在android目錄下進行,也就是android部分。

編寫Android部分

用AS開啟flutter_text_plugin/android專案,這樣子開發起來比較方便。但是開啟過後,會發現出現了很多錯誤,提示找不到flutter相關的東西,我們仔細看這個專案,會發現跟我們平時用AS建的Android專案有所不同,少了很多部分,目錄也有所不同。這是因為這個android專案不需要能夠直接去執行,因此減少了很多東西。但是對於初次接觸的人來說,可能是一頭懵逼,例如該如何新增第三方庫,如何新增proguard rule等等。

引入flutter庫

android外掛工程是沒有引入flutter庫的,所以才會出現錯誤提示,我們在專案根目錄建立一個libs資料夾,用來存放flutter庫。

flutter庫就在我們的flutter sdk中,路徑如下

/bin/cache/artifacts/engine

engine下面包含了各種平臺的flutter庫,我們隨便拷貝一個Android平臺的庫到libs資料夾下,右鍵flutter.jar,彈出選單選擇Add As Library...

經過這一步,專案中不會再報錯了,但是,由於整個flutter plugin包含了flutter庫,因此不能只是簡單的新增就了事了,點選選單Project Structure...,找到flutter_text_plugin的Dependencies中,將flutter庫的Scope從Implementation改成Compile Only。至此,引入flutter庫的工作完成了,可以進行外掛的編寫操作了。

新增第三方庫

新增第三方庫有兩種,一種是jar包引入,另一種通過gradle的方式進行。由於進行了第一步flutter庫的引入,這一步就簡單多了。檢視build.gradle檔案,可以看到最下面出現瞭如下的資訊。

dependencies {
  compileOnly files('libs/flutter.jar')
}
複製程式碼

看到這個,是不是就明朗多了,新增靜態庫以及新增線上庫都可以在這個地方進行。例如我新增一個bugly靜態庫以及okhttp3庫:

dependencies {
  compileOnly files('libs/flutter.jar')
  implementation 'com.squareup.okhttp3:okhttp:3.10.0'
  implementation files('libs/bugly_crash_release.jar')
}
複製程式碼

新增proguard rule

由於了bugly以及okhttp3庫,因此需要新增progurad rule。我們發現專案中沒有proguard-rules.pro檔案,因此這一步也需要我們自己去建立,在根目錄下,建立proguard-rules.pro檔案,將混淆規則新增進去,然後修改build.gradle檔案,新增如下資訊,跟普通Android專案差不多:

buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
  }
複製程式碼

Android許可權

新增了bugly以及okhttp3庫,需要對應的許可權申明,才能正常執行。直接在manifest檔案下,新增對應的許可權

  <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  <uses-permission android:name="android.permission.READ_LOGS"/>
複製程式碼

外掛開發

至此,準備工作都已就緒,你可以把這個專案當做一個獨立的Android專案,在上面進行各種封裝操作,然後在FlutterTestPlugin檔案下,將介面暴露出來。通過platform channels與flutter層關聯起來。

釋出

當外掛開發完畢,可以將外掛釋出讓其他人使用,在釋出之前,確保pubspec.yaml,、README.md以及CHANGELOG.md檔案的內容都正確填寫完畢。可以通過dry-run命令來看準備是否就緒。

flutter packages pub publish --dry-run

檢查無誤後,可以執行下面的命令,釋出到Pub上。

flutter packages pub publish

如何引用

對外掛的引用有兩種,已經發布的和未釋出的。

引用釋出的庫

flutter專案的很多資源管理都在根目錄的pubspec.yaml下面,類似於js中的一些包管理一樣,在dependencies加上我們需要引入的庫,例如引入url_launcher庫:

dependencies:
  url_launcher: ^0.4.2
複製程式碼

如果這個庫包含了一些平臺相關的東西,例如需要在native層進行使用的話,則需要在對應的native專案單獨做引用。

Android

修改android/build.gradle的dependencies處做引用:

dependencies {
        provided rootProject.findProject(":url_launcher")
    }
複製程式碼

iOS

修改ios/hello.podspec檔案

Pod::Spec.new do |s|
  # lines skipped
  s.dependency 'url_launcher'
複製程式碼

引用衝突

引用不同的庫可能會導致一些衝突,例如A和B兩個外掛,都包含了C外掛,但是所需的版本不同。因此我們可以採取以下措施避免這種問題:

  • 儘量使用範圍版本而不是指定一個特定的版本。
  • 強制統一衝突的外掛版本
  • 對於native層,android可以通過force命令強制指定版本,而iOS這邊,Cocoapods則不支援引用的override功能。

引用未釋出的庫

引用未釋出的庫有兩種方式,通過本地路徑和git地址的方式:

基於Path的引用方式:

這種方式主要針對本地的未釋出的庫,引用的路徑可以是相對或者絕對路徑。

dependencies:
  plugin1:
    path: ../plugin1/
複製程式碼

基於Git的引用方式:

這種方式針對存放在git上的庫,其中path是可選的,可以定位到某個子目錄

dependencies:
  package1:
    git:
      url: git://github.com/flutter/packages.git
      path: packages/package1   
複製程式碼

擴充套件

Flutter - 不一樣的跨平臺解決方案介紹了Flutter平臺,對Flutter平臺技術進行了簡要的分析,並從多個維度去調研探討Flutter在商用環境的可行性,歡迎大家閱讀。

後話

筆者新建了一個flutter學習相關的專案,github地址,裡面包含了筆者寫的關於flutter學習相關的一些文章,後期也會定期更新,也會上傳一些學習demo,歡迎大家關注。

參考

  1. Flutter進階—平臺外掛
  2. Flutter - Creating a Plugin
  3. Flutter for Android Developers
  4. Writing custom platform-specific code with platform channels
  5. Developing Packages & Plugins
  6. Using Packages

相關文章