夜雨聆风学习资料网

ARTICLE · 1137060

一台手机,出门在外也能开发调试电视 App:AScrcpy + Termux + nl2sh 的移动开发闭环

一台手机,出门在外也能开发调试电视 App:AScrcpy + Termux + nl2sh 的移动开发闭环

一台手机,出门在外也能开发调试电视 App:AScrcpy + Termux + nl2sh 的移动开发闭环

写代码、编译、安装、排查、看界面、按遥控器、做验收。以前这套流程我默认要坐在电脑前完成。现在,我出门在外,手里只要一台 Android 手机,也能把整条链路跑完。

封面图

前几天我写了一篇一部手机开发安卓 App:让写代码和看效果都舒服起来,讲的是我怎么把“手机 + SSH + Agent + AScrcpy”串起来,让一台手机也能完成 Android App 的开发和验收。

文章发出去以后,有网友问了我一个很合理的问题:

“用手机看设备画面,再用手机控制设备,这不是多此一举吗?直接看设备不就好了?”

嗯。

正常情况下,确实有点多此一举。

但如果你看到我的设备,一台“电视”长这样,大概就能理解事情为什么没那么简单了。


先介绍一下我的电视:它除了没有屏幕,其他基本都在

我家里现在有一台很特别的电视。

严格来说,它已经很难再叫“电视”了。

因为它——没有屏幕。

事情的起因很朴实。

去年,小朋友玩玩具时一个“精准制导”,直接把电视屏幕砸坏了。

而且不是轻微裂一下,是内外屏一起报废。

屏幕修起来不划算,后来干脆把所有的零件拆下来,屏幕和外壳拿去废品站处理掉了(卖得5块钱巨款)。

于是最后剩下来的,就是:

  • • 主板
  • • 电源板
  • • 喇叭
  • • Wi-Fi / 蓝牙模块
  • • 远场拾音模块
  • • 遥控接收相关硬件
  • • 各种线材
  • • 原装底座
  • • 以及一具已经失去屏幕的电视“躯体”

正常家庭看到这里,结论应该是:

扔了吧。

但程序员看到这里,想法可能会稍微不一样:

“主板不是还能跑吗?”

于是,它就活了下来。

而且不仅活了下来,还重新被我组装成了一台——

没有显示屏,但依然能正常启动 Android TV 系统的开发设备。

用一块木板做支撑,重新组装起来,作为没有屏幕的大号智能音箱使用。抛开美观性不说,原有的喇叭音质还是挺不错的,四麦远场拾音模块也比很多智能音箱效果要好不少,我特意留下的WiFi天线也很好的发挥作用,甚至没了电视壳,信号接收效果更好了。


为什么我要留着一台“看不见画面”的电视?

因为我的工作本身就和电视有关。

我目前主要在康佳做电视应用开发,其中一个比较重要的方向是语音助手应用。

所以对我来说,这台电视主板并不是“电子垃圾”。

它更像是一台真实的 Android TV 测试机,而且是跟我日常工作兼容的设备。

虽然没有屏幕,但它依然可以:

  • • 正常开机
  • • 跑真实电视系统
  • • 安装 APK
  • • 跑系统服务
  • • 接收遥控器按键
  • • 测试语音助手
  • • 查看日志
  • • 分析系统状态
  • • 验证应用行为
  • • 复现一些只有真实电视环境才会出现的问题

有些问题,模拟器就是复现不出来。

比如硬件相关能力、厂商系统服务、Audio / HDMI / 蓝牙 / 麦克风、系统权限、遥控器行为,甚至一些具有康佳特色的系统 framework 定制。

这时候,这块“没有屏幕的电视主板”反而非常有价值。

问题只有一个:

它没有屏幕。

以前我的解决方式很传统:

电脑 + scrcpy。

电脑连上电视,通过 ADB 把电视画面投出来。

开发、安装、看效果、操作,一切都很自然。

直到最近这两年,事情开始发生变化。


Vibe Coding 之后,“写代码”已经不再强依赖电脑

