preface
Local actions must be used to save user information or network data during the development process of FLUTTER. There is a local action in the form of key-value in FLUTTER (just like NSUserDefaults in ios).
In addition, the conversion between JSON and objects is described here
JOSN quickly generates a variety of language Model entries
Demo address (contents in the fileManager folder, can replace main comments try effect)
Tips: If you’re storing a lot of data and need a relational database, you can search for other sources
Persistent storage (key-value)
Import shared_preferences
The repository for persistent storage was developed by the Flutter team and is called shared_preferences, but it exists as a third-party repository and therefore needs to be imported manually
flutter pub add shared_preferences
Copy the code
After the import, you can directly import directly to use (generally use prompt import)
import 'package:shared_preferences/shared_preferences.dart';
Copy the code
SharedPreferences is introduced
SharedPreferences is a singleton and is a Future asynchronous function, so we need to call the Future asynchronous function to get the singleton and await it.
General principle: Similar to other three-party caching principles, file information is saved in one copy in memory, and all data is read into memory at one time during initialization
Advantages and disadvantages can be clearly seen: fast access speed, large memory footprint, suitable for saving small information
If you store a large amount of data, or if you need to store complex data, you need to choose another database
Database: Relational database SQLite, Core Data, GreenDao, etc. For non-relational databases, options include Realm and UnQLite. For Key/Value stores, there are Redis, Berkeley DB, Level DB, and so on
You can choose a packaged database based on your needs, typically SQLite or Realm on mobile
SharedPreferences Read and write operations
To store data
By passing key and value, you can store all kinds of basic data, and find that there is no store object (not introduced later).
// This is just a generics demonstration. You can actually call whichever you want
static saveInfo<T>(String key, T value) async {
// We need to get the singleton object with await
final manager = await SharedPreferences.getInstance();
// The default uses are as follows
manager.setBool(key, value as bool);
manager.setDouble(key, value as double);
manager.setInt(key, value as int);
manager.setString(key, value as String);
manager.setStringList(key, value as List<String>);
}
Copy the code
Read the data
By passing the key, you can call the corresponding get method directly.
// This is just a generics demonstration. You can actually call whichever you want
static Future<T> readInfo<T>(String key) async {
final manager = await SharedPreferences.getInstance();
return manager.getString(key) as T;
return manager.getBool(key) as T;
return manager.getDouble(key) as T;
return manager.getInt(key) as T;
return manager.getString(key) as T;
return manager.getStringList(key) as T;
}
Copy the code
Delete the data
Delete not to say, pass a key to delete
static remove(String key) async {
final manager = await SharedPreferences.getInstance();
manager.remove(key);
}
Copy the code
Json converts and stores objects to and from objects
Shared_preferences shared_preferences does not have the ability to store objects, so we can store objects instead of JSON strings
Therefore, the step you need to understand is the json to object conversion
There is currently no reflection mechanism in Flutter, so friendly one-click conversion is not possible. Currently, Map can only be used as a link. Json and Map can be converted to each other
Conversion between JSON and Map
Through the system prefabricated convert library, to achieve the conversion process
Convert a Map to a jsonString using jsonEncode
final userMap = {
name: "Marshal".age: 20
}
// Convert map to jsonString
final jsonString = jsonEncode(userMap);
Copy the code
JsonString is converted to a Map by jsonDecode
final jsonString = "{"name":"Marshal","age": 20}";
//jsonString is converted to Map
final jsonMap = jsonDecode(jsonString);
Copy the code
Transformations between objects and maps
Using the UserInfo class as an example, create two methods (each class that needs to be saved implements these two methods)
JsonMap to object: Using the named constructor, you can convert the jsonMap passed to this object
Object to jsonMap: You can use object methods or class methods to convert objects created by this class to Maps
// Select the class name and press CTL + Enter to generate Constructor. Select the attributes that need to be initialized by default to generate the parameterized Constructor
class UserInfo {
String name;
int age;
UserInfo(this.name, this.age);
// The factory constructor can also be used
UserInfo.fromJson(Map<String, dynamic> json): name = json['name'], age = json['age'];
// If you want to write as a protocol, you can inherit the protocol when archiving (json and object interchange, for ease of use), then you can use normal methods instead of constructors
Map<String, dynamic> toJson() =>
{'name': name, 'age': age};
}
Copy the code
Indirect conversions between objects and JSON
Convert an object to a JSON string indirectly, using UserInfo as an example
final userInfo = UserInfo("Marshal".20);
// Convert UserInfo to jsonMap
final userMap = userInfo.toJson();
// Then call jsonEncode to convert the map to jsonString
final jsonString = jsonEncode(userMap);
//jsonEncode can only convert a map to JSON by default, so two callbacks are needed to convert an object to a map before converting it
// The same as above
final jsonString2 = jsonEncode(value,
toEncodable: (Object? value) = > value is UserInfo
? value.toJson()
: throw UnsupportedError('Cannot convert to JSON: $value'));
Copy the code
Convert a JSON string to an object indirectly, using UserInfo as an example
final jsonString = "{"name":"Marshal","age": 20}";
// Convert jsonString to jsonMap
final jsonMap = jsonDecode(jsonString); // Convert to Map
// Convert jsonMap to UserInfo
final userInfo = UserInfo.fromJson(jsonMap);
Copy the code
SharedPreferences Access objects
Store the object. Putting all the previous steps together, store the json string converted by the object
static saveObject(String key, UserInfo value) async { final manager = await SharedPreferences.getInstance(); // You can actually set UserInfo as a generic constraint to inherit (or inherit) a class or implement an interface through which toJson methods are called // Converting a class to jsonString requires calling the corresponding class's toJson methods, Final userMap = value.tojson (); // Then call jsonEncode to convert the map to jsonString final jsonString = jsonEncode(userMap); JsonString2 = jsonEncode(value, toEncodable: = jsonEncode(value, toEncodable: = jsonEncode)) (Object? value) => value is UserInfo ? value.toJson() : throw UnsupportedError('Cannot convert to JSON: $value')); if (jsonString.isEmpty) return; manager.setString(key, jsonString); log('jsonEncode --' + jsonString); }Copy the code
Read the object, combining the previous steps, to read the json string transformed object
static Future<dynamic> readObject(String key) async { final manager = await SharedPreferences.getInstance(); final jsonString = manager.getString(key); if (jsonString ! = null) { final jsonMap = jsonDecode(jsonString); // Convert to Map log('jsonDecode --' + jsonmap.tostring ()); Return userinfo.fromjson (jsonMap); return userinfo.fromjson (jsonMap); } return null; }Copy the code
FileManagerEx(improved access object version, currently does not solve the constructor problem, can only be slightly limited, just for reference)
The last
Shared_preferences is only suitable for storing a small amount of data, such as basic user information, search information, etc. If you need a large amount of data, or relational, you can switch to other preferences
This object and JSON interchange is the main introduction to this chapter