【问题标题】:shared preference is deleted when application is closed关闭应用程序时删除共享首选项
【发布时间】:2019-02-18 15:31:04
【问题描述】:

我正在使用颤振构建一个登录屏幕,如果正确的话,我会将用户数据保存在共享首选项中 然后我在第二个屏幕中测试了保存的数据,它已经保存了 当应用程序关闭并再次打开时,我检查共享首选项,但它变为空 这是我的 saveData 和 getData 函数

String namePref,phonePref, typePref,statePref;
Future saveDataPref(String name,String phone, String type, String state )async{
  SharedPreferences pref = await SharedPreferences.getInstance();
  pref.setString('phone', phone);
  pref.setString('name', name);
  pref.setString('type', type);
  pref.setString('state', state);
  pref.commit();
  print('pref stored');
  print('${pref.getString('phone')}');
}

Future getDataPref() async{
  SharedPreferences pref = await SharedPreferences.getInstance();
  phonePref = pref.getString('phone');
  namePref = pref.getString('name');
  typePref = pref.getString('type');
  statePref = pref.getString('state');
}

我应该提到两件事 “提交”功能已弃用 第二个是代码正在使用已弃用的提交,但现在不是 我删除了我所做的所有更改,但它仍然无法正常工作 在我的设备和其他设备上,不知道为什么! 如果没有解决方案,在颤振中是否有任何替代共享偏好的方法? 这就是我使用 saveDataPref() 的地方

Future login(BuildContext context) async {
  String password = passwordController.text;
  String phone = phoneController.text;
  print("entered login function");
  //check if the user is registered
  Map<String, User> users = new Map<String, User>();
  users = await getUserDataFromFireStore();
  if (await userCheck(phone)) {
    // user is registered check if it is the right password
    if (users[phone].password == password) {
      // check if the user have an order

保存数据首选项( users[phone].phone, users[phone].name, "user", users[phone].ordered);

      if (users[phone].ordered == "true") {
        Navigator.push(
            context, MaterialPageRoute(builder: (context) => OrderBinding()));
        return;
      } else {
        Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => UserApp(
                      userName: users[phone].name,
                      userPhone: users[phone].phone,
                    )));
        return;
      }
    } else {
      ShowDialogue(
          "تم إدخال كلمة السر بشكل خاطئ من فضلك تأكد من كلمة السر", context);
    }
  }

  Map<String, Driver> drivers = new Map<String, Driver>();
  drivers = await getDriverDataFromFireStore();
  if (await DriverCheck(phone)) {
    // user is registered check if it is the right password
    if (drivers[phone].password == password) {
      //check if driver account is activated
      if (drivers[phone].activation == "true") {
        saveDataPref(drivers[phone].phone, drivers[phone].name, "driver",
            drivers[phone].activation);
        Navigator.push(
            context, MaterialPageRoute(builder: (context) => DriverApp()));
      } else {
        ShowDialogue(
            "لم يتم تفعيل حسابكم بعد يرجى الانتظار وسيتم التواصل معكم قريباً",
            context);
      }
    } else {
      ShowDialogue(
          "تم إدخال كلمة السر بشكل خاطئ من فضلك تأكد من كلمة السر", context);
    }
  } else {
    ShowDialogue(
        "لم يتم تسجيل هذا المستخدم من فضلك قم بانشاء حساب اولا", context);
  }
}

这里我检查登录数据是否正确 我测试了这个功能并且我工作了 它打开 saveDataPref() 我使用从另一个屏幕检索数据,它的工作原理 但是当关闭应用程序并再次打开它时,我使用 getDataPref() 但检索到的数据为空 在这里我使用 getDataPref() 来检查用户是否已经注册,所以转到 UserApp 屏幕,如果没有打开主屏幕

checkSigned() {
  getDataPref();
  print("${phonePref}");
  print("${namePref}");
  if (phonePref != null) {
    print("${phonePref}");

    if (phonePref != "") {
      print("${phonePref}");

      return new UserApp(
        userName: namePref,
        userPhone: phonePref,
      );
    } else {
      return new MyHomePage();
    }
  } else {
    return new MyHomePage();
  }
}

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Generated App',
      theme: new ThemeData(
        primarySwatch: Colors.lightGreen,
        primaryColor: const Color(0xFF8BC34A),
        accentColor: const Color(0xFF8BC34A),
        canvasColor: const Color(0xFFEEEEEE),
      ),
      home: checkSigned(),
    );
  }
}

【问题讨论】:

  • 我不使用 commit()。只需 setString() 就可以了,效果很好。您是否在应用中的任何位置调用 pref.clear()?
  • 我删除了它但仍然无法使用我在另一个屏幕中使用了删除并删除了该功能但仍然无法使用
  • 你在哪里打电话给saveDataPref()
  • 我用我使用 saveDataPref() 和 getDataPref() 的地方更新了问题,它是主类文件中的全局方法
  • 我认为该值存储在缓存中,如下所述:stackoverflow.com/questions/51215064/… 我如何将其保存到设备内存而不是缓存?

标签: dart sharedpreferences flutter


【解决方案1】:

确保您没有在代码中的任何位置调用pref.clear();

loadUserId() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
  userId = pref.getString("userId");
});}

最后在 initState() 中调用上述函数,如下所示:

@override
    void initState() {
     super.initState();
      loadUserId();
 }

【讨论】:

    【解决方案2】:

    我在这里找到了解决方案:

    Flutter: Shared Preferences null on Startup

    请注意,如果您像我之前所做的那样在主类之外调用它,共享偏好将不起作用。 您应该在 initState() 中调用它。 这有效:

    @override
      void initState() {
        super.initState();
        readFile('phone');
        SharedPreferences.getInstance().then((SharedPreferences sp) {
          sharedPreferences = sp;
          ph = sp.getString('phone');
          setState(() {});
        });
      }
    

    【讨论】:

    【解决方案3】:

    我得出的结论是,由于数据丢失,我在我的应用程序中的某个地方使用了 prefs.clear()。确保您的任何活动中都没有 prefs.clear()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-06
      • 1970-01-01
      • 1970-01-01
      • 2016-12-10
      相关资源
      最近更新 更多