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