定时器调用性能优化
This commit is contained in:
@@ -54,10 +54,11 @@ class Loopers(val runtime: ScriptRuntime) {
|
||||
private var mMainLooperQuitHandler: LooperQuitHandler? = null
|
||||
private val allTasks = ConcurrentLinkedQueue<AsyncTask>()
|
||||
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()
|
||||
|
||||
@@ -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<Int, Runnable?>()
|
||||
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<Any>)
|
||||
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<Any>) {
|
||||
private fun callFunction(callback: Any, thiz: Any?, args :Any?) {
|
||||
val myArgs = args?.let { args as Array<*> }?: emptyArray<Any>()
|
||||
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<Any>)
|
||||
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<Any>)
|
||||
callFunction(listener, null, args)
|
||||
mHandlerCallbacks.remove(id)
|
||||
}
|
||||
mHandlerCallbacks[id] = r
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user