
2.3 第一个程序——Hello World
下面我们来运行一个Demo,以检验配置的成果。习惯上,我们把搭建好环境后的首个程序称为“Hello World”,本小节以mac OS系统和Android Studio为例。
2.3.1 运行自诊断脚本
启动Terminal运行自诊断脚本,它将会检查环境配置是否有问题,或者是否缺少组件等。同时,还将为自身的运行做首次配置。而在运行自诊断脚本前,需要先运行下列指令:

这里的操作要求反复按空格键,直到出现可以输入“agree”为止。此时,输入“agree”并按回车键,即同意Xcode许可协议。然后运行

为Xcode做最后的配置。
之后,需要执行下列语句,并同意Android SDK的许可协议:

在每次询问是否同意时,都输入“y”并按回车键。
最后输入:

启动自诊断脚本。这一过程可能需要输入当前账户的密码,而且时间略长。最后,如图2.14所示,即表明环境配置正确无误。

图2.14 配置无误的终端提示
如果此处出现了感叹号甚至红叉号的错误提示,则需要根据提示内容复查配置内容。这里要注意,某些感叹号只是警告并非是必须要解决的问题。
2.3.2 启动Android模拟器
为了保证App的普适性,如无例外,本书将尽量以模拟器作为示例的运行平台。其版本为Android 8.1,模拟的设备为Google Pixel。
创建模拟器的过程十分简单:启动Android Studio,展开右下方的Configuration下拉菜单,选择AVD Manager(虚拟设备管理器)。在弹出的窗口中单击“Create Virtual Device(创建虚拟设备)”按钮,依次选择Pixel,然后选择下载API 27的Oreo版本,如图2.15所示。

图2.15 下载虚拟设备镜像文件
选择下载好的镜像,然后单击“Finish”按钮,新建的模拟器设备就出现在虚拟设备列表中了,如图2.16所示。

图2.16 建好的虚拟设备
点击在Actions一列中的左侧三角图标启动虚拟设备,会看到一部无论是外形还是系统都和真实的Pixel手机相同的设备,如图2.17所示。

图2.17 虚拟的Pixel手机
选择AVD和Android 8.1是由Android系统版本在当前市场上的占有率决定的。众所周知,Android操作系统的碎片化很严重,有不同的版本、尺寸等。
在实际开发中,首先,要考虑的就是兼顾大多数用户,因此,选取一个当前市场占有率最高的Android系统版本是明智之举。其次,虽然各厂商对Android操作系统都有不同程度的定制,但是本质上还是一样的,所以使用AVD更具有通用性,可以规避某一个品牌或机型的差异性。
2.3.3 将项目运行在模拟器上
在Android Studio的启动界面中选择Start a new Flutter project,开启新建项目向导。我们选择Flutter Application,然后单击“Next”按钮进入下一步,如图2.18所示,再输入必要的信息进入设置包名的相关步骤。

图2.18 新建Flutter项目
注意:Project name必须以小写字母开头,而且不可以有空格。
我们可以跳过这一步的设置,直接单击“Finish”按钮。图2.19所示为Android Studio的工作区,之后的编码、调试等工作基本上都会在这个环境中进行。随着练习的逐步深入,会逐步了解Android Studio的各种功能并将其设置为自己习惯的界面风格。
单击界面右上角的三角图标,程序开始编译代码,然后运行在已经启动的模拟器上。这样,一个简单的Flutter应用程序就运行起来了,如图2.20所示。

图2.19 Android Studio工作区

图2.20 Hello Flutter
2.3.4 探索Flutter热修复特性
和传统的原生开发不同,Flutter具有热修复(在某些情况下称之为热重载)特性。热修复特性是Flutter的重要特性之一。所谓热修复,指的是无须重新启动App,即可快速地将修改后的源代码文件注入正在运行的Dart虚拟机中,而Dart虚拟机会立即套用修改后的代码。Flutter框架会自动重新构建组件树实现热修复。
我们来动手实践一次,体会一下这既神奇又实用的特性。在上面的Hello World程序中,每点击一次右下方的“+”按钮,上方的计数器就会增加1。打开main.dart文件,找到下列代码:

将其改为

然后按“Command+S”组合键进行保存,再次回到模拟器,点击右下角的“+”按钮,这时发现计数器每次增加2。虽然这里程序的逻辑已经发生变化,但是并没有重新安装App的过程。
打开Android Studio的控制台输出,发现如下日志:

由日志得知,是热修复特性起了作用。特别注意的是,以下几种情况无法执行热修复。
◎ 编译错误:如果修改的代码存在编译错误,那么就无法执行热修复,如语句末尾少了分号。
◎ 修改后的代码影响了修改前的状态(即数据):实际上,Flutter的热修复可以保留运行时的状态,如用户登录状态,但如果代码的更改影响到了这些状态,则有可能导致热修复后的运行效果和期望的不一致。
◎ 对于静态字段:对于final修饰的常量值,在修改后不会有所变化,仍为修改前的值。
◎ 对于UI组件:如果修改后的代码不会因重新构建Widget组件树而被重新执行的话,热修复就对其不起作用,并且不会抛出任何异常。
◎ 枚举类型更改为常规类,或常规类更改为枚举类型,都会导致热修复失败。
◎ 更改泛型类型声明会导致热修复失败。