Flutter小知識--外掛開發建議

ershixiong發表於2019-09-26

外掛是flutter生態中必需品。開發者可以通過外掛跟app所執行的平臺進行互動。

在2018年的10月時,在 pub.dev上已經有上百款外掛了。外掛的質量尤為重要,不管外掛是來自google官方還是第三方。本文主要是探索什麼是一款好的外掛以及如何打造。

功能性第一,其次才是APIs

很多時候在寫外掛時,橋接的是本地已經存在的庫。最直接的做法就是根據原生庫的api來寫對應的dart api。但是當 APIs因為平臺差異不太匹配時,你又不得不暴露更多的原生API細節,導致了很多壞結果。

當你書寫外掛時,優先考慮功能性,而不是APIs。比如,假設你在寫一款本地儲存外掛,你可能需要的api是

  • 能存各種型別的值
  • 能夠取到他們 想好你要支援的功能後,就可以思考你的dart api如何設計了:
class StoragePlugin {
  
  /// Reads a string
  Future<String> getString(String key) async {}
  
  /// Writes a string
  Future<void> setString(String key, String value) async {}
}

複製程式碼

搞完這個,接下來開始關注對外暴露的API 和 如何進行平臺適配:

class StoragePlugin {
  
  Future<String> getString(String key) async {
    if (Platform.isIos) {
      return await callMethodChannel('fetchValue', {'id': base64encode(key)});
    } else if (Platform.isAndroid) {
      return await callMethodChannel('fetchValue', {'id': key});
    }
  }
  
  Future<void> setString(String key, String value) async {
    if (Platform.isIos) {
      await callMethodChannel('setValue', {'id': base64encode(key), 'value': value});
    } else if (Platform.isAndroid) {
      await callMethodChannel('setValue', {'id': key, 'value': value});
    }
  }
}
複製程式碼

如果你提供的某個功能不被某個平臺支援,那API需要提供合理的報錯資訊。 可不能把app搞掛,而且這個不支援的操作應該是被註釋出來。你應該繼續請求platform來完成這個不支援的操作以走通整個外掛呼叫流程。

避免特定平臺的方法

Flutter本身是跨平臺的,寫特定平臺的程式碼是不對滴。如果外掛使用者想做下面的事情:

if (Platform.isIos) {
  myPlugin.doIOSThing();
} else if (Platform.isAndroid) {
  myPlugin.doAndroidThing();
}
複製程式碼

考慮將平臺特定邏輯交給plugin本身完成,可以改成下面這樣:

myPlugin.doThing();
複製程式碼

避免僅支援一個平臺

你可能一開始想寫一個"小而美"的外掛,功能僅支援Android。但是很不幸的是,當外掛釋出後,將會對不支援的平臺使用者即開發者造成困擾。

比如這款Android平臺外掛,Android Intent,如果不能顯示,可以直接訪問 github.com/flutter/plu…

讓你的外掛更容易被理解和測試

根據經驗來說,你的外掛應該包含較多的dart程式碼。

  • native層很重要,主要是完成庫在emulators不能起作用的功能。
  • Flutter大部分是由dart書寫的。Flutter app亦然,這樣當你跟蹤程式碼時,可以在dart裡面自由跟進。

唯一使用native 層的原因應該是 平臺相關實現需要儲存狀態或者其他一些處理。一個好的例子是 在Android上生物識別有著自己複雜的生命週期,這個需要native code來管理。
如果你需要寫較多的native程式碼,考慮單一職權原則,劃分到不同的類中方便單元測試。

理想情況下,你的外掛僅僅是監聽 方法呼叫,並把呼叫結果派發回dart端。如果你做的事情超過這個範圍,試著看能否把多的部分移至dart端,最終你的程式碼邏輯會在多個平臺進行復用,比如web 、Android、ios。

避免寫靜態( 或者全域性)函式

比如:

Future<User> authenticate() async {
  // Some code
}
複製程式碼

但是下面的更好:

class AuthenticatePlugin {
  Future<User> authenticate() async {
    // Some code
  }
}
複製程式碼

這樣會讓外掛更容易被mock。使用者可以輕易替換掉真正的實現然後app可以執行在模擬器或者測試工具上。

總結結語:
Plugins讓Flutter變得更禿更強了。趕緊來書寫屬於你自己的外掛吧!!加油騷年


動動手指頭,點個讚唄。

Flutter爛筆頭

相關文章