Flutter在一个字段中存储共享首选项

时间:2018-04-02 05:10:33

标签: flutter

我在Flutter应用程序中使用共享首选项,我想要做的是将SharedPreferences存储为启动时的字段,然后在应用程序中同步使用它。但是我不确定我是不是错过了任何东西。 我想要实现的不是:

method1() async {
  SharedPreferences sp = await SharedPreferences.getInstance();
  return sp.getString('someKey');
}

SharedPreferences sp;
//I would probably pass SharedPreferences in constructor, but the idea is the same
someInitMethod() async {
  sp = await SharedPreferences.getInstance();
}
method1() {
  return sp.getString('someKey');
}
method2() {
  return sp.getString('someKey2');
}
method3() {
  return sp.getString('someKey3');
}

通过这种方式,我将实现对sharedPrefs的同步访问。这是不好的解决方案吗?

编辑:
值得一提的是getInstance方法只会检查实例,如果有的话,它会返回它,因此我认为只需要初始化实例async。无论如何,setget方法都是同步的。

static Future<SharedPreferences> getInstance() async {
  if (_instance == null) {
    final Map<String, Object> fromSystem =
        await _kChannel.invokeMethod('getAll');
    assert(fromSystem != null);
    // Strip the flutter. prefix from the returned preferences.
    final Map<String, Object> preferencesMap = <String, Object>{};
    for (String key in fromSystem.keys) {
      assert(key.startsWith(_prefix));
      preferencesMap[key.substring(_prefix.length)] = fromSystem[key];
    }
    _instance = new SharedPreferences._(preferencesMap);
  }
  return _instance;
}

4 个答案:

答案 0 :(得分:5)

我使用与原始海报建议相同的方法,即我有一个全局变量(实际上是我用于所有这些变量的类中的静态字段),我初始化为共享首选项,如下所示:

globals.dart中的

class App {      
  static SharedPreferences localStorage;
  static Future init() async {
    localStorage = await SharedPreferences.getInstance();
  }
}
main.dart中的

void main() {
  start();
}

Async.Future start() async {
  await App.init();
  localStorage.set('userName','Bob');
  print('User name is: ${localStorage.get('userName)'}');  //prints 'Bob'
}

上述工作正常,但我发现如果我尝试使用其他dart文件中的App.localStorage,例如settings.dart它不起作用,因为App.localStorage为空,但我无法理解它是如何变为空。

原来问题是settings.dart中的导入语句应该是import 'package:<packagename>/src/globals.dart'; import 'globals.dart;

答案 1 :(得分:0)

  1. 在启动有状态主应用程序时调用共享首选项(在super.initState()之后我们称之为StatefulWidget的initState()重写
  2. 在共享prefs inits之后,将值设置为main上的字段(例如:String _someKey)
  3. 此字段注入任何子组件
  4. 你可以在闲暇时在_someKey上调用setState(),它会持续注入你的田地的孩子

答案 2 :(得分:0)

@ iBob101的答案很好,但是仍然必须等待第一次使用SharedPreferences。

对于您的SharedPreferences,重点不在于await,请确保它始终不是NULL。

因为无论如何您都必须等待,所以请在main()方法中进行操作:

class App {      
  static SharedPreferences localStorage;
  static Future init() async {
    localStorage = await SharedPreferences.getInstance();
  }
}

主要方法:

void main() async{
  await SharedPref.initSharedPref();
  runApp(MyApp());
}

await SharedPref.initSharedPref();行执行大约需要100毫秒。据我所知,这是唯一的缺点。

但是您绝对知道,在应用程序的每个位置,您的sharedPreferenes实例都为NOT NULL并可以访问它:

String s = App.localStorage.getString(PREF_MY_STRING_VALUE);

我认为这很值得

答案 3 :(得分:0)

最干净的方法是在const columns = [{ Header: 'id', accessor: 'id', show: false }, { Header: 'Description', Cell: props => { let spaces = props.original.description.indexOf("0"); if(spaces>-1){ return <span>{" ".repeat(spaces) + props.original.description}</span> } else { return <span>{props.original.description}</span> } } }]; 方法中检索SharedPreferences并将其作为依赖项传递给main

MyApp