外掛是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變得更禿更強了。趕緊來書寫屬於你自己的外掛吧!!加油騷年
動動手指頭,點個讚唄。