6.7.0 - Alpha14 - 新增 images.loadAsync 方法, 用于异步获取网络图像资源 (issue #327)

This commit is contained in:
SuperMonster003
2026-01-12 22:18:00 +08:00
parent 27e06e5fe7
commit 9e1d3b65cc
5 changed files with 51 additions and 13 deletions

View File

@@ -14,6 +14,7 @@
"app.isDualInstalled 方法, 用于检测双开应用是否已安装 (需要 Shizuku 或 Root 权限) _[`issue #450`](http://issues.autojs6.com/450)_", "app.isDualInstalled 方法, 用于检测双开应用是否已安装 (需要 Shizuku 或 Root 权限) _[`issue #450`](http://issues.autojs6.com/450)_",
"device.getSharedDeviceId 方法, 用于跨应用获取统一共享设备 ID _[`issue #455`](http://issues.autojs6.com/455)_", "device.getSharedDeviceId 方法, 用于跨应用获取统一共享设备 ID _[`issue #455`](http://issues.autojs6.com/455)_",
"device.setPointerLocation 等 Toggleablle 系列方法, 用于设置或获取指针位置系统设置项 _[`issue #381`](http://issues.autojs6.com/381)_", "device.setPointerLocation 等 Toggleablle 系列方法, 用于设置或获取指针位置系统设置项 _[`issue #381`](http://issues.autojs6.com/381)_",
"images.loadAsync 方法, 用于异步获取网络图像资源 _[`issue #327`](http://issues.autojs6.com/327)_",
"ui.getNavigationBarHeight 方法/navigationBarHeight 属性 (getter), 用于获取导航栏高度 _[`issue #456`](http://issues.autojs6.com/456)_", "ui.getNavigationBarHeight 方法/navigationBarHeight 属性 (getter), 用于获取导航栏高度 _[`issue #456`](http://issues.autojs6.com/456)_",
"ui.getVisible(Status/Navigation)BarHeight 方法/visible(Status/Navigation)BarHeight 属性 (getter), 用于快捷获取状态栏或导航栏可见高度 _[`issue #456`](http://issues.autojs6.com/456)_", "ui.getVisible(Status/Navigation)BarHeight 方法/visible(Status/Navigation)BarHeight 属性 (getter), 用于快捷获取状态栏或导航栏可见高度 _[`issue #456`](http://issues.autojs6.com/456)_",
"http 模块请求相关方法获取的 body 对象增加 stream/saveToFile/close 等方法 _[`issue #452`](http://issues.autojs6.com/452)_", "http 模块请求相关方法获取的 body 对象增加 stream/saveToFile/close 等方法 _[`issue #452`](http://issues.autojs6.com/452)_",

View File

@@ -559,15 +559,11 @@ public class Images {
}; };
} }
public ImageWrapper load(String src) { public ImageWrapper load(String src) throws IOException {
try { HttpURLConnection connection = (HttpURLConnection) new URL(src).openConnection();
HttpURLConnection connection = (HttpURLConnection) new URL(src).openConnection(); connection.setDoInput(true);
connection.setDoInput(true); connection.connect();
connection.connect(); return ImageWrapper.ofBitmap(mScriptRuntime, BitmapFactory.decodeStream(connection.getInputStream()));
return ImageWrapper.ofBitmap(mScriptRuntime, BitmapFactory.decodeStream(connection.getInputStream()));
} catch (IOException e) {
return null;
}
} }
public ImageWrapper invert(@NonNull ImageWrapper image) { public ImageWrapper invert(@NonNull ImageWrapper image) {

View File

@@ -51,6 +51,7 @@ import org.autojs.autojs.util.RhinoUtils.coerceIntNumber
import org.autojs.autojs.util.RhinoUtils.coerceNumber import org.autojs.autojs.util.RhinoUtils.coerceNumber
import org.autojs.autojs.util.RhinoUtils.coerceString import org.autojs.autojs.util.RhinoUtils.coerceString
import org.autojs.autojs.util.RhinoUtils.coerceStringLowercase import org.autojs.autojs.util.RhinoUtils.coerceStringLowercase
import org.autojs.autojs.util.RhinoUtils.handleAsyncOperation
import org.autojs.autojs.util.RhinoUtils.isBackgroundThread import org.autojs.autojs.util.RhinoUtils.isBackgroundThread
import org.autojs.autojs.util.RhinoUtils.isUiThread import org.autojs.autojs.util.RhinoUtils.isUiThread
import org.autojs.autojs.util.RhinoUtils.newNativeObject import org.autojs.autojs.util.RhinoUtils.newNativeObject
@@ -86,6 +87,7 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
::imread.name, ::imread.name,
::copy.name, ::copy.name,
::load.name, ::load.name,
::loadAsync.name,
::clip.name, ::clip.name,
::pixel.name, ::pixel.name,
::captureScreen.name to AS_GLOBAL, ::captureScreen.name to AS_GLOBAL,
@@ -215,10 +217,17 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
@JvmStatic @JvmStatic
@RhinoRuntimeFunctionInterface @RhinoRuntimeFunctionInterface
fun load(scriptRuntime: ScriptRuntime, args: Array<out Any?>): ImageWrapper = ensureArgumentsOnlyOne(args) { src -> fun load(scriptRuntime: ScriptRuntime, args: Array<out Any?>): ImageWrapper? = ensureArgumentsOnlyOne(args) { src ->
scriptRuntime.images.load(coerceString(src)) scriptRuntime.images.load(coerceString(src))
} }
@JvmStatic
@RhinoRuntimeFunctionInterface
fun loadAsync(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeObject = ensureArgumentsOnlyOne(args) { src ->
val url = coerceString(src)
handleAsyncOperation(scriptRuntime) { scriptRuntime.images.load(url) }
}
@JvmStatic @JvmStatic
@RhinoRuntimeFunctionInterface @RhinoRuntimeFunctionInterface
fun clip(scriptRuntime: ScriptRuntime, args: Array<out Any?>): ImageWrapper = ensureArgumentsLengthInRange(args, 2..5) { fun clip(scriptRuntime: ScriptRuntime, args: Array<out Any?>): ImageWrapper = ensureArgumentsLengthInRange(args, 2..5) {

View File

@@ -17,6 +17,7 @@ import org.autojs.autojs.extension.ScriptableExtensions.defineProp
import org.autojs.autojs.extension.ScriptableExtensions.prop import org.autojs.autojs.extension.ScriptableExtensions.prop
import org.autojs.autojs.rhino.TopLevelScope import org.autojs.autojs.rhino.TopLevelScope
import org.autojs.autojs.runtime.ScriptRuntime import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.runtime.api.ScriptPromiseAdapter
import org.autojs.autojs.runtime.exception.ScriptInterruptedException import org.autojs.autojs.runtime.exception.ScriptInterruptedException
import org.autojs.autojs.runtime.exception.WrappedRuntimeException import org.autojs.autojs.runtime.exception.WrappedRuntimeException
import org.autojs.autojs6.BuildConfig import org.autojs.autojs6.BuildConfig
@@ -911,6 +912,37 @@ object RhinoUtils {
return null return null
} }
fun handleAsyncOperation(scriptRuntime: ScriptRuntime, func: () -> Any?): NativeObject {
val promiseAdapter = ScriptPromiseAdapter()
// Use Android Thread directly to avoid coupling with JS threads/loopers here.
// zh-CN: 直接使用 Android Thread, 避免在此处与 JS 线程/Looper 机制强耦合.
Thread {
try {
// Do the blocking work (e.g. network request) in background thread.
// zh-CN: 在后台线程执行阻塞式操作 (如网络请求).
val result = func.invoke()
// Resolve on UI thread so that UI scripts can safely touch `ui.*` in then().
// zh-CN: 在 UI 线程 resolve, 让 UI 脚本在 then() 中可安全操作 `ui.*`.
Handler(Looper.getMainLooper()).post {
promiseAdapter.resolve(result)
}
} catch (t: Throwable) {
// Reject on UI thread for consistent callback threading.
// zh-CN: 在 UI 线程 reject, 保持回调线程一致性.
Handler(Looper.getMainLooper()).post {
promiseAdapter.reject(t)
}
}
}.start()
// Convert ScriptPromiseAdapter into a JavaScript Promise.
// zh-CN: 将 ScriptPromiseAdapter 转换为 JavaScript Promise.
return callFunction(scriptRuntime, scriptRuntime.js_ResultAdapter, "promise", arrayOf(promiseAdapter)) as NativeObject
}
@JvmStatic @JvmStatic
fun Class<*>.getRhinoStandardFunctionMethods(): List<Method> { fun Class<*>.getRhinoStandardFunctionMethods(): List<Method> {
return this.declaredMethods.filter { return this.declaredMethods.filter {

View File

@@ -1,5 +1,5 @@
#Mon Jan 12 17:10:46 CST 2026 #Mon Jan 12 21:46:16 CST 2026
BUILD_TIME=1768209046850 BUILD_TIME=1768225576059
COMPILE_SDK_VERSION=36 COMPILE_SDK_VERSION=36
IMAGE_QUANT_CMAKE_VERSION=3.22.1 IMAGE_QUANT_CMAKE_VERSION=3.22.1
IMAGE_QUANT_NDK_VERSION=26.1.10909125 IMAGE_QUANT_NDK_VERSION=26.1.10909125
@@ -27,6 +27,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3 RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
TARGET_SDK_VERSION=36 TARGET_SDK_VERSION=36
TARGET_SDK_VERSION_INRT=29 TARGET_SDK_VERSION_INRT=29
VERSION_BUILD=3598 VERSION_BUILD=3599
VERSION_NAME=6.7.0 Alpha14 VERSION_NAME=6.7.0 Alpha14
VSCODE_EXT_REQUIRED_VERSION=1.0.13 VSCODE_EXT_REQUIRED_VERSION=1.0.13