6.7.0 - Alpha11 - 修复输入事件观察器 InputEventObserver 可能导致应用启动时明显卡顿的问题

This commit is contained in:
SuperMonster003
2025-11-19 13:52:19 +08:00
parent 111bec7312
commit d51481333e
4 changed files with 41 additions and 5 deletions

View File

@@ -48,6 +48,7 @@
"运行项目时 project.json 配置参数无法正常解析的问题",
"修复项目配置文件中构建版本号或构建时间出现较大数字时可能导致应用崩溃的问题",
"频繁获取或重建 ImageReader 时可能因缓冲区暂无可用帧导致应用崩溃的问题",
"输入事件观察器 InputEventObserver 可能导致应用启动时明显卡顿的问题",
"打包应用无法正常使用 Paddle OCR 与 Rapid OCR 功能的问题",
"版本历史页面部分系统因字体差别导致统计数据显示不完整的问题",
"部分设备无法正常初始化 MLKit Google OCR 的问题 (试修) _[`issue #8`](http://issues.autojs6.com/8#issuecomment-3117061768)_",

View File

@@ -45,10 +45,12 @@ object InputDevices {
val result = ProcessShell.execCommand(cmd, true)
if (result.code == 0) return@run result.result
}
if (WrappedShizuku.isOperational()) {
if (WrappedShizuku.isRunning()) {
runCatching {
val result = WrappedShizuku.execCommand(cmd)
if (result.code == 0) return@run result.result
}
}
return -1
}
val lines = result.lines()

View File

@@ -32,9 +32,18 @@ public class InputEventObserver {
public static InputEventObserver getGlobal(Context context) {
if (sGlobal == null) {
// noinspection UnnecessaryLocalVariable
InputEventObserver observer = new InputEventObserver(context);
sGlobal = observer;
observer.observe();
// @Hint by SuperMonster003 on Nov 16, 2025.
// ! If calling observe() here, it will synchronously create a Shell
// ! and block the main thread during app startup.
// ! Changed to lazy initialization, asynchronously call ensureObservedAsync()
// ! at appropriate time (like in GlobalKeyObserver constructor).
// ! zh-CN:
// ! 如果在此处调用 observe(), 会在应用启动时同步创建 Shell 并阻塞主线程.
// ! 修改为懒初始化, 在适当时机 (如 GlobalKeyObserver 构造函数中) 异步调用 ensureObservedAsync().
// # observer.observe();
}
return sGlobal;
}
@@ -109,6 +118,25 @@ public class InputEventObserver {
});
}
// Ensure lazy start observation in background thread
// to avoid blocking the main thread/app startup.
// zh-CN: 确保在后台线程懒启动观察, 避免在主线程/应用启动期阻塞.
public void ensureObservedAsync() {
if (mShell != null) return;
synchronized (this) {
if (mShell != null) return;
new Thread(() -> {
try {
observe();
} catch (Throwable ignored) {
// Do not throw exceptions to main thread to avoid affecting first screen;
// specific errors will be handled at the usage point.
// zh-CN: 启动失败时不抛到主线程, 避免影响首屏; 具体错误在使用处再处理.
}
}, "InputEventObserver-Init").start();
}
}
public void onInputEvent(String eventStr) {
if (!TextUtils.isEmpty(eventStr) && eventStr.startsWith("[")) {
try {

View File

@@ -1,6 +1,7 @@
package org.autojs.autojs.event;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import org.autojs.autojs.AutoJs;
@@ -31,7 +32,11 @@ public class GlobalKeyObserver implements OnKeyListener, ShellKeyObserver.KeyLis
AccessibilityService.Companion.getStickOnKeyObserver().addListener(this);
ShellKeyObserver observer = new ShellKeyObserver();
observer.setKeyListener(this);
InputEventObserver.getGlobal(applicationContext).addListener(observer);
InputEventObserver io = InputEventObserver.getGlobal(applicationContext);
io.addListener(observer);
// Starts getevent asynchronously with a delay to avoid blocking the first frame.
// zh-CN: 将底层 getevent 的启动改为异步, 并稍作延迟, 避免阻塞首帧.
new Handler(applicationContext.getMainLooper()).postDelayed(io::ensureObservedAsync, 240);
}
public static void initIfNeeded(Context applicationContext) {