2
votes

Flutter, la fonction doit attendre que les données soient disponibles

Je suis un novice en programmation de flutter. J'essaie de comprendre les appels de fonction asynchrone, mais je me suis trompé.

Je souhaite stocker des données sur mon appareil de manière sécurisée. Ainsi, lors de l'écriture des données, les données seront cryptées et lors de la lecture des données, les données seront décryptées. L'application ne sait pas que les données sont chiffrées sur l'appareil.
J'ai créé une classe Storage qui utilise la bibliothèque SharedPreferences.
Une deuxième fonctionnalité de la fonction de lecture, c'est que l'application attendra que les données soient disponibles.

J'ai écrit quelque chose comme ça

  static String getString(String key)  {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    return _decrypt(prefs.getString(key));   
  }

Maintenant le compilateur se plaint que l'instruction await n'est pas attendue.

Quand je change la fonction en une fonction asynchrone renvoyant un Future , cela fonctionne. Cependant, mon problème d'attente monte, à l'endroit où la fonction getString est appelée.
Objectif: la fonction doit retourner la chaîne déchiffrée et le thread principal doit attendre que les données soient disponibles.

Ajouté à partir d'une réponse de l'OP qui aurait dû être une édition:

Désolé de ne pas être assez précis. Ma page se charge dans son propre fil de discussion. Dans le fil, je veux obtenir la valeur du magasin. Le thread ne peut pas continuer car l'instruction suivante dépend des données du magasin.

Par exemple. J'ai besoin du nom d'utilisateur et du mot de passe du magasin pour pouvoir me connecter. le nom d'utilisateur et le mot de passe sont stockés séparément.

Bien sûr, je peux imbriquer les déclarations «alors», mais je pense que pour la lisibilité du code source, il est préférable d'attendre que la valeur soit lue depuis le magasin. p >


0 commentaires

4 Réponses :


0
votes

Vous devez ajouter les mots-clés async et Future comme suit:

getString("someKey").then((valueString) => print(valueString));

et pour utiliser cette méthode asynchrone, vous devez le faire de la manière suivante:

static Future<String> getString(String key)  async { // ------> here
   SharedPreferences prefs = await SharedPreferences.getInstance();

   return _decrypt(prefs.getString(key));   
}


0 commentaires

7
votes

Vous ne devez jamais bloquer le thread principal, car il bloque les opérations de l'application. Votre initialisation peut prendre du temps et le système peut tuer vos applications si nécessaire.

Pour résoudre votre problème, il est préférable de ne pas bloquer le thread principal, et cela peut être fait en créant un écran de chargement, attendez que le chargement des données soit terminé, et affichez l'écran final de l'application.

Le prototype de code pourrait être comme suit:

class HomePage extends StatefulWidget {
  @override
  HomePageState createState() => HomePageState();
}

class HomePageState extends State<HomePage> {
  String data;

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

    loadData().then((data) {
      setState(() {
        this.data = data; 
      });
    });
  }

  Future loadData() async {    
    data = 'xxx'; // load your data from SharedPreferences
    return data;    
  }

  @override
  Widget build(BuildContext context) {
    if (data == null) {
      loadData();
      return LoadingScreen();
    } else {
      return MainScreen();
    }
  }
}


0 commentaires

0
votes
          Future strUser() async {
            SharedPreferences sharedPreferences = await 
            SharedPreferences.getInstance();
            return sharedPreferences.getInt('strUser');
          }

  init(){
         await SharedPreferenceFunction().strUser().then((value) {
                   setState(() {
                    this.strUser = value; 
                  });
                });
    }

1 commentaires

À quelle question répond cette question et comment? Veuillez tenir compte de Comment rédiger une bonne réponse?



0
votes

Appelez simplement de cette façon voici Ma fonction & Définir l'état est Imp!

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    checkInCart();

  }

et l'appeler dans

checkInCart()async{
    bool pre=await storage.containsKey(key: '${widget.eventIndex}');
    if(pre) {
      setState(() {
        isavail=true;
        favorite=true;
      });

    }

  }

Cela doit fonctionner Bienvenue à l'avance!


0 commentaires