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

@@ -559,15 +559,11 @@ public class Images {
};
}
public ImageWrapper load(String src) {
try {
HttpURLConnection connection = (HttpURLConnection) new URL(src).openConnection();
connection.setDoInput(true);
connection.connect();
return ImageWrapper.ofBitmap(mScriptRuntime, BitmapFactory.decodeStream(connection.getInputStream()));
} catch (IOException e) {
return null;
}
public ImageWrapper load(String src) throws IOException {
HttpURLConnection connection = (HttpURLConnection) new URL(src).openConnection();
connection.setDoInput(true);
connection.connect();
return ImageWrapper.ofBitmap(mScriptRuntime, BitmapFactory.decodeStream(connection.getInputStream()));
}
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.coerceString
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.isUiThread
import org.autojs.autojs.util.RhinoUtils.newNativeObject
@@ -86,6 +87,7 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
::imread.name,
::copy.name,
::load.name,
::loadAsync.name,
::clip.name,
::pixel.name,
::captureScreen.name to AS_GLOBAL,
@@ -215,10 +217,17 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
@JvmStatic
@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))
}
@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
@RhinoRuntimeFunctionInterface
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.rhino.TopLevelScope
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.WrappedRuntimeException
import org.autojs.autojs6.BuildConfig
@@ -911,6 +912,37 @@ object RhinoUtils {
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
fun Class<*>.getRhinoStandardFunctionMethods(): List<Method> {
return this.declaredMethods.filter {