做 Android IDE 终端时踩过的 UI 坑:键盘、会话、侧滑栏和文件管理
PyStudio 这类 Android IDE 最容易被低估的,不是“能不能跑一条命令”,而是终端、编辑器、键盘和文件管理几条线能不能互相不添乱。键盘弹起时符号栏错位、侧滑栏误触、运行脚本后回不到编辑器、文件列表钻进空目录,这些问题单独看都小,叠在一起就会让 App 像临时 demo。 这篇更像一次 UI 复盘:哪些状态应该交给终端运行时,哪些交给页面,哪些交互要在手机上收紧。读完至少能得到一条判断线:移动端 IDE 的体验,不靠一个惊艳控件,而靠很多边界都稳定。 这张图先把终端会话、编辑器、文件系统和输入法放到同一个工作台上,后面的几个坑基本都来自这些边界被写乱。 终端不能只是一个 View一开始终端逻辑很容易写成: 1234TerminalPage -> ViewModel -> create TerminalSession -> attach TerminalView 这样能跑,但生命周期很脆。Activity 重建、页面切换、安装脚本运行、Python 调试会话、Alpine/proot 会话都混在 ViewModel 里,最后...
把 Android IDE 的运行时依赖做成清单:PyStudio 包管理踩坑记录
PyStudio 不可能把 Python、pip、debug 工具、tree-sitter、proot、Alpine rootfs、C/C++ 工具链全塞进 APK。App 本体要轻,运行时能力又要能按需安装和更新,这中间必须有一层清单。 这篇记录我最后采用的模型:runtime-packages.json 负责发现能力,Packages.xz 负责包级依赖,planner 负责算安装计划,installer 把计划变成用户能看见的终端脚本。 清单不是另一个 apt。它负责告诉 App 去哪里找能力,真正的依赖关系仍然交给包索引。 为什么不用一堆写死链接最早的想法很简单:App 里放一个按钮,点了就下载某个包。问题也很快出现: 不同 ABI 的包不同:aarch64、arm、i686、x86_64; 有些能力不是一个文件,而是一组 .deb 依赖; 同一个 profile 会不断重建,比如 proot 从 r40 到 r100; bootstrap 也需要灵活更新,不能永远内置在 APK; 下载源会变:GitHub、Gitee、ModelScope、Cloud...
Android App 里跑 proot:一次 fork 被 seccomp 拦截后的排查复盘
这次问题最容易误判:同一份 Alpine rootfs、同一个 proot 二进制,在 adb run-as 里能跑,到了 App 真实终端里却报 /bin/sh: can't fork: Function not implemented。如果只看控制实验,很容易去重做 rootfs、下载脚本或 UI。 真正的分界线在 Android App 进程域。adb run-as 成功只能说明文件和参数大体没坏,不能证明 zygote/seccomp/SELinux 这条真实路径也通。这篇按排查顺序写,重点是如何把验收线放回 App 域里。 左边是容易误导人的控制组,右边才是 App 内终端真正会走到的路径。 一开始误判的地方最容易误判的是这条控制实验: 1234567adb shell run-as com.vchangxiao.pystudio ` /data/data/com.vchangxiao.pystudio/files/usr/bin/proot ` -r /data/data/com.vchangxiao.pystudio/file...
把膝关节超声 AI 部署到 Hugging Face Spaces:Gradio 6 项目的踩坑复盘
这篇是一次完整的 Hugging Face Spaces 部署复盘:一个本地 Gradio 应用,最后变成可公开访问、可通过 API 调用、可生成 Markdown/PDF 报告的 Space。项目本身用于膝关节超声图像里的髌腱/髌软骨识别、厚度测量和健康风险参考;它不是医疗诊断系统,定位是 AI 辅助健康参考。 我把坑按部署链路重新整理了一遍:模型文件怎么上传、页面和 API 如何共用同一条推理链、PDF 中文字体怎么兜底、深色模式为什么会翻车,以及远端 API 应该怎么验收。 项目地址: Hugging Face Space: vg188/knee-Ultrasound-agent 直接访问地址: https://vg188-knee-ultrasound-agent.hf.space 这张图把图像上传、模型推理和报告输出放在同一个工作台里。后面的每个坑,基本都落在其中一段。 最终形态最后部署出来的 Space 主要包含三层能力。 第一层是网页评估界面:用户上传膝关节超声图像,补充年龄、性别、BMI、活动水平、生活习惯、运动习惯、鞋履...
Cloudflare Pages + 华为云 DNS 分线路加速:原理和操作步骤
这篇记录一条已经实测跑通的加速路线:网站继续放在 Cloudflare Pages,父域 DNS 仍由 Cloudflare 管理,只把需要加速的子域名通过 NS 委派交给华为云 DNS,再让华为云 DNS 按线路返回不同的 CNAME。 重点不是“把 Cloudflare Pages 换掉”,而是把站点托管、父域管理、子域调度拆开。这样 Pages 自定义域名仍保持 active,大陆访问可以走优选 CNAME,其他地区还有默认线路兜底。 加速前后对比: 这张图是整篇的核心:Cloudflare 管父域和 Pages 归属,华为云 DNS 只管被委派的 speed.vg188.cyou。 技术路线和原理 不要把 Cloudflare DNS 里的 Pages CNAME 直接替换成优选域名;更稳的是先绑定 Pages,再把子域解析委派出去。本次测试用到的实际项目: 1234567Cloudflare Pages 项目名: av7980Pages 默认域名: av7980.pages.devPages 默认访问: https://av7980.pages.dev加速...