Flutter shared_preferences 探究

原由

Flutter 中使用三方插件的時候,很好奇,他是怎麼作到,跨平臺,既能在iOS上使用,也能在Android上使用?android

一探究竟

拿經常使用的數據持久化的 shared_preferences 來看,他的功能在iOS上和 NSUserDefaults 的功能基本相似, 在安卓上 基本上和 SharedPreferences 同樣,bash

猜測

  1. 用Flutter 本身的某種方法實現,和Flutter 的界面同樣,既不是在iOS中轉化成了 UIViewController 也不是在Android中轉化成了 Activity,
  2. 和RN同樣,在iOS上調用了iOS的實現,在安卓上調用了安卓的實現,

結果

最後看了 shared_preferences 的源碼,發現,shared_preferences 是基於通道, 在iOS上 和 android 有不一樣的實現,和猜測二同樣,在 iOS 上使用了 NSUserDefaults 安卓使用了 SharedPreferencesmarkdown

iOS的實現

通道, 以庫的名稱爲通道名,註冊了一個 FlutterMethodChannelspa

FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:CHANNEL_NAME
                                                              binaryMessenger:registrar.messenger];
複製代碼

在iOS 中 經過通道的 result 將結果返回,這裏摘出一小部分,就能夠理解,這裏 摘出的是 shared_preferencessetBool 的實現,映射的是iOS 中的插件

[[NSUserDefaults standardUserDefaults] setBool:value.boolValue forKey:key];
複製代碼

摘出的部分以下:code

else if ([method isEqualToString:@"setBool"]) {
      NSString *key = arguments[@"key"];
      NSNumber *value = arguments[@"value"];
      [[NSUserDefaults standardUserDefaults] setBool:value.boolValue forKey:key];
      result(@YES);
    } else if ([method isEqualToString:@"setInt"]) {
      NSString *key = arguments[@"key"];
      NSNumber *value = arguments[@"value"];
     
      [[NSUserDefaults standardUserDefaults] setValue:value forKey:key];
      result(@YES);
複製代碼

android的實現

android 和 iOS 的實現基本相似, 首先也是註冊通道,而後 映射到安卓的 SharedPreferences 來實現orm

通道- 主要代碼源碼

MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL_NAME);
    SharedPreferencesPlugin instance = new SharedPreferencesPlugin(registrar.context());
    channel.setMethodCallHandler(instance);
複製代碼

對應的實現 這裏也摘出 部分, Flutter 中的 shared_preferences 的setBool 對應 android 的it

status = preferences.edit().putBoolean(key, (boolean) call.argument("value")).commit();
複製代碼

摘出的內容以下io

switch (call.method) {
        case "setBool":
          status = preferences.edit().putBoolean(key, (boolean) call.argument("value")).commit();
          break;
        case "setDouble":
          double doubleValue = ((Number) call.argument("value")).doubleValue();
          String doubleValueStr = Double.toString(doubleValue);
          status = preferences.edit().putString(key, DOUBLE_PREFIX + doubleValueStr).commit();
          break;
複製代碼
相關文章
相關標籤/搜索