热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Flutter数据处理

文章将会被同步至微信公众号:Android部落格文章参考:https:flutterchina.clubjson更多信息可以参考flutter官方教程&

文章将会被同步至微信公众号:Android部落格
文章参考:https://flutterchina.club/json/
更多信息可以参考flutter官方教程:https://flutter.dev/docs/cookbook


一、文件IO

PathProvider 插件提供了一种平台透明的方式来访问设备文件系统上的常用位置。该类当前支持访问两个文件系统位置:

  • 临时目录: 系统可随时清除的临时目录(缓存)。在iOS上,这对应于NSTemporaryDirectory() 返回的值。在Android上,这是getCacheDir()返回的值。
  • 文档目录: 应用程序的目录,用于存储只有自己可以访问的文件。只有当应用程序被卸载时,系统才会清除该目录。在iOS上,这对应于NSDocumentDirectory。在Android上,这是AppData目录。

1)在pubspec.yaml中添加path_provider库

dependencies:
path_provider: 0.4.1

2)在dart文件中实现文件读写方法

import 'dart:io';
import 'package:path_provider/path_provider.dart';

读文件:

Future<File> _getLocalFile() async {// get the path to the document directory.String dir &#61; (await getApplicationDocumentsDirectory()).path;return new File(&#39;$dir/counter.txt&#39;);
}Future<int> _readCounter() async {try {File file &#61; await _getLocalFile();// read the variable as a string from the file.String contents &#61; await file.readAsString();return int.parse(contents);} on FileSystemException {return 0;}
}

getApplicationDocumentsDirectory这一行代码的路径对应到Android路径下是&#xff1a;

/data/data/com.example.flutterhello/app_flutter

写文件&#xff1a;

await (await _getLocalFile()).writeAsString(&#39;$_counter&#39;);

通过库中的接口可以直接实现从File读写string

二、Json操作

Flutter有一个内置dart:convert库&#xff0c;其中包含一个简单的JSON编码器和解码器。

{"name": "John Smith","email": "john&#64;example.com"
}

有了dart:convert&#xff0c;我们可以用两种方式来序列化这个JSON model。

1&#xff09;内连序列化JSON

Map<String, dynamic> user &#61; JSON.decode(json);
print(&#39;Howdy, ${user[&#39;name&#39;]}!&#39;);
print(&#39;We sent the verification link to ${user[&#39;email&#39;]}.&#39;);

JSON.decode()仅返回一个Map&#xff0c;这意味着我们直到运行时才知道值的类型&#xff0c;这样就失去了大部分静态类型语言特性&#xff1a;类型安全、自动补全和最重要的编译时异常。这样一来&#xff0c;代码可能会变得非常容易出错。

2&#xff09;在模型类中序列化JSON

可以通过引入一个简单的模型类(model class)来解决前面提到的问题&#xff0c;称之为User。在User类内部&#xff0c;我们有&#xff1a;
一个User.fromJson 构造函数, 用于从一个map构造出一个 User实例 map structure
一个toJson 方法, 将 User 实例转化为一个map.

class User {final String name;final String email;User(this.name, this.email);User.fromJson(Map<String, dynamic> json): name &#61; json[&#39;name&#39;],email &#61; json[&#39;email&#39;];Map<String, dynamic> toJson() &#61;>{&#39;name&#39;: name,&#39;email&#39;: email,};
}

现在&#xff0c;序列化逻辑移到了模型本身内部。采用这种新方法&#xff0c;可以非常容易地反序列化user。

Map userMap &#61; JSON.decode(json);
var user &#61; new User.fromJson(userMap);
print(&#39;Howdy, ${user.name}!&#39;);
print(&#39;We sent the verification link to ${user.email}.&#39;);

要序列化一个user&#xff0c;我们只是将该User对象传递给该JSON.encode方法。我们不需要手动调用toJson这个方法&#xff0c;因为JSON.encode已经为我们做了。
String json &#61; JSON.encode(user);

3&#xff09;使用代码生成库序列化JSON

这种json处理方式需要在项目中设置json_serializable&#xff0c;要包含json_serializable到我们的项目中&#xff0c;需要一个常规和两个开发依赖项。简而言之&#xff0c;开发依赖项是不包含在我们的应用程序源代码中的依赖项。

dependencies:json_annotation: ^2.0.0
dev_dependencies:build_runner: ^1.0.0json_serializable: ^2.0.0

将我们的User类转换为一个json_serializable&#xff1a;

import &#39;package:json_annotation/json_annotation.dart&#39;;
// user.g.dart 将在我们运行生成命令后自动生成
part &#39;user.g.dart&#39;;

///这个标注是告诉生成器&#xff0c;这个类是需要生成Model类的

&#64;JsonSerializable()
class User {User(this.name, this.email);String name;String email;//不同的类使用不同的mixin即可factory User.fromJson(Map<String, dynamic> json) &#61;> _$UserFromJson(json);Map<String, dynamic> toJson() &#61;> _$UserToJson(this);
}

有了这个设置&#xff0c;源码生成器将生成用于序列化name和email字段的JSON代码。
有两种生成序列化的方式&#xff1a;

第一种&#xff0c;一次性生成

项目根目录下运行flutter packages pub run build_runner build&#xff0c;我们可以在需要时为我们的model生成json序列化代码。 这触发了一次性构建&#xff0c;它通过我们的源文件&#xff0c;挑选相关的并为它们生成必要的序列化代码。
可以看到在user.dart所在的目录下生成了user.g.dart文件&#xff0c;内容如下&#xff1a;

// GENERATED CODE - DO NOT MODIFY BY HANDpart of &#39;user.dart&#39;;// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************User _$UserFromJson(Map<String, dynamic> json) {return User(json[&#39;name&#39;] as String, json[&#39;email&#39;] as String);
}Map<String, dynamic> _$UserToJson(User instance) &#61;><String, dynamic>{&#39;name&#39;: instance.name, &#39;email&#39;: instance.email};

第二种&#xff0c;持续生成

使用_watcher_可以使源代码生成的过程更加方便。它会监视项目中文件的变化&#xff0c;并在需要时自动构建必要的文件。可以通过flutter packages pub run build_runner watch在项目根目录下运行来启动_watcher_。只需启动一次观察器&#xff0c;然后并让它在后台运行&#xff0c;这是安全的。
可以动态的在user.dart中添加变量id&#xff0c;可以自动更新对应目下的user.g.dart文件&#xff1a;

// GENERATED CODE - DO NOT MODIFY BY HANDpart of &#39;user.dart&#39;;// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************User _$UserFromJson(Map<String, dynamic> json) {return User(json[&#39;name&#39;] as String, json[&#39;email&#39;] as String, json[&#39;id&#39;] as String);
}Map<String, dynamic> _$UserToJson(User instance) &#61;> <String, dynamic>{&#39;name&#39;: instance.name,&#39;email&#39;: instance.email,&#39;id&#39;: instance.id};

4&#xff09;使用json_serializable模型

要通过json_serializable方式反序列化JSON字符串&#xff0c;不需要对先前的代码进行任何更改。

Map userMap &#61; JSON.decode(json);
var user &#61; new User.fromJson(userMap);

序列化也一样。调用API与之前相同。

String json &#61; JSON.encode(user);

有了json_serializable&#xff0c;我们可以在User类上忘记任何手动的JSON序列化 。源代码生成器创建一个名为user.g.dart的文件&#xff0c;它具有所有必需的序列化逻辑。

三、shared_preferences

shared_preferences 包含了Android的SharedPreferences接口和iOS的NSUserDefaults接口。

1&#xff09;在pubspec.yaml添加库支持

https://pub.dartlang.org/packages/shared_preferences
dependencies:flutter:sdk: fluttershared_preferences: "0.4.3"

2&#xff09;获取实例写数据

final prefs &#61; await SharedPreferences.getInstance();
// Try reading data from the counter key. If it does not exist, return 0.
final counter &#61; prefs.getInt(&#39;counter&#39;) ?? 0;

3&#xff09;保存数据

// obtain shared preferences
final prefs &#61; await SharedPreferences.getInstance();// set value
prefs.setInt(&#39;counter&#39;, counter);

4&#xff09;删除数据

final prefs &#61; await SharedPreferences.getInstance();prefs.remove(&#39;counter&#39;);

5&#xff09;支持的数据类型

支持的数据类型是&#xff1a;int, double, bool, string and stringList
不支持写大量的数据。
另外需要注意的是&#xff0c;获取SharedPreferences是阻塞式的&#xff0c;因为get数据的时候如果mMap没有初始化就一直等着&#xff1a;

_loadCounter() async {SharedPreferences prefs &#61; await SharedPreferences.getInstance();setState(() {_counter &#61; (prefs.getInt(&#39;counter&#39;) ?? 0);});}

详细分析见文章&#xff1a;Android SharedPreferences

微信公众号二维码&#xff1a;


推荐阅读
author-avatar
老谢2502887117
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有