以前离开电脑,就基本等于离开开发环境。

现在不太一样了。

有了 Claude Code、Codex 这类终端 Agent 之后,我很多开发工作已经变成:

  1. 1. SSH 到远程开发机;
  2. 2. 进入项目目录;
  3. 3. 把需求告诉 Agent;
  4. 4. Agent 修改代码;
  5. 5. 编译;
  6. 6. 跑测试;
  7. 7. 提交结果。

也就是说,真正需要我亲手“敲代码”的时间正在减少。

更多时候,我做的是:

描述需求 → 看 diff → 判断结果 → 补充信息 → 验收。

这件事其实特别适合手机。

我只需要在 Android 手机上打开Tailcale+Termux,然后:

ssh my-dev-server

接下来不管是进 tmux、跑 Codex,还是进入远程容器继续开发,都没有太大问题。

于是“人在外面临时改代码”这件事,已经从以前的:

“等我回家开电脑。”

变成了:

“给我两分钟,我手机 SSH 上去改一下。”

这部分其实已经很舒服了。

真正一直让我觉得少点什么的是下一步:

代码写完了,电视上的实际效果怎么看?


编译成功,不代表你真的“开发完了”

Agent 很容易告诉你:

BUILD SUCCESSFUL

测试也可能全部是绿色。

但 Android 开发的人都知道,这不等于结束。

尤其是 UI 和交互相关的修改。

你还是得看一眼:

  • • 焦点是不是跑偏了?
  • • 按钮是不是被遮住了?
  • • 电视端 UI 的间距是不是合理?
  • • 字是不是太小?
  • • 遥控器上下左右能不能正常移动焦点?
  • • Back 键行为对不对?
  • • 弹窗出来以后焦点落在哪?
  • • 页面切换有没有闪一下?
  • • Loading 是否挡住内容?
  • • 语音助手浮层是不是盖住了不该盖的东西?

这些问题,日志不会主动告诉你。

单元测试也不一定会告诉你。

最终还是那句话:

得看到画面,还得真的按两下。

以前出门在外,这里就是断点。

我可以用手机 SSH 回去开发。

可以让 Agent 编译。

可以 ADB install。

甚至可以让脚本跑完一大堆测试。

然后……

看不到。

这感觉就像你让厨师把菜做好了,厨房告诉你:

编译成功,单元测试全部通过。

但你问:

“那好吃吗?”

对面沉默了。


AScrcpy 补上的,正是最后这一块

这也是我最近开发 AScrcpy                                                                                                                                                                                                                                                                                                                             的一个重要原因。

AScrcpy 可以简单理解成:

运行在 Android 手机上的 scrcpy / ADB 控制端。

以前是:

电脑  ↓scrcpy  ↓Android 设备

现在变成:

Android 手机  ↓AScrcpy  ↓Android 设备 / 电视 / 模拟器

于是我那台没有屏幕的电视,就重新“长出屏幕”了。

只不过这个屏幕,不再挂在电视机壳上。

而是在我手里的手机上。


更重要的是:这不是“看一眼”,而是真正可以操作

单纯看到画面,其实还不够。

电视应用和普通手机应用不同。

很多交互依赖:

  • • 上
  • • 下
  • • 左
  • • 右
  • • OK
  • • Back
  • • Home
  • • Menu
  • • 音量
  • • 电源

所以 AScrcpy 里我专门做了适合电视使用的遥控器操作界面。

这样一来,我在外面打开手机,不仅能看到电视画面,还可以直接:

  • • 移动焦点
  • • 点击确认
  • • 返回
  • • Home
  • • 调音量
  • • 操作菜单
  • • 检查页面跳转
  • • 验证 TV 端焦点行为

那位问我:

“为什么不直接看电视屏幕?”

的网友,如果看到我这台电视,大概就知道答案了。

因为它真的没有屏幕。

而现在,AScrcpy 就是它的屏幕。

甚至还是一个我能揣进口袋、带出门的屏幕。


但只有 AScrcpy 还不够,我还需要 nl2sh

