联网 App 第 1 课:连通测试,把一句话存到服务器再读回来(附 .aia 源码)

第 1 课 连通测试:把一句话保存到自己搭的服务器,再从服务器读回来,并显示用了多少毫秒。连不上时告诉你该检查什么。

下载 NetHello.aia 返回联网 App 专题

这一课学什么

  • 服务地址:网络微数据库把数据发到哪里,由「服务地址」属性决定。
  • 异步:点了按钮,App 不会停下来等服务器回话;结果在事件里才拿到。
  • 出错处理:服务器没开、地址抄错时,在「发生 Web 服务故障时」里告诉用户原因。
连通测试界面预览

图为由最终 .aia 执行真实积木生成的布局预览,不是真机截图。截图是在电脑上用本机地址跑的;你在手机上要填服务端窗口里显示的局域网地址(如 http://192.168.1.19:5000/口令)。

准备

  1. 按《网络微数据库后台搭建教程》启动服务端,并用手机浏览器打开服务地址,看到「网络微数据库:共 0 条,图片 0 张」。
  2. 下载 NetHello.aia,在 App Inventor 里「项目 → 导入项目」,连上 AI 伴侣。

想自己从空白项目搭,就照下面的步骤做;直接导入的同学可以对照着看懂每一块。

第一步:界面

组件 名字 要设置的属性
文本输入框 文本输入框_地址 提示:如 http://192.168.1.19:5000/3f9a1c7e
按钮 按钮_保存地址 文本:保存
标签 标签_地址状态 字号 12
文本输入框 文本输入框_内容 提示:写一句话
按钮 按钮_保存、按钮_读取 文本:保存到服务器 / 从服务器读取
标签 标签_结果 显示结果
网络微数据库 网络微数据库1 服务地址先不用改,代码里设置
微数据库 微数据库1 把服务地址存在手机上
计时器 计时器1 取消勾选「启用计时」,只用来取当前时间
底部提示条 底部提示条1 显示简短提示

.aia 里还用「组件美化」把三块区域做成了卡片,和功能无关,可以不加。

第二步:服务地址存在手机上

每个人的服务地址都不一样(IP 和口令都不同),不能写死在积木里。做法是:用户填一次、点保存,存进微数据库(手机本地),每次打开 App 读出来设给网络微数据库。

when Screen1.Initialize() {
  文本输入框_地址.Text = 微数据库1.GetValue("serviceUrl", "")
  使用地址(文本输入框_地址.Text)
}

when 按钮_保存地址.Click() {
  var 地址 = trim(文本输入框_地址.Text)
  if textLength(地址) > 0 and segment(地址, textLength(地址), 1) == "/" {
    地址 = segment(地址, 1, textLength(地址) - 1)
  }
  if not (startsat(地址, "http://") == 1 or startsat(地址, "https://") == 1) {
    底部提示条1.Show("服务地址要以 http:// 开头,照抄服务端窗口里显示的那一行")
  } else {
    文本输入框_地址.Text = 地址
    微数据库1.StoreValue("serviceUrl", 地址)
    使用地址(地址)
    底部提示条1.Show("服务地址已保存")
  }
}

procedure 使用地址(地址) {
  if 地址 == "" {
    标签_地址状态.Text = "还没填:启动服务端后,窗口里「服务地址」那一行就是。"
  } else {
    网络微数据库1.ServiceURL = 地址
    标签_地址状态.Text = join("正在使用:", 地址)
  }
}
  • 去掉首尾空格和末尾的 /:从微信、浏览器复制过来的地址常常多带这些。
  • 「求起始位置」等于 1 就表示文字以它开头。

中途验证:填地址点保存,标签显示「正在使用:http://…」;关掉 App 再打开,地址还在。

第三步:保存和读取

global 开始时间 = 0

procedure 设置忙碌(忙) {
  按钮_保存.Enabled = not 忙
  按钮_读取.Enabled = not 忙
}

when 按钮_保存.Click() {
  if 微数据库1.GetValue("serviceUrl", "") == "" {
    底部提示条1.Show("先在上面填好服务地址并点保存")
  } else if isempty(trim(文本输入框_内容.Text)) {
    底部提示条1.Show("先写一句话")
  } else {
    设置忙碌(true)
    开始时间 = 计时器1.SystemTime()
    标签_结果.Text = "正在保存……"
    网络微数据库1.StoreValue("hello", trim(文本输入框_内容.Text))
  }
}

when 网络微数据库1.ValueStored() {
  设置忙碌(false)
  标签_结果.Text = join("保存成功,用时 ", 计时器1.SystemTime() - 开始时间, " 毫秒。")
}

when 按钮_读取.Click() {
  设置忙碌(true)
  开始时间 = 计时器1.SystemTime()
  标签_结果.Text = "正在读取……"
  网络微数据库1.GetValue("hello")
}

when 网络微数据库1.GotValue(tagFromWebDB, valueFromWebDB) {
  设置忙碌(false)
  if valueFromWebDB == "" {
    标签_结果.Text = "服务器上还没有这条数据,先点「保存到服务器」。"
  } else {
    标签_结果.Text = join("读到:", valueFromWebDB, "\n用时 ", 计时器1.SystemTime() - 开始时间, " 毫秒")
  }
}

这一段是整个专题最重要的概念——异步:

  1. 点「保存」时,保存值 只是把请求发出去,马上就执行完了,这时服务器还没收到。
  2. 服务器存好后回话,「值存储完毕时」事件才运行。所以「保存成功」要写在事件里,不能写在按钮里紧跟着 保存值。
  3. 读取也一样:获取值 不会返回值,值在「已获得值时」的参数 valueFromWebDB 里。
  4. 服务器上没有这个标签时,拿到的是空文本。

请求没回来之前把两个按钮变灰,防止连点发出一串请求。

中途验证:写一句话点保存,标签显示「保存成功,用时 xx 毫秒」;电脑浏览器刷新服务地址页面,表格里多了 hello 这一行。

第四步:连不上时告诉用户原因

when 网络微数据库1.WebServiceError(message) {
  按钮_保存.Enabled = true
  按钮_读取.Enabled = true
  标签_结果.Text = join("连不上服务器:", message, "\n检查:服务端窗口还开着吗?手机和电脑是同一个 WiFi 吗?服务地址抄对了吗?")
}

没有这一块,服务器一出问题,按钮就永远是灰的,用户只会觉得 App 卡死了。下面按当前安卓组件说明常见消息:

消息里有 意思
timed out 网络通信失败的统一提示;连接被拒、服务端未开也可能出现,不能仅凭文字判定真正超时
protocol exception 连上了,但服务器返回错误,多半是口令那一段抄错了(服务端返回 404)

新版鸿蒙组件已按安卓对齐这两类消息。旧版鸿蒙可能返回 HTTP 404 或系统原始网络错误;这时先核对服务地址、接口路径和口令。无论平台是哪一个,排错都应结合实际原因,不能把 timed out 一律当作真正超时。

中途验证:关掉服务端窗口再点读取,标签显示「连不上服务器」和排查提示;重新启动服务端,再点读取,之前保存的那句话还在。

跑起来看看

  • 用两台手机(或一台手机 + 模拟器)装同一个 App、填同一个服务地址:一台保存,另一台读取,读到的是同一句话。这就是「联网」的全部秘密——数据不在手机上,在服务器上。
  • 用时一般是几十毫秒;手机离路由器远、WiFi 拥挤时会变长。

常见问题

现象 原因与办法
一直显示「正在保存……」,按钮是灰的 事件没触发。检查「值存储完毕时」和「发生 Web 服务故障时」两个事件块都在,组件名对得上
提示 timed out 先用手机浏览器打开服务地址;打不开就按服务端教程常见问题的 Q2 排查
提示 protocol exception 口令抄错了,以服务端文件夹里 secret.txt 的内容为准
读到的中文是乱码 服务地址还是默认的 MIT 服务器,改成自己的服务端
另一台手机读不到 两台手机的服务地址不一样,或者保存的标签不一样(本课固定是 hello)
关掉 App 后服务地址没了 保存地址时没点「保存」按钮,或按钮里没有「微数据库 保存值」

动手改一改

  1. 把标签 hello 改成用户输入的内容,做成「按标签存取」的小工具。
  2. 保存时把当前时间一起存进去(用字典:{"text": …, "time": …}),读取时显示「xx 点 xx 分保存的」。

下一课

第 2 课 班级留言板:一个标签里存很多条留言,大家都能往里加——这时会碰到第一个真正的联网问题:怎么不把别人刚发的留言覆盖掉。

用到的组件

网络微数据库 · 微数据库 · 计时器 · 底部提示条 · 文本输入框 · 按钮

验证范围

最终 .aia 已通过正式编辑器载入与保存重开(0 错误)、后台导入和 Android APK 编译;连真实服务端执行积木检查 14 项(存取、中文与数字原样、另一台手机读取、空标签、口令错误、服务端关掉再重启等),见验证记录。真机运行与 AI 伴侣联调尚未测试。

文档反馈