fix: thread.interrupt() not quit looper
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user