Skip to content

feat(android): 安卓手机本地运行版完整可运行(APK 构建闭环 + WASM sharp + 横竖屏布局) - #122

Open
Fly143 wants to merge 27 commits into
ExplosiveCoderflome:mainfrom
Fly143:main
Open

feat(android): 安卓手机本地运行版完整可运行(APK 构建闭环 + WASM sharp + 横竖屏布局)#122
Fly143 wants to merge 27 commits into
ExplosiveCoderflome:mainfrom
Fly143:main

Conversation

@Fly143

@Fly143 Fly143 commented Aug 4, 2026

Copy link
Copy Markdown

概述

本次 PR 为项目新增安卓手机本地运行版:从仓库 clone 后即可构建出可安装的 APK,创作工作台在手机本地运行(内置 Node 运行时 + SQLite + WASM sharp),界面与桌面端一致。模型调用仍需联网(用户自配本地或远程模型服务)。

⚠️ 说明:本 PR 全部代码由 AI 辅助完成(Hermes Agent / Claude Code 工作流),已通过真机验证。

主要内容

1. 安卓工程(android-app/,170 文件)

  • 完整 Android 工程:MainActivity(WebView 容器 + Node 服务桥接)、NodeService(内嵌 Node 运行时启动/停止)
  • 强制桌面布局注入 + 横竖屏按方向切换布局(竖屏手机布局、横屏桌面布局)
  • WebView 下载导出到公共 Downloads/AINovel(MediaStore 免权限)
  • 构建资产全部入库:node 运行库 / node-project.zip(依赖)/ 数据库迁移——fork 后两步即可构建

2. 资产构建脚本(android/)

  • build-android-assets.sh:一键生成 bundle.cjs + www.zip(node-project.zip 为固定资产)
  • sharp-android/:bionic sharp 编译工具链(NDK 交叉编译,历史方案)
  • fetch-termux-libs*.py:Termux 库获取工具

3. 漫画工作台(server/src 迁移)

  • 漫画模块数据库迁移补全(ComicCharacter.gender / ComicScene / ComicCharacterAsset / ComicPanel.sceneRef)
  • 漫画渲染:WASM sharp(@img/sharp-wasm32 + @emnapi/runtime),免原生库依赖,真机验证渲染正常

4. 前端适配(client/src)

  • 横竖屏方向布局切换(useIsMobileViewport 按 orientation 判断)
  • 解锁短剧工作台桌面端入口

验证

  • 真机(小米)验证:服务器启动(SERVER_READY)、API 全 200、漫画渲染 PNG 生成、旋转切横屏
  • fork 模拟验证:clone → pnpm install → 构建脚本 → gradle assembleDebug → 166MB 可用 APK
  • 已发布 v0.4.7.2(162.6MB APK)

注意事项

  • 构建需要 Android SDK(compileSdk 35)+ JDK 17,README 已写明
  • 模型调用需联网(App 本身本地运行,不含模型)
  • 代码由 AI 生成,建议维护者 review 后合入

Fly143 added 20 commits August 2, 2026 01:40
- 新增 android-app 安卓工程:内嵌 Termux node 运行时 + better-sqlite3,
  WebView 加载本地前端,后端 API 在 127.0.0.1:3000 本地运行
- 手机端导航归类与命名对齐电脑端(资产/系统/运行记录等)
- 沉浸式全屏(状态栏不遮挡)、旋转不重启、启动 Loading 提示
- App 图标与电脑端一致(web-app-icon 同源)
- server 增加 AI_NOVEL_DISABLE_COMIC 开关(漫画工坊依赖 sharp)
- 修复 typescript/zod 包缺失 .d.ts 导致 tsc 无法运行
- 新增 android/run-on-android.sh 手机端启动脚本
- 实测 @img/sharp-wasm32(纯 WASM 回退)在内嵌 JNI node 运行时加载即死锁
  (emscripten pthreads 工作线程阻塞事件循环),无法用于安卓
- 原生 sharp-linux-arm64 需 NDK 交叉编译 libvips(glib/cairo/pango 等),属独立专项
- 漫画工作台在安卓端暂保持禁用,其余创作功能均正常
- 更新 android/run-on-android.sh 说明,app.ts 注释补全根因
- 用 NDK r26d 交叉编译 bionic sharp.node(AArch64),链接 Termux 的 bionic libvips 8.18.4
- jniLibs/arm64-v8a 新增 42 个 libvips 依赖闭包 .so(glib/gio/cairo/pango/rsvg/OpenEXR 等)
- 移除 NodeService 与 run-on-android.sh 的 AI_NOVEL_DISABLE_COMIC 禁用,app.ts 直接挂载 /api/comic
- node-project.zip 内 @img/sharp-wasm32/sharp.node 替换为原生 bionic 版本(zip 本身被 .gitignore 忽略)
- 新增 android/sharp-android/ 可复现脚本(compile-sharp.sh / pkg-config.py / assemble-libs.py / inject-sharp.sh / README)
- 更新 release-notes.md 与 README 最新更新:漫画工作台已在手机端启用
- android/build-android-assets.sh:一键生成被 gitignore 的安卓资产
  (bundle.cjs 完整打包 express 进包内、www.zip/node-project.zip 无目录前缀、
  注入 bionic sharp.node),fork 后跑脚本即可构建完整 APK
