Flutter开发桌面应用,Google准备了三年!终于发了!

4,161 阅读3分钟

已经三年了

Desktop Embedding for Flutter项目,从提交“Initial commit”(2018年2月15日)到现在,已经三年了。

一年前的官方文档仍然警告用户,“不打算用于生产”

终于可以用于生产了

目前该文档已经改成如下:

有两个要点:

  1. 从一个独立的项目到嵌入到flutter,可以说由干儿子变成了亲儿子了
  2. 去掉了不适用于生产环境的提示:
- The code and examples here, and the desktop Flutter libraries they use, are in early stages, and not intended for production use.
- 这里的代码和示例,以及它们使用的桌面Flutter库处于早期阶段,不打算用于生产。

目前新的文档在:Desktop-shells

从文档的历史记录我们可以看到这个发展过程:

2019年12月5日:支持了macos

2020年7月8日:linux平台就已经进入了alpha阶段

2020年9月24日:windows平台进入alpha阶段

截止2020年9月文档中windows平台的状态由“early technical preview”改成了“alpha”,至此三大平台的状态都进入了alpha。

用Flutter开发桌面应用,可以说是蓄势待发了。 2021年2月25日文档有进行了一次变更但仅仅是文本格式变更,难道是在做发布前的准备?

今天有时间,忍不住体验了一下macos端app的开发。分享一下过程:

Flutter桌面应用开发初体验

由于目前处于目前尚处于alpha阶段,因此我们必须将Flutter的channel切换到dev才行。

切换channel

输入“flutter channel dev”结果如下:

$ flutter channel dev
Switching to flutter channel 'dev'...

....

flutter upgrade
git: Switched to a new branch 'dev'
git: Branch 'dev' set up to track remote branch 'dev' from 'origin'.
Successfully switched to flutter channel 'dev'.
To ensure that you're on the latest build from this channel, run 'flutter
upgrade'

更新flutter

上一步的提示,按照提示我们执行“flutter upgrade”进行更新

$ flutter upgrade
Downloading Dart SDK from Flutter engine 6993cb229b99e6771c6c6c2b884ae006d8160a0f...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  199M  100  199M    0     0  10.5M      0  0:00:18  0:00:18 --:--:-- 10.7M
Building flutter tool...
Flutter is already up to date on channel dev
Flutter 1.27.0-8.0.pre • channel dev • https://github.com/flutter/flutter.git
Framework • revision b7d4806243 (7 days ago) • 2021-02-19 09:22:45 -0800
Engine • revision 6993cb229b
Tools • Dart 2.13.0 (build 2.13.0-30.0.dev)

配置

flutter config --enable-macos-desktop

参考:flutter.dev/desktop 其他平台:

 flutter config --enable-windows-desktop
 flutter config --enable-macos-desktop
 flutter config --enable-linux-desktop

验证

看一下我们的桌面设备是否能找到了

$ flutter devices
Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure
you trust this source!
Downloading Material fonts...                                      457ms
Downloading Gradle Wrapper...                                       33ms
Downloading package sky_engine...                                  158ms
Downloading flutter_patched_sdk tools...                         1,111ms
Downloading flutter_patched_sdk_product tools...                 1,094ms
Downloading darwin-x64 tools...                                     3.3s
Downloading darwin-x64/font-subset tools...                        543ms
2 connected devices:

macOS (desktop) • macos  • darwin-x64     • Mac OS X 10.15.7 19H524 darwin-x64
Chrome (web)    • chrome • web-javascript • Google Chrome 88.0.4324.192

添加platform

以往我们创建的项目都是不带macos的平台的。

我们可以通过下面这条命令,向已有项目添加platform: “flutter create --platforms=macos .” 执行完这条命令我们可以在项目根目录下发现一个macos目录。

接下来就是激动人心的flutter run 时刻了。 然而和以往不同的是,现在需要我们选择设备了。 即便你没有连接手机,你也已经有两个设备了:

macOS (desktop)        • macos                                    • darwin-x64     • Mac OS X 10.15.7 19H524 darwin-x64
Chrome (web)           • chrome                                   • web-javascript • Google Chrome 88.0.4324.192

这样我们就需要传递设备id了 现在我们通过这条命令就可以启动我们的macos桌面app了。

运行桌面app

flutter run -d macos

桌面应用的一个特点是鼠标移动到一个控件上的时候,可以给用户一个提示。

默认的例子中floatingActionButton的tooltip就是用来设置提示文案的。

当我们将鼠标移动到右下角的悬浮按钮上的时候,就会见到这个提示了。

import 'package:flutter/material.dart';

// ...
class _MyHomePageState extends State<MyHomePage> {
    
  // ...

  @override
  Widget build(BuildContext context) {
    
    return Scaffold(
      // ...
      body: Center(
        // ...
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

如果我们还想在手机上开发应用需要指定设备

列出设备:

如果我们同时连接了安卓和ios手机结果会是这样

$ flutter devices
4 connected devices:

Redmi K30 Pro (mobile) • c7e616ee                                 • android-arm64  • Android 10 (API 29)
xxx的iPhone (mobile)    • 1cbcdf88d261301317e2d83b07fcfbb48501e47d • ios            • iOS 13.6.1
macOS (desktop)        • macos                                    • darwin-x64     • Mac OS X 10.15.7 19H524 darwin-x64
Chrome (web)           • chrome                                   • web-javascript • Google Chrome 88.0.4324.192

按照设备运行

此时如果我们想用安卓手机调试则需要输入:

flutter run -d c7e616ee

如果想要用ios手机调试则输入:

flutter run -d 1cbcdf88d261301317e2d83b07fcfbb48501e47d

折腾完hello word并不过瘾,又将以前的项目拿出来实验。

解决联网问题

然而意外发生了。

SocketException: Connection failed (OS Error: Operation not permitted, errno = 1)

开始我天真的以为这是苹果禁用http的后果, 然后添加了NSAllowsArbitraryLoads:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>
    <!--- ... --->
</dict>
</plist>

上次就是这样成功的解决了iPhone上无法显示图片的问题, 然而这次并不管用。

随后经过探索发现macos还有其独特的权限控制。 参考: github.com/flutter/flu… flutter.dev/desktop#ent…


Important: The com.apple.security.network.server entitlement, which allows incoming network connections, is enabled by default only for debug and profile builds to enable communications between Flutter tools and a running app. If you need to allow incoming network requests in your application, you must add the com.apple.security.network.server entitlement to Runner-Release.entitlements as well, otherwise your app will work correctly for debug or profile testing, but will fail with release builds.

说人话就是:

需要在macos/Runner/DebugProfile.entitlements文件中添加com.apple.security.network.client权限。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.cs.allow-jit</key>
	<true/>
	<key>com.apple.security.network.server</key>
	<true/>
	<key>com.apple.security.network.client</key>
	<true/>
</dict>
</plist>

如果你想发布还需要在 macos/Runner/Release.entitlements添加“com.apple.security.network.server”和“com.apple.security.network.client"

再次运行桌面应用:

有点太丑了,随后适配了一下:

感兴趣的同学可以看一下源码: github.com/ovotop/flut…






⭐️⭐️⭐️⭐️⭐️
⭐️眼巴巴盼着你点赞⭐️
⭐️转发请保持文章完整⭐️
⭐️转发请注明出处:juejin.cn/post/684490…⭐️
⭐️本文作者正眼巴巴盼着你点赞⭐️