如果说 AScrcpy 解决的是:

“让我看到设备,并操作设备。”

那么 nl2sh                                                                                                                                                                                                                                                                                                                             解决的是另一件事:

“让我直接在 Android 设备内部做分析和操作。”

nl2sh 是我一直在做的另一个项目。

它运行在 Android 原生 shell 环境中,可以让你直接用自然语言驱动设备里的工具。

比如以前遇到电视问题,我可能要敲:

dumpsys activitydumpsys audiodumpsys media.audio_flingerlogcatps -Agetproppm list packagesam start ...

命令不复杂。

问题是——很多。

而且不同问题对应不同命令组合。

现在我更习惯直接对 nl2sh 说:

看一下当前前台应用和 Activity。

或者:

分析为什么语音助手拉起后没有拿到焦点。

再或者:

帮我看一下当前 audio focus、音频输出设备和相关日志。

nl2sh 自己去组织工具、拿信息、继续分析。

所以它在我的这套移动开发工作流里,扮演的是:

设备端 Agent / 现场工程师。


于是,Termux + AScrcpy + nl2sh,刚好形成三个分工

这三个工具放在一起以后,我发现它们的角色非常清晰。

Termux:负责“远程开发”

Termux 是手机上的入口。

我通过它:

  • • SSH 回家
  • • 进入开发服务器
  • • 打开 tmux
  • • 运行 Codex / Claude Code 等 Agent
  • • 拉代码
  • • 改代码
  • • 编译
  • • 安装
  • • 查看 Git diff
  • • 提交和推送

手机屏幕虽小,但在 Vibe Coding 模式下,我并不需要长期盯着几十个代码文件来回跳。

大量工作交给 Agent 后,终端反而变成了一个非常合适的控制入口。

AScrcpy:负责“看效果 + 操作”

代码改完以后,我切到 AScrcpy。

这时候它负责:

  • • 显示电视实时画面
  • • 操作遥控器
  • • 验证页面
  • • 检查焦点
  • • 看弹窗
  • • 看动画
  • • 看布局
  • • 测试实际交互

换句话说:

Termux 负责告诉设备“改成什么样”,AScrcpy 负责让我确认“现在到底长什么样”。

nl2sh:负责“深入设备内部排查”

如果发现问题不是简单的 UI 问题,我再进入 nl2sh。

比如:

这个页面为什么没起来?

为什么按 Home 后服务没退出?

为什么语音助手有 UI,但没有声音?

当前到底是谁拿着 Audio Focus?

这个进程是不是被系统杀了?

看一下最近有没有 ANR。

传统方式是:

想命令 → 查命令 → 敲命令 → 看输出 → 再想下一条命令。

nl2sh 的方式更像:

直接描述问题。

它自己去调用 Android/Linux 工具获取信息,再继续分析。

这件事在手机上尤其重要。

因为在电脑上敲十几条 shell 命令不算什么。

但在手机软键盘上反复输入一长串:

dumpsys ...

很快就会开始怀疑人生。


我现在出门在外,实际会怎么开发?

举个最近最真实的流程。

我人在外面,突然想到一个电视应用要改的地方。

第一步:手机打开 Termux

SSH 回家:

ssh home

进入已经跑着的 tmux:

tmux attach

里面可能已经有 Codex 在项目目录里等着了。

我直接告诉它:

把这个页面的返回逻辑调整一下,顺便检查从语音助手进入时的焦点恢复。完成后编译、安装到测试电视。

然后等它干活。

第二步:Agent 修改、编译、安装

这时手机实际上只是一个“驾驶舱”。

真正干重活的是家里的开发环境。

Gradle、Android SDK、代码仓库、构建缓存,都留在远端。

等 Agent 告诉我:

BUILD SUCCESSFUL

并且 APK 已经安装到设备。

以前到这里,我如果不在电脑前,基本就只能“相信它”。

现在不用。

第三步:切到 AScrcpy

打开电视连接。

