processSpeed 进程加速
约 1271 字大约 4 分钟
processSpeed 进程加速
processSpeed 用来调当前 Hook 到的目标进程 的原生时间倍率。
它不是给 JS 自己的 setTimeout(...) 加速,也不是给整个手机系统调倍速,而是针对当前宿主进程里被接管的 native 计时链路做倍率控制。
你先记住 6 条:
- 模块名是
processSpeed,别名是$processSpeed。 - 它只在 Hook 宿主进程 里可用;无宿主运行里不能用。
- 它不吃包名、不吃 PID,不是
processSpeed.setRate("com.xxx", 2)这种设计。 setRate(rate)传进去的倍率会按0.25为步长归一化。reset()只是把倍率恢复到1x,不会帮你清别的脚本逻辑。- 它影响的是目标进程里的 native 时间缩放,不影响 JS 定时器、Binder、网络超时和系统时钟。
processSpeed.getRate()
读取当前进程生效中的倍率。
返回值
number- 常见值例如:
1、1.25、2.5、10
例子
log("current rate = " + processSpeed.getRate() + "x");
如果当前不支持原生加速,这里不会抛错,而是会从当前状态里折算出默认倍率;更稳妥的习惯还是先配合 processSpeed.isSupported() 或 processSpeed.getState() 一起看。
processSpeed.setRate(rate)
设置当前 Hook 宿主进程的加速倍率。
参数
| 参数 | 类型 | 必填 | 可填值 | 说明 |
|---|---|---|---|---|
rate | number | 是 | 0.25 ~ 100 之间的有限数字 | 目标倍率 |
取值规则
当前源码里会做这些检查:
- 必须是
Number - 必须是有限值,
NaN/Infinity都不行 - 范围必须在
0.25 ~ 100 - 最终按
0.25为步长落地
返回值
number- 返回的是实际生效后的倍率
这点很重要。
比如你传 2.37,最后不一定还是 2.37,而是会返回归一化后的实际值。
例子
const actualRate = processSpeed.setRate(2.5);
log("native rate = " + actualRate + "x");
const actualRate = processSpeed.setRate(3.12);
log("rounded rate = " + actualRate + "x");
动态切换例子
//@process=main
processSpeed.setRate(1.5);
setTimeout(function () {
processSpeed.setRate(4);
}, 3000);
setTimeout(function () {
processSpeed.reset();
}, 8000);
什么时候会抛错
下面这些情况都会直接报错:
- 不在 Hook 宿主进程里调用
- 传的不是数字
- 传了
NaN/Infinity - 传入倍率超出
0.25 ~ 100 - native 加速桥初始化失败
processSpeed.reset()
把当前进程倍率恢复到 1x。
返回值
number- 正常情况下返回
1
例子
processSpeed.setRate(8);
log("after boost = " + processSpeed.getRate());
processSpeed.reset();
log("after reset = " + processSpeed.getRate());
一个很容易误解的点
reset() 只负责把当前进程倍率改回 1x。
它不是“撤销所有脚本副作用”,也不是“脚本结束自动调用”。
当前实现里:
- 脚本热重载后,下一个
setRate(...)会覆盖前一次倍率 - 脚本结束时,不会强制自动
reset()
所以如果你明确要求恢复正常速度,最好自己显式调用一次:
try {
processSpeed.setRate(5);
// 你的调试逻辑
} finally {
processSpeed.reset();
}
processSpeed.getState()
读取完整状态,比单看 getRate() 更适合排错。
返回值结构
const state = processSpeed.getState();
// {
// supported: true,
// active: true,
// rate: 2.5,
// minRate: 0.25,
// maxRate: 100,
// step: 0.25,
// packageName: "com.example.game",
// processName: "com.example.game:main",
// error: ""
// }
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
supported | boolean | 当前环境是否支持原生加速 |
active | boolean | 当前是否处于非 1x 状态 |
rate | number | 当前实际倍率 |
minRate | number | 最小允许倍率,当前固定为 0.25 |
maxRate | number | 最大允许倍率,当前固定为 100 |
step | number | 步长,当前固定为 0.25 |
packageName | string | 当前目标包名 |
processName | string | 当前目标进程名 |
error | string | 不支持或失败时的诊断信息 |
什么时候优先看它
这几种场景优先看 getState():
- 你不确定当前到底支不支持加速
- 你调用
setRate(...)失败了,想看原因 - 你怀疑脚本跑在了错误进程里
- 你想把当前倍率、包名、进程名一起打日志
排错例子
const state = processSpeed.getState();
log(JSON.stringify(state, null, 2));
if (!state.supported) {
throw new Error("当前环境不支持 processSpeed: " + state.error);
}
processSpeed.isSupported()
快速判断当前环境能不能用这套能力。
返回值
boolean
例子
if (!processSpeed.isSupported()) {
log("processSpeed unavailable");
} else {
processSpeed.setRate(2);
}
processSpeed.MIN_RATE
最小倍率常量。
当前值
0.25
processSpeed.MAX_RATE
最大倍率常量。
当前值
100
processSpeed.STEP
倍率步长常量。
当前值
0.25
processSpeed.NORMAL_RATE
正常倍率常量。
当前值
1
processSpeed.api
指回模块对象本身,主要是为了和其他 ScriptX 模块的风格保持一致。
例子
log(processSpeed.api === processSpeed); // true
典型完整例子
例子 1:游戏内临时加速
//@process=main
const state = processSpeed.getState();
if (!state.supported) {
throw new Error(state.error || "processSpeed unavailable");
}
log("before = " + state.rate + "x");
try {
processSpeed.setRate(3);
log("after = " + processSpeed.getRate() + "x");
sleep(5000);
} finally {
processSpeed.reset();
}
例子 2:按进程区分倍率
if (lpparam.processName === lpparam.packageName) {
processSpeed.setRate(2);
} else {
log("非主进程,不改倍率: " + lpparam.processName);
}
影响范围一定要分清
当前实现明确说了,这套能力主要影响:
- 目标 APK 自己的 native 库
- 已识别的游戏引擎时间链路
它不会去改下面这些东西:
- JS 的
setTimeout(...)/setInterval(...) sleep(...)- Binder 调度
- 网络超时
- 系统墙钟时间
- 其他无关系统进程
所以如果你看到:
- 画面逻辑变快了
- 但脚本里的定时器节奏没变
这正是当前实现的正常表现,不是没生效。
