diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditText.java b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditText.java index 5228a717..580686a8 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditText.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/edit/editor/CodeEditText.java @@ -170,7 +170,7 @@ public class CodeEditText extends AppCompatEditText { if (lineStart >= textLength) { return; } - int lineEnd = layout.getLineVisibleEnd(line); + int lineEnd = Math.min(layout.getLineVisibleEnd(line), highlightTokens.colors.length); int visibleCharStart = getVisibleCharIndex(paint, scrollX, lineStart, lineEnd); int visibleCharEnd = getVisibleCharIndex(paint, scrollX + mParentScrollView.getWidth(), lineStart, lineEnd) + 1; int previousColorPos = visibleCharStart; diff --git a/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.java b/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.java index 2b3726bb..491c578c 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.java +++ b/autojs/src/main/java/com/stardust/autojs/core/looper/Loopers.java @@ -3,6 +3,7 @@ package com.stardust.autojs.core.looper; import android.os.Handler; import android.os.Looper; import android.os.MessageQueue; +import android.util.Log; import com.stardust.autojs.runtime.ScriptRuntime; import com.stardust.autojs.runtime.api.Threads; @@ -18,6 +19,8 @@ import java.util.concurrent.CopyOnWriteArrayList; public class Loopers implements MessageQueue.IdleHandler { + private static final String LOG_TAG = "Loopers"; + public interface LooperQuitHandler { boolean shouldQuit(); } @@ -139,11 +142,14 @@ public class Loopers implements MessageQueue.IdleHandler { if (l == null) return true; if (l == mMainLooper) { + Log.d(LOG_TAG, "main looper queueIdle"); if (shouldQuitLooper() && !mThreads.hasRunningThreads() && mMainLooperQuitHandler != null && mMainLooperQuitHandler.shouldQuit()) { + Log.d(LOG_TAG, "main looper quit"); l.quit(); } } else { + Log.d(LOG_TAG, "looper queueIdle: " + l); if (shouldQuitLooper()) { l.quit(); } @@ -153,12 +159,13 @@ public class Loopers implements MessageQueue.IdleHandler { public void prepare() { if (Looper.myLooper() == null) - Looper.prepare(); + LooperHelper.prepare(); Looper.myQueue().addIdleHandler(this); waitWhenIdle.set(Looper.myLooper() == Looper.getMainLooper()); } public void notifyThreadExit(TimerThread thread) { + Log.d(LOG_TAG, "notifyThreadExit: " + thread); //当子线程退成时,主线程需要检查自身是否退出(主线程在所有子线程执行完成后才能退出,如果主线程已经执行完任务仍然要等待所有子线程), //此时通过向主线程发送一个空的Runnable,主线程执行完这个Runnable后会触发IdleHandler,从而检查自身是否退出 mMainHandler.post(EMPTY_RUNNABLE); diff --git a/autojs/src/main/java/com/stardust/autojs/core/looper/TimerThread.java b/autojs/src/main/java/com/stardust/autojs/core/looper/TimerThread.java index a1cfcd26..7fe88314 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/looper/TimerThread.java +++ b/autojs/src/main/java/com/stardust/autojs/core/looper/TimerThread.java @@ -57,6 +57,12 @@ public class TimerThread extends ThreadCompat { } } + @Override + public void interrupt() { + LooperHelper.quitForThread(this); + super.interrupt(); + } + private void notifyRunning() { synchronized (mRunningLock) { mRunning = true; diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Threads.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/Threads.java index 0e2e1b06..abb91107 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Threads.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Threads.java @@ -6,21 +6,9 @@ import com.stardust.autojs.core.looper.MainThreadProxy; import com.stardust.autojs.core.looper.TimerThread; import com.stardust.autojs.engine.RhinoJavaScriptEngine; import com.stardust.autojs.runtime.ScriptRuntime; -import com.stardust.concurrent.VolatileBox; import com.stardust.concurrent.VolatileDispose; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListSet; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -55,7 +43,7 @@ public class Threads { } public TimerThread start(Runnable runnable) { - TimerThread thread = startThread(runnable); + TimerThread thread = createThread(runnable); synchronized (mThreads) { mThreads.add(thread); thread.setName(thread.getName() + " (Spawn-" + mSpawnCount + ")"); @@ -66,7 +54,7 @@ public class Threads { } @NonNull - private TimerThread startThread(Runnable runnable) { + private TimerThread createThread(Runnable runnable) { return new TimerThread(mRuntime, mRuntime.timers.getMaxCallbackUptimeMillisForAllThreads(), () -> { ((RhinoJavaScriptEngine) mRuntime.engines.myEngine()).createContext(); diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Timers.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/Timers.java index 6eff9905..31fd355e 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Timers.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Timers.java @@ -80,9 +80,9 @@ public class Timers { public boolean hasPendingCallbacks() { //如果是脚本主线程,则检查所有子线程中的定时回调。mFutureCallbackUptimeMillis用来记录所有子线程中定时最久的一个。 - if (mThreads.getMainThread() == Thread.currentThread()) { - return mMaxCallbackUptimeMillisForAllThreads.get() > SystemClock.uptimeMillis(); - } + // if (mThreads.getMainThread() == Thread.currentThread()) { + // return mMaxCallbackUptimeMillisForAllThreads.get() > SystemClock.uptimeMillis(); + //} //否则检查当前线程的定时回调 return getTimerForCurrentThread().hasPendingCallbacks(); }