当应用程序关闭时,共享首选项会被删除。

5

我正在使用flutter构建登录界面,并在shared preference中保存用户数据。如果正确,则测试第二个页面中的保存数据,已经保存。 当应用程序关闭并再次打开时,我检查shared pref,但它变为空。 以下是我的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');
}

我需要提到两件事情: 第一,"commit"函数已经被弃用; 第二,代码之前可以使用已经废弃的"commit"函数,但现在不行了。 我已经撤销了所有更改,但它仍然不能在我的设备和其他设备上运行,不知道为什么! 如果没有解决方案,Flutter中是否有Shared Preference的替代品? 这就是我使用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].name, users[phone].ordered),其中users[phone].phone是用户电话。函数名为saveDataPref,参数为用户电话、用户名和"user"字符串。
      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()吗? - Sebastian
我已经删除了它,但仍然无法工作。 我在另一个屏幕中使用了“remove”并删除了该函数,但仍然无法工作。 - Ahmed El Sayed
你从哪里调用 saveDataPref() 函数? - Günter Zöchbauer
我已经更新了问题,并在其中使用了saveDataPref()和getDataPref(),这是主类文件中的全局方法。 - Ahmed El Sayed
我认为这个值像在这里提到的那样被存储在缓存中: https://dev59.com/xVUK5IYBdhLWcg3w0Sx1 我该如何将它保存到设备内存而不是缓存中? - Ahmed El Sayed
4个回答

3
我得出结论是我的应用程序中某个地方使用了 prefs.clear() 导致数据丢失。请确保在任何活动中没有写入 prefs.clear()。

1

请确保您的代码中没有调用 pref.clear();

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

最后,在您的initState()中调用上述函数,如下所示:
@override
    void initState() {
     super.initState();
      loadUserId();
 }

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

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(() {});
    });
  }

1
它对我仍然不起作用:shared preferences do not persist - Jérémy

0

删除了这行

SharedPreferences.setMockInitialValues({});

代码正在工作


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接