几秒钟后,那块远在家里的电视主板画面,就出现在我手机上。

我开始:

  • • 按方向键
  • • 切页面
  • • 看焦点
  • • 按返回
  • • 打开语音助手
  • • 看浮层
  • • 看页面有没有跳错
  • • 看动画顺不顺

如果发现:

焦点还是落错位置。

我直接截图,或者记住现象。

第四步:切回 Termux,继续让 Agent 改

我告诉 Agent:

现在从语音助手退出后,焦点落到了顶部 Tab,不是原来的卡片。按刚才这个现象继续查。

Agent 接着分析、修改、编译、安装。

然后我再切回 AScrcpy。

如此循环。

第五步:复杂问题交给 nl2sh

如果现象不像纯 UI 问题,比如:

页面看起来正常,但语音唤醒之后没有声音。

我就让 nl2sh 去设备里检查:

分析一下当前音频输出、Audio Focus 和语音助手进程状态。

这时候它可以从 Android 系统内部找线索。

最后我把排查结果再反馈给远端开发 Agent。


这时候,一台手机真的把开发闭环接起来了

整个流程可以压缩成这样:

          一台 Android 手机                 │        ┌────────┴────────┐        │                 │     Termux            AScrcpy        │                 │       SSH              ADB/scrcpy        │                 │   远程开发环境         测试电视        │                 │    编译 / 安装       画面 / 遥控        │                 │        └───────┬─────────┘                │              nl2sh                │        Android 设备内部分析

更口语一点:

Termux:     改AScrcpy:    看nl2sh:      查Agent:      干活我:         提需求 + 验收

这基本就是我现在最舒服的状态。


手机上远程开发,Agent 完成提交与推送

Termux 远程开发截图

上面这张图就是我实际在手机上的开发状态。

没有 IDE。

没有外接显示器。

没有键盘鼠标。

就是一台手机,通过终端连到远程环境,让 Agent 完成开发任务。

你会发现,在这种工作模式下,“手机屏幕小”这个以前非常致命的问题,突然没那么严重了。

因为你不再需要在 6 英寸屏幕上手写 500 行代码。

你需要做的更多是:

  • • 描述任务
  • • 阅读结论
  • • 看关键 diff
  • • 回答问题
  • • 做决策

这是 Vibe Coding 真正改变移动开发可能性的地方。


没有屏幕的电视,也能在手机上直接看、直接按

AScrcpy 控制电视截图

这一张图,是 AScrcpy 控制电视的实际画面。

左边是电视实时画面。

电视遥控器是半透明浮层,可以自由拖动,也可缩小成图标。

看画面和操作设备放到同一个界面里。

所以对于我这台“无屏电视”来说,这不是锦上添花。

这是刚需。


这套方案让我最喜欢的,不是“手机能写代码”

“一台手机写代码”这个说法听起来很酷,但我现在反而觉得,这不是重点。

真正有意思的是:

手机开始变成一个完整的远程开发控制台。

计算可以在别处。

代码可以在服务器。

Android SDK 可以在服务器。

构建缓存可以在服务器。

测试设备可以放在家里。

Agent 可以长期运行。

而我手里的手机,只负责:

  • • 下指令
  • • 接收结果
  • • 看效果
  • • 做判断
  • • 继续下一轮

这和过去“把完整 IDE 硬塞进手机里”的思路完全不一样。

以前我们想象手机开发,大概是:

手机上装一个小号 Android Studio。

但我现在越来越觉得,未来更合理的形态可能是:

手机不用变成电脑。手机只需要成为远程 Agent、设备和算力的统一控制台。


手机开发的核心,不是把 PC 搬到手机里

这一点其实很重要。

如果让我在手机屏幕上:

  • • 写大量 Kotlin
  • • 手工改 XML
  • • 查几十个文件
  • • 对照 Logcat
  • • 开十几个窗口

那我肯定还是选电脑。

但有了 Agent 以后,人的工作方式变了。

以前:

人 → 编辑器 → 代码

现在越来越像:

人 → Agent → 代码 / 工具 / 设备

