Flutter移动应用快速构建实践——状态管理、国际化、数据持久化、性能优化(二)
继续上一篇:极简诗词开发背后:Flutter移动应用快速构建实践——状态管理、国际化、数据持久化、性能优化(一) 前文中说到了项目结构、状态管理和国际化的方案,本文继续聊聊数据持久化和粗略的性能优化。 数据持久化 目前的话,flutter用的比较多比较成熟的数据持久化就是shared_preferences和SQFLite,一个是ini配置文件,一个是SQLite数据库,小应用我比较倾向只用前者,
目录5 个章节
继续上一篇:极简诗词开发背后:Flutter移动应用快速构建实践——状态管理、国际化、数据持久化、性能优化(一)
前文中说到了项目结构、状态管理和国际化的方案,本文继续聊聊数据持久化和粗略的性能优化。
数据持久化
目前的话,flutter用的比较多比较成熟的数据持久化就是shared_preferences和SQFLite,一个是ini配置文件,一个是SQLite数据库,小应用我比较倾向只用前者,比较方便,Sqflite能用,但是flutter至今没有很好用的ORM框架,用起来需要写很多SQL语句就很难受了。
所以下面介绍的是shared_preferences的简单用法,详细见官网:https://pub.flutter-io.cn/packages/shared_preferences
添加依赖:
dependencies:
shared_preferences: ^0.5.6
这里的官网的简单例子:
SharedPreferences prefs = await SharedPreferences.getInstance();
int counter = (prefs.getInt('counter') ?? 0) + 1;
print('Pressed $counter times.');
await prefs.setInt('counter', counter);
单纯抄一下官网的例子当然是不够的,我想说的数据持久化是这个,本项目用到的方法。
还记得上一篇写到的json model模块吗,它提供的对象序列化和反序列化在持久化中很好用,在保存数据的时候,将model类转换给json数据存在SharedPreferences配置中,例如:
/// 持久化Profile信息
static saveProfile() => _prefs.setString("profile", jsonEncode(profile.toJson()));
当App启动时,从SharedPreferences中读出json数据,使用model类的json构造函数,创建(反序列化)为model对象,例子如下:
_prefs = await SharedPreferences.getInstance();
var _profile = _prefs.getString("profile");
if (_profile != null) {
try {
profile = Profile.fromJson(jsonDecode(_profile));
// 防止读取出来是null,用于从版本已有profile数据的升级,如果是全新安装的没有这个问题
profile.darkMode = profile.darkMode ?? false;
} catch (e) {
print(e);
}
}
这样就完成了数据持久化的工作,非常简便。
相关配置
接下来先讲一点有关项目配置的,无论是flutter开发还是Android开发,那都是谷歌的技术,谷歌嘛你懂的,服务器都是被屏蔽的,而且用到的Gradle那些maven源也大多是访问不了的,所以每次编译成Android Apk的时候都很慢,我们需要设置一下国内源。
修改 android/build.gradle,把里面默认的google()和jcenter()改成下面的地址就好了。
repositories {
// google()
// jcenter()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
还要修改 android/gradle/wrapper/gradle-wrapper.properties文件。
#Wed Dec 11 15:10:31 HKT 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
把最后一行改成国内的服务器,如:distributionUrl=https\://downloads.gradle-dn.com/distributions/gradle-5.1.1-all.zip,改域名就可以了。
还有一个pub.dev,dart语言的包发布网站,国内访问不了,但我们有国内镜像:https://pub.flutter-io.cn/
感谢国内开源社区的大佬们的努力!
还有关于迁移到AndroidX的,也是一个坑来的,可以参考:Flutter开发:迁移Flutter应用到AndroidX
Flutter的“多线程”
接下来聊聊有关性能优化的实践,小标题的多线程我加了双引号,dart语言是单线程的,和js差不多,在flutter里面,UI和其他操作都是放在同一个线程执行的,如果主线程里面有耗时操作的话,界面就卡住了,flutter默认是60帧显示,所以如果一个操作不能在1/60秒内完成,就会影响界面刷新,产生明显的卡顿感。
那到底怎么解决啊?dart提出了一个叫Isolate的东西,类似线程,但是和主线程之间又不能共享内存,如果要共享数据,必须通过复制内存的方式传参和获取返回值,使用起来和多线程相比还是有很多限制的。
关于Isolate的详情我就不介绍那么多了,了解详情请查看官方文档和大佬的博客。这里记录一下我的实践。
前面说到主线程和isolate之间的切换开销很大,所以为了使用多线程又需要提升性能的话,就要减少isolate的创建,所以我们可以用“线程池”做负载均衡,在代码定义一个LoadBalancer,用来存我们的isolate。
Future<LoadBalancer> loadBalancer = LoadBalancer.create(4, IsolateRunner.spawn);
使用的时候通过loadbalancer创建可复用的isolate:
final lb = await loadBalancer;
lb.run(Isolate方法, 参数);
isolate方法是一个静态方法,接收一个参数,因为只能一个参数,所以要传多个参数的时候就需要自己定协议了,可以自己写一个类,也可以传dict或者list,我比较习惯传dict,不要单独再定义一个类。执行完的结果通过返回值返回,我一般也是返回一个dict(map)。
注意:isolate不能访问主线程的内存,在isolate内访问其他地方的变量都是无效的,请使用传参+获取返回值的方式交换数据。
并且现在不能使用print函数打印日志,也不能通过channel访问Android的logcat输出日志,据说是flutter的bug,唯一的方法是使用官方devtools里的日志工具,参考:https://flutter.dev/docs/testing/code-debugging
未完待续
不知不觉又写了很多了,还有剩下一些零碎的内容,以及更多性能优化和App体积优化的内容正在研究和总结中,下篇文章再继续更新~
欢迎交流
交流问题请在微信公众号后台留言,每一条信息我都会回复哈~
_EOF_
Flutter移动应用快速构建实践——状态管理、国际化、数据持久化、性能优化(二)
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
从细节入手改善用户体验,Flutter跨平台App开发中设置Android和iOS的启动页
前言 flutter开发App方便快捷,就是冷启动的时候要加载dart引擎有短暂的白屏,严重影响用户体验,这个时候我们就需要设置一个启动图片,像国内大部分App那样(例如微信那个地球),启动App的时候显示这个图片,加载完再进入App,不至于影响用户体验。 Android启动页 首先要准备好启动图,本文命名为splash.png,按照不同的分辨率添加到对应的mipmap-hdpi / mipmap
2021-12-18 · Flutter · 约 1 分钟
初见Flutter!框架简单介绍以及构建可发布的签名Apk包
哈喽!好久不见,算起来我已经一个多月没更新博客了,近期刚刚完成了一个项目,正好抽出时间整理一下学到的东西并且写写博客。 关于flutter 开始使用flutter还是春节后的事情,其实之前很早就想学一下flutter了,毕竟谷歌出的技术总是不会太差的,无奈一直没有时间和做app的需求,这次接触了flutter之后仿佛发现了新大陆,原来开发app还能这么方便,真的颠覆了我原来的认知啊,热更新也太好用
2021-12-18 · Flutter · 约 1 分钟
Windows上怎么配置flutter开发环境?这篇文章手把手教你
前言 在Windows上做开发,一个字:坑。 但是有时候外出只能带着笔记本,Linux在一些笔记本上不太兼容,驱动支持不完美,而且电源管理不够好,所以无奈的情况下只能用Windows暂时顶一下,就像现在我要在Windows上搭建Flutter的开发环境一样,太坑了。 进入正题 先安装Android SDK 首先,你要有一种可以下载到Android SDK的方式,可以是梯子,或者是国内镜像,具体我就
2023-03-05 · Flutter · 约 1 分钟
Flutter开发:ListView手动滚动到底部
这个问题搜了很久都没找到,国内关于flutter的研究好像还没多少,不过stackoverflow真的是万能的,这里记录一下~ 原文 Use ScrollController.jumpTo() or ScrollController.animateTo() method to achieve this. Here is code snippet (After 1 second, the ListV
2021-12-18 · Flutter · 约 1 分钟
讨论
共 0 条加载评论中…