diff --git a/app/src/main/java/org/autojs/autojs/core/looper/Loopers.kt b/app/src/main/java/org/autojs/autojs/core/looper/Loopers.kt index 53d3f73b..3185e93e 100644 --- a/app/src/main/java/org/autojs/autojs/core/looper/Loopers.kt +++ b/app/src/main/java/org/autojs/autojs/core/looper/Loopers.kt @@ -54,10 +54,11 @@ class Loopers(val runtime: ScriptRuntime) { private var mMainLooperQuitHandler: LooperQuitHandler? = null private val allTasks = ConcurrentLinkedQueue() val mTimer: Timer + val myLooper: Looper init { prepare() - val myLooper = Looper.myLooper()!! + myLooper = Looper.myLooper()!! mTimer = Timer(runtime, myLooper) waitWhenIdle = myLooper == Looper.getMainLooper() } @@ -69,12 +70,16 @@ class Loopers(val runtime: ScriptRuntime) { } fun addAsyncTask(task: AsyncTask) { - allTasks.add(task) + synchronized(myLooper) { + allTasks.add(task) + } } fun removeAsyncTask(task: AsyncTask) { - allTasks.remove(task) - mTimer.post(EMPTY_RUNNABLE) + synchronized(myLooper) { + allTasks.remove(task) + mTimer.post(EMPTY_RUNNABLE) + } } private fun checkTask(): Boolean { @@ -86,15 +91,17 @@ class Loopers(val runtime: ScriptRuntime) { } private fun shouldQuitLooper(): Boolean { - if (Thread.currentThread().isInterrupted) return true - if (mTimer.hasPendingCallbacks()) return false - //检查是否有运行中的线程 - if (checkTask()) return false - if (waitWhenIdle) return false - if ((Context.getCurrentContext() as AutoJsContext).hasPendingContinuation()) { - return false + synchronized(myLooper) { + if (Thread.currentThread().isInterrupted) return true + if (mTimer.hasPendingCallbacks()) return false + //检查是否有运行中的线程 + if (checkTask()) return false + if (waitWhenIdle) return false + if ((Context.getCurrentContext() as AutoJsContext).hasPendingContinuation()) { + return false + } + return true } - return true } private fun initServantThread() { @@ -111,7 +118,7 @@ class Loopers(val runtime: ScriptRuntime) { get() { if (mServantLooper == null) { initServantThread() - val lock = this as Object + val lock = this as java.lang.Object synchronized(lock) { try { lock.wait() diff --git a/app/src/main/java/org/autojs/autojs/core/looper/Timer.kt b/app/src/main/java/org/autojs/autojs/core/looper/Timer.kt index 14dbd0ad..95dad6c9 100644 --- a/app/src/main/java/org/autojs/autojs/core/looper/Timer.kt +++ b/app/src/main/java/org/autojs/autojs/core/looper/Timer.kt @@ -4,6 +4,9 @@ import android.os.Handler import android.os.Looper import android.os.SystemClock import org.autojs.autojs.runtime.ScriptRuntime +import org.mozilla.javascript.BaseFunction +import org.mozilla.javascript.Context +import org.mozilla.javascript.Scriptable import java.util.concurrent.ConcurrentHashMap import kotlin.random.Random @@ -14,6 +17,7 @@ class Timer( runtime: ScriptRuntime, looper: Looper ) { + private val myLooper: Looper = looper private val mHandlerCallbacks = ConcurrentHashMap() private val mRuntime: ScriptRuntime = runtime private val mHandler: Handler = Handler(looper) @@ -21,10 +25,10 @@ class Timer( constructor(runtime: ScriptRuntime, ) : this(runtime, Looper.myLooper()!!) - fun setTimeout(callback: Any, delay: Long, vararg args: Any): Int { + fun setTimeout(callback: Any, delay: Long, vararg args: Any?): Int { val id = createTimerId() val r = Runnable { - callFunction(callback, null, args as Array) + callFunction(callback, null, args) mHandlerCallbacks.remove(id) } mHandlerCallbacks[id] = r @@ -32,9 +36,13 @@ class Timer( return id } - private fun callFunction(callback: Any, thiz: Any?, args: Array) { + private fun callFunction(callback: Any, thiz: Any?, args :Any?) { + val myArgs = args?.let { args as Array<*> }?: emptyArray() + val map = myArgs.map { Context.javaToJS(it, callback as BaseFunction) } try { - mRuntime.bridges.callFunction(callback, thiz, args) + (callback as BaseFunction).call(Context.getCurrentContext(),callback.parentScope, + thiz as? Scriptable?, map.toTypedArray() + ) } catch (e: Exception) { if (isUiLoop) { mRuntime.exit(e) @@ -52,12 +60,12 @@ class Timer( return id } - fun setInterval(listener: Any, interval: Long, vararg args: Any): Int { + fun setInterval(listener: Any, interval: Long, vararg args: Any?): Int { val id = createTimerId() val r: Runnable = object : Runnable { override fun run() { if (mHandlerCallbacks[id] == null) return - callFunction(listener, null, args as Array) + callFunction(listener, null, args) postDelayed(this, interval) } } @@ -67,22 +75,26 @@ class Timer( } fun postDelayed(r: Runnable, interval: Long) { - val uptime = SystemClock.uptimeMillis() + interval - mHandler.postAtTime(r, uptime) + synchronized(myLooper) { + val uptime = SystemClock.uptimeMillis() + interval + mHandler.postAtTime(r, uptime) + } } fun post(r: Runnable) { - mHandler.post(r) + synchronized(myLooper) { + mHandler.post(r) + } } fun clearInterval(id: Int): Boolean = clearCallback(id) fun clearImmediate(id: Int): Boolean = clearCallback(id) fun clearTimeout(id: Int): Boolean = clearCallback(id) - fun setImmediate(listener: Any, vararg args: Any): Int { + fun setImmediate(listener: Any, vararg args: Any?): Int { val id = createTimerId() val r = Runnable { - callFunction(listener, null, args as Array) + callFunction(listener, null, args) mHandlerCallbacks.remove(id) } mHandlerCallbacks[id] = r diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/Threads.kt b/app/src/main/java/org/autojs/autojs/runtime/api/Threads.kt index ac3ae7ff..d3be8e14 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/Threads.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/Threads.kt @@ -6,6 +6,8 @@ import org.autojs.autojs.core.looper.MainThreadProxy import org.autojs.autojs.core.looper.TimerThread import org.autojs.autojs.runtime.ScriptRuntime import org.autojs.autojs.runtime.exception.ScriptInterruptedException +import org.mozilla.javascript.BaseFunction +import org.mozilla.javascript.Context import java.util.concurrent.Executors import java.util.concurrent.ThreadFactory import java.util.concurrent.atomic.AtomicLong @@ -23,7 +25,14 @@ class Threads(private val mRuntime: ScriptRuntime) { private var mExit = false private val looperTask = Loopers.AsyncTask("AsyncTaskThreadPool") private val threadPool = Executors.newFixedThreadPool(20, ThreadFactory { - val thread = Thread(it) + val thread = Thread(fun() { + Context.enter() + try { + it.run() + } finally { + Context.exit() + } + }) thread.name = mainThread.name + " (AsyncThread)" thread }) @@ -33,17 +42,20 @@ class Threads(private val mRuntime: ScriptRuntime) { return if (thread === mainThread) mMainThreadProxy else thread } - fun runTaskForThreadPool(runnable: Runnable) { + fun runTaskForThreadPool(runnable: BaseFunction) { if (mTaskCount.addAndGet(1) == 1L) mRuntime.loopers.addAsyncTask(looperTask) threadPool.execute { try { - runnable.run() + runnable.call( + Context.getCurrentContext(), runnable.parentScope, runnable, + emptyArray() + ) } catch (e: Throwable) { if (!ScriptInterruptedException.causedByInterrupted(e)) { mRuntime.console.error("$this: ", e) } } finally { - if (mTaskCount.addAndGet(-1) == 0L){ + if (mTaskCount.addAndGet(-1) == 0L) { mRuntime.loopers.removeAsyncTask(looperTask) } } diff --git a/version.properties b/version.properties index 34c3b7fd..0cb338a1 100644 --- a/version.properties +++ b/version.properties @@ -1,8 +1,8 @@ -#Sat Jun 10 13:06:56 CST 2023 -BUILD_TIME=1686373616005 +#Sat Jun 10 19:42:58 CST 2023 +BUILD_TIME=1686397378556 COMPILE_SDK_VERSION=33 JAVA_VERSION=20 MIN_SDK_VERSION=24 TARGET_SDK_VERSION=33 -VERSION_BUILD=1910 +VERSION_BUILD=1911 VERSION_NAME=6.3.1