Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving State After App Is Closed with Provider Package FLUTTER

What's the best way to save an activity page state with Flutter provider package? Currently, using the provider package and doing a restart or closing the app the page gets rebuilt and all the new widgets are removed. The state is saved on hot reload not hot restart. For example, the post created by a user on the news feed page is removed when I close the app or restart it.

like image 738
createdonthate Avatar asked Jan 22 '20 03:01

createdonthate


People also ask

How do you save data when an app is closed on Flutter?

I think the right and safety way is using pop modal when try to close or exit and let use chose save or not. don't forget that u have to let user learn how to use app, not let them make u change app cause of misuse. There is difference between the coding app to use simple interface and make it work safety and easy.

How do you keep state in Flutter?

Obviously you have to use AutomaticKeepAliveStateMixin to main the state of pages to want to maintain state 2nd Method The other way which is simple and handy is to use indexedStack widget and provide it a set of children(pages) and current page index.

Why is Exit 0 not preferred for closing an app Flutter?

Close Android App With Code: exit(0) : This command also works but it is not recommended because it terminates the Dart VM process immediately and users may think that the app got crashed.


1 Answers

So following the comment and reading the flutter persistence cookbook, I see three common possibilites:

  • Persist data with SQLite
  • Read and write files
  • Store key-value data on disk

Each has different usecases, but I think the common case is to store a few objects as JSON. SQLite seems to me in simple cases an overkill and key-values do not offer enough flexibility. So I will focus on reading and writing files.

Here comes an example. I use JSON code generation libraries as described here.

The data object I read and write to disk is looks the following way:

import 'package:json_annotation/json_annotation.dart';

// json methods generated using code geneartion
// see https://flutter.dev/docs/development/data-and-backend/json#serializing-json-using-code-generation-libraries
part 'easy_data.g.dart';

@JsonSerializable()
class EasyData {
    int counter;
    String data;

    EasyData(this.counter, this.data);

  // run the following command to generate json:
  // flutter pub run build_runner build
  factory EasyData.fromJson(Map<String, dynamic> json) => _$EasyDataFromJson(json);

  Map<String, dynamic> toJson() => _$EasyDataToJson(this);
}

The Service to load the json from disk and save looks the following way:

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

import '../model/easy_data.dart';

class FileStorage with ChangeNotifier {
  EasyData loadedData;

  Future<String> get _localPath async {
    final directory = await getApplicationDocumentsDirectory();
    return directory.path;
  }

  Future<File> get _localFile async {
    final path = await _localPath;
    return File('$path/app_data.json');
  }

  loadData() async {
    try {
      final file = await _localFile;
      // Read the file
      String contents = await file.readAsString();
      if (contents != null) {
        // parse json if file was saved before
        loadedData = EasyData.fromJson(json.decode(contents));
        notifyListeners();
      }
    } on FileSystemException catch (_) {
      // the file did not exist before
    } catch (e) {
      // error handling
      log(e);
    }
  }

  Future<File> writeData(EasyData data) async {
    final file = await _localFile;
    // Write the file
    return file.writeAsString(jsonEncode(data.toJson()));
  }
}

I used a provider for the service, because I want other services to be notified when the data is loaded from disk. The other Providers need to be declared with ChangeNotifierProxyProvider in main dart to use the information from the FileStorage Provider.

I hope it this was helpful.

like image 113
Adam Avatar answered Oct 23 '22 11:10

Adam