背景
公司要开发一款批量下载图片的应用,需要按照特定的目录结构来保存在电脑上,一开始规划是给web来实现,不过web实现有局限性,无法满足业务需求,刚好flutter最新的稳定版支持Windows,于是把这个任务接过来了,就有了公司第一款基于Windows的软件,接下来记录下开发Windows软件踩的坑
环境部署
我自己的开发电脑是Mac,既然flutter是跨平台的,应该也支持Windows吧,创建好了demo,愉快的运行打包命令,尝试打包
代码语言:javascript复制flutter build windows
然后被打脸了
代码语言:javascript复制"build windows" only supported on Windows hosts.
就像打包ios,必须在Mac的系统,window打包只能在Windows上,只能去搞一台Windows电脑了,考虑到平常开发调试,还是用Mac,window仅仅是为了打包,基于能省则省,联系运维搞了一台Windows虚拟机来负责打包
在虚拟机上部署flutter开发环境,配置git,配置ssh,安装IDE,拉取代码,搞了大半天,再次运行打包命令,这次完美出包了,生成包在这个Relase目录下
vc报错
生成的包本地运行正常,发给测试的Windows的运行验证,也是正常的,不过业务反馈,运行不了,报错如下
难道是业务的电脑跟测试的电脑不一样,反复对比多台电脑跟笔记本,包括系统配置,安装软件等,没找到规律,后经过大佬提醒,是不是vc环境的问题,网上搜索一波,果然有思路了
先找了个有异常的电脑,在电脑上打开控制面板程序程序和功能
,查看它的vc环境如下
另外找了个不会报错的电脑,vc环境如下
看起来,报错的电脑,是少了最新的vc环境,于是去Microsoft官网安装最新的vc库后,果然正常运行了 https://learn.microsoft.com/zh-CN/cpp/windows/latest-supported-vc-redist?view=msvc-170
Mac开发环境跟Windows打包环境的兼容
由于日常开发调试用Mac,所以在调用下载功能的时候,需要加个平台的判断
代码语言:javascript复制String downloadRootFolder = "D:\spu_images\";
if (Platform.isMacOS) {
downloadRootFolder = "/Users/weigan/Downloads/spu_images/";
}
在Mac跟Windows初始下载路径不同,这样两端都可以调试功能了,获取详细的下载子目录,也需要加对应的平台判断
代码语言:javascript复制 String getSpuFolder(String downloadFolder, String spuCode) {
if (Platform.isMacOS) {
return "$downloadFolder$spuCode/";
} else {
return "$downloadFolder$spuCode\";
}
}
toast问题
Android跟ios都可以很方便的弹出toast提示,也不依赖buildContext,但是在Windows平台就不行了,着实烦恼,toast功能都是依赖flutterToast这个库,所以只能采用带buildContext的方式弹toast,使用局限性大了许多,也是确实没办法
我是采用封装mixin的方式来使用,新建一个文件叫ToastMixin
,然后实现toast初始化和展示逻辑
mixin ToastMixin<T extends StatefulWidget> on State<T> {
late FToast fToast;
@override
void initState() {
super.initState();
fToast = FToast();
fToast.init(context);
}
showToast(String msg) {
Widget toast = Container(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
color: Colors.greenAccent,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(msg),
],
),
);
fToast.showToast(
child: toast,
gravity: ToastGravity.BOTTOM,
toastDuration: const Duration(seconds: 3),
);
}
}
需要弹出toast的地方,继承ToastMixin
就可以了,最大不方便的就是,不能在网络请求等没有buildContext的地方弹出toast了
图片加载问题
图片加载是一款软件基础的功能,不管是app还是Windows,使用的都是鼎鼎大名的图片加载库cached_network_image
,可是让我吐血的是,居然不支持Windows平台
Mac都支持了,居然不支持Windows,看来Windows的开发还是太少,生态建设还不够,心里很慌,于是哆哆嗦嗦的打开官网查一查,看有还没有一丝希望
皇天不负苦心人,2020年就回复在beta版本支持windows,可是都2022年了,怎么还不正式版本支持? 不管怎样,尝试一下吧,咔咔,报错了
多方尝试,后来终于找打方案了,新增了一个依赖库解决了这个问题
代码语言:javascript复制sqflite_common_ffi: ^2.1.1 1
长松了一口气,至此,相关核心的技术难题也基本解决了
软件配置
启动icon,是放在这个目录下的一个叫app_icon.ico
的文件
大小固定256*256,替换这个文件就可以了,另外软件名称跟初始的窗口大小,在main.cpp
里面设置
Win32Window::Point origin(10, 10);
//这里设置窗口的初始大小,当然也可以鼠标手动拖动窗口修改大小
Win32Window::Size size(1300, 800);
// pms_flutter就是软件名称
if (!window.CreateAndShow(L"pms_flutter", origin, size)) {
return EXIT_FAILURE;
}
软件发布
由于改软件是公司内部使用,不需要上传到微软的应用市场,所以直接用最简单的zip包交互方式就好了 运行打包命令flutter build windows
,打包成功后,把生成最终relase文件压缩,发给测试和产品即可,解压后,双击exe文件,既可以运行软件
总结
过来人说,第一次总是难免不太顺利的,不过至少在代码的世界,很多坑都已经有人踩过了,我们做到的就是找到解决方案,然后照搬过来就好了,这次windows软件的成功落地,我只做了不到1%的工作,剩余的99%都是基于前人已经做好的框架和组件去开发...