Skip to content

ApkStart v0.4.3

Choose a tag to compare

@github-actions github-actions released this 15 Nov 03:13

ApkStart v0.4.3

一句话:把旋转/全屏从"改运行时分辨率"彻底改成"换物理面板尺寸",横屏终于正立且铺满;同时修掉整机卡顿,并新增游戏 / 低延迟模式(为 FPS 准备)。

一、旋转 / 全屏:现在真的正立且铺满

之前为什么一直不对

模拟器的画面来自一块「物理 LCD 面板」,Qt 会按面板尺寸开窗口、把画面贴在左上角。之前三种做法都是错路,而每一条都对应你截图里的一个现象:

做法 结果
运行期改 wm size 只改 Android 逻辑分辨率,物理面板仍是竖的 → 画面躺倒 90°、只占左上角一条、点击坐标错位
运行期改 wm density framebuffer 尺寸不变 → 画面不会铺满,最大化后右侧一大片空白
adb emu rotate 只转画面内容,系统里还是竖屏

现在怎么做

旋转 = 改 hw.lcd.width/height 并重启模拟器(约 30–60 秒,只在点旋转时发生一次):

  • 竖屏面板 720x1280,横屏面板 1280x720;
  • 同时按方向锁 wm user-rotation(横屏锁 1、竖屏锁 0)+ 关闭传感器自动旋转 —— 面板变横但 rotation 仍是 0 时,画面就会躺倒;
  • 方向持久化在设置里,重开 ApkStart 仍按这个方向开机;
  • 全屏按钮 = 切横屏:窗口最大化 + 物理面板转横,不再是把竖画面拉大。

顺带修掉的两个真 bug

  1. -no-skin 覆盖 -skin:启动参数同时带了这两个,-no-skin 让面板尺寸退回 config.ini 旧值 —— 这就是"设置里切了横屏、实际还是竖屏"的直接原因。已移除 -no-skin。
  2. 最大化后不铺满:Electron 最大化时宿主窗口变成 1936×1048,但内部的 Chrome 渲染层仍停在旧尺寸(实测 532×984),而模拟器窗口挂在渲染层之下、会被父窗口裁剪。现在 Fit 会先把渲染层拉满宿主客户区,再按该尺寸贴模拟器;窗口扫描每轮也会自愈一次,即使 JS 的 resize 事件丢了也能恢复。

二、卡顿:整机变卡的三处开销

  1. 窗口扫描频率:原来开机前 90 秒每 120ms 就全桌面枚举一次窗口(一轮里 4 次 EnumWindows + 进程路径查询),持续吃 CPU。现在改为前 10 秒 250ms、之后 1500ms;游戏模式进一步降到 3000ms。
  2. 模拟器优先级:默认 balanced 会把 qemu 摁到 BelowNormal,关掉应用后甚至降到 Idle(最低)—— Android 因此严重掉帧。现在关闭应用后不再无条件降到 Idle。
  3. 全局鼠标钩子:WH_MOUSE_LL 会对桌面每个鼠标事件同步回调,明显增加指针延迟。游戏模式下完全不装。

三、新增:游戏 / 低延迟模式

设置 → 性能与资源 → 虚拟机优先级 → 「游戏 / 低延迟」:

  • 模拟器进程提到 High 优先级,安卓渲染和输入优先拿到 CPU;
  • 关闭全局鼠标钩子,指针走原生输入路径;
  • 窗口扫描降到 3000ms,减少宿主侧打扰;
  • 「流畅」资源策略现在也直接进这个模式(视频/游戏优先)。

代价是整机其他程序会慢一些,所以默认仍是「均衡」。

四、顺带加固

  • settings.json 现在能容忍 UTF-8 BOM。之前文件一旦带 BOM,JSON.parse 直接抛错,整个配置静默回落到默认值 —— 用户会看到"设置全丢了"却查不出原因(我自己测试时就踩到了)。
  • 新增回归测试:横屏必须靠 lcdFor({landscape})、不得再用运行期 wm size;窗口模式必须用 -skin 且不得带 -no-skin;游戏模式必须是 High 且不装全局钩子。

五、实测

  • npm test:117 项全部通过(8 + 25 + 84)。
  • 横屏实测:wm size = Physical size: 1280x720、user_rotation=1,guest 画面正立、布局正确、无黑边;最大化后宿主客户区 1920×1032、渲染层同步拉满。
  • 竖屏实测:720x1280、rotation=0,画面正立铺满。

六、升级方式

  • 便携版:解压覆盖,数据目录(默认 %APPDATA%\apkstart)保持不变。
  • 安装版:直接安装覆盖。