这个变化会直接降低“小屏幕”的劣势。

你不再需要操作每一个细节。

而是把目标告诉 Agent,再对结果负责。

这时候手机这种:

  • • 随身
  • • 随时在线
  • • 有 SSH
  • • 有 VPN / Tailscale
  • • 能跑 Android App
  • • 能做 ADB 控制
  • • 能看实时视频

的设备,突然非常适合做开发入口。


为什么我还要自己做 AScrcpy 和 nl2sh?

其实答案也很简单。

因为现成工具很难刚好覆盖我的这些奇怪需求。

比如:

“我人在外面,只有一台 Android 手机,想 SSH 回家让 Agent 修改 Android TV 项目,然后直接用同一台手机查看一块没有屏幕的真实电视主板画面,并用虚拟遥控器验收,如果有问题,再让运行在 Android shell 里的 Agent 帮我查系统状态。”

把这段话说给正常人听,对方大概率会沉默几秒。

但对我来说,这就是实际工作场景。

所以我干脆自己把缺的工具补上。

AScrcpy

项目地址:

https://github.com/Ernest-su/ascrcpy

它解决的是:

Android 手机如何成为另一台 Android 设备的显示器和控制器。

nl2sh

项目地址:

https://github.com/nl2sh/nl2sh

它解决的是:

如何让 Agent 真正进入 Android shell 环境,调用系统工具完成分析和操作。

这两个项目加上 Termux,正好把我自己的工作流拼完整了。


现在回头看,那台被砸坏的电视反而更适合我了

这件事其实挺有意思。

一开始屏幕被砸坏的时候,我当然觉得:

完了,电视报废。

结果兜兜转转,它现在反而变成了我很喜欢的一台开发设备。

没有屏幕以后:

  • • 占地方更小了
  • • 搬起来轻了
  • • 放工作台更方便
  • • 反正画面可以通过 AScrcpy 看
  • • 真实电视系统和硬件环境还在

某种意义上,它从一台电视进化成了:

一块超大号 Android 开发板。

唯一的问题是,当别人第一次看到它时,我得解释半天:

“你别看它没有屏幕,它真的是电视。”


最后

过去我觉得:

真正的 Android 开发,还是得坐在电脑前。

后来有了远程开发机和终端 Agent,我发现:

写代码这件事,可以离开电脑。

再后来做了 AScrcpy,我发现:

看效果、操作设备,也可以离开电脑。

加上 nl2sh 之后:

连设备内部的分析排查,也开始能自然地塞进一台手机。

于是现在,我出门在外只带一台 Android 手机,也能完成:

需求 → 修改 → 编译 → 安装 → 查看 → 操作 → 排查 → 验收 → 再修改

当然,我不会因此把电脑扔掉。

真正需要长时间阅读代码、做复杂架构设计、处理大量文件时,大屏幕和实体键盘依然舒服得多。

但对于:

  • • 临时改一个问题
  • • 看 Agent 进度
  • • Review 一下修改
  • • 远程验证真机
  • • 排查线上设备
  • • 在路上完成一次小迭代

一台手机已经开始变得出乎意料地能打。

而且最有趣的是:

不是手机变成了电脑。

而是 AI Agent、远程算力和设备控制工具,把原本必须集中在电脑上的能力拆开了。

手机只需要把它们重新串起来。

这可能才是我理解中的移动开发新形态。


如果你也经常和 Android、ADB、远程设备、电视应用或者终端 Agent 打交道,可以试试:

  • • AScrcpy:https://github.com/Ernest-su/ascrcpy
  • • nl2sh:https://github.com/nl2sh/nl2sh

如果这两个项目对你有帮助,也欢迎顺手点个 Star。

后面我还会继续折腾 Android 端 Agent、设备控制、远程开发、Vibe Coding 这些方向。

如果你也有一些很“邪门”、但真实存在的开发场景,也欢迎评论区评论或公众号后台私信交流。

说不定你缺的那个工具——

我也正好缺。

相关学习资料