热门标签 | 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;


推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 【Windows】实现微信双开或多开的方法及步骤详解
    本文介绍了在Windows系统下实现微信双开或多开的方法,通过安装微信电脑版、复制微信程序启动路径、修改文本文件为bat文件等步骤,实现同时登录两个或多个微信的效果。相比于使用虚拟机的方法,本方法更简单易行,适用于任何电脑,并且不会消耗过多系统资源。详细步骤和原理解释请参考本文内容。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
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社区 版权所有