- README:安卓端构建(fork 后首次构建必读)
- inject-sharp.sh:MSYS 下路径转 Windows 原生(cygpath)
- sharp-android README:更新构建流程说明
20260402 character_gender_fields 迁移早于 20260612 add_comic_module
建表,漏给 ComicCharacter 加 gender 列,导致安卓端(迁移建库)查
漫画项目详情报 column does not exist。新增迁移对齐 schema.prisma。
- ComicCharacterAsset / ComicScene 两表在 add_comic_module 迁移中漏建,
  迁移建库环境(安卓)查询报 table does not exist
- ComicPanel.sceneRef 列 schema 有定义但无迁移补齐
- 桌面端此前靠 prisma db push 掩盖;此修复让迁移建库= schema 一致
- signingConfigs.release(自签名 keystore,密码 ainovel123,keystore 不入库)
- versionCode 2 / versionName 0.4.7.1
安卓打包实测 pnpm deploy 原生支持 workspace:* 协议,
无需改成 file:../shared(PR 到原仓库前保持依赖约定一致)
- QuickSetupDialog API Key 输入框 onChange 语法错误(event....alue
  -> event.target.value),导致自定义厂商的 Key 无法录入、提交被禁用
- build-android-assets.sh 补前端构建步骤:vite 需 AI_NOVEL_CLIENT_BASE=
  relative(file:// 相对路径)与 VITE_API_BASE_URL=127.0.0.1:3000/api
  (安卓 localhost 解析异常会导致网络连接失败)
移除 assets/nodejs/node_modules 真实目录冗余:
- 该目录仅是 node-project.zip 的打包源,zip 已含全部依赖
- gradle assets exclude 对目录无效,需构建脚本打完 zip 后清理
- build-android-assets.sh 已内置清理逻辑(fork 者受益)
- AndroidManifest: screenOrientation=landscape(App 固定横屏)
- MainActivity: 注入 window.__ANDROID_APP__(前端据此强制桌面布局)
- useIsMobileViewport: App 内永远返回 false(不看宽度,低分辨率手机横屏也不会误入移动布局)
- MobileNovelEditView: 工作区左上角加返回按钮
- AppLayout: AI 创作实况入口移到右下角(避免与创作工具菜单重叠)
- AutoDirectorCreatePage: 移动端返回按钮 + 裸布局(无站点壳)
前端导出(a[download]/blob)在 WebView 默认无响应,新增
DownloadListener:
- blob URL:evaluateJavascript 取回 base64 解码落盘
- 常规 URL:HttpURLConnection 流式下载
- Android 10+ 用 MediaStore 写入 Download/AINovel(免权限),
  用户文件管理器直接可见;生产数据仍留在私有目录
- 移除 bionic sharp.node 注入:原生版依赖 libvips 全家(libstdc++
  ABI 真机不兼容,dlopen 失败);WASM 版(@img/sharp-wasm32 +
  @emnapi/runtime)免原生库,真机验证渲染正常
- node-project.zip 不再重新打包:依赖树含安卓版原生库(better-sqlite3
  ELF),Windows 无法凭空生成;改为固定资产,缺失时提示从 Release 下载
- 新增 fetch-termux-libs*.py / prune-node-project.py(资产维护工具)
- noderuntime/(18 个 node 运行库,48MB)入库:安卓 node 运行时
- node-project.zip(40MB)入库:依赖树固定资产(安卓 ELF better-sqlite3 + WASM sharp)
- migrations.sqlite/(85 个迁移)入库:真机建表必需
- .gitignore 放行上述资产;此前 fork 者 clone 后缺失全部构建源,无法构建
- README/release-notes 更新:fork 后 clone 即可构建 APK(资产入库)
- build-android-assets.sh 增加 shared workspace 包构建(tsc 生成 dist)
- .gitignore 放行 noderuntime/ 和 migrations.sqlite/
- Sidebar 短剧工作台移除 disabled(功能已可用,仅入口被禁)
- useIsMobileViewport 安卓端改为按屏幕方向切换布局:竖屏→移动布局、
  横屏→桌面布局(不用宽度断点,低分辨率横屏不误判)
- AndroidManifest 改 sensorPortrait(默认竖屏、可旋转横屏)
- sensorPortrait 只允许竖屏±180°,旋转无法切横屏;fullSensor 允许横竖屏
- versionName 0.4.7.1 -> 0.4.7.2,versionCode 2 -> 3
@Fly143 Fly143 changed the title feat(android): 安卓离线版完整可运行(APK 构建闭环 + WASM sharp + 横竖屏布局) feat(android): 安卓手机本地运行版完整可运行(APK 构建闭环 + WASM sharp + 横竖屏布局) Aug 4, 2026
Fly143 and others added 7 commits August 4, 2026 09:46
# Conflicts:
#	README.md
#	client/src/components/layout/AppLayout.tsx
#	docs/releases/release-notes.md
- NodeService 解压的是 www.zip 而非 assets/www/ 目录;只同步 www/ 不重打
  www.zip 会导致 APK 打包旧前端(版本号/功能不更新)。build-android-assets.sh
  与 README 增加醒目警告:每次构建 APK 前必须重跑脚本
- MainActivity 增加 LOAD_NO_CACHE + clearCache,避免 WebView 缓存旧前端
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant