mirror of
https://github.com/TonyJiangWJ/Auto.js.git
synced 2026-06-21 21:01:43 +08:00
api: threads, events
This commit is contained in:
parent
729958d419
commit
3647cef81b
23
app/src/main/assets/sample/多线程/多线程按键监听.js
Normal file
23
app/src/main/assets/sample/多线程/多线程按键监听.js
Normal file
@ -0,0 +1,23 @@
|
||||
auto();
|
||||
|
||||
threads.start(function(){
|
||||
//在子线程中调用observeKey()从而使按键事件处理在子线程执行
|
||||
events.observeKey();
|
||||
events.on("key_down", function(keyCode, events){
|
||||
//音量键关闭脚本
|
||||
if(keyCode == keys.volume_up){
|
||||
exit();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
toast("音量上键关闭脚本");
|
||||
|
||||
events.on("exit", function(){
|
||||
toast("脚本已结束");
|
||||
});
|
||||
|
||||
while(true){
|
||||
log("脚本运行中...");
|
||||
sleep(2000);
|
||||
}
|
||||
@ -88,6 +88,13 @@ public class EditActivity extends BaseActivity implements OnActivityResultDelega
|
||||
super.onActionModeStarted(mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (!mEditor.onBackPressed()) {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
if (mEditor.isTextChanged()) {
|
||||
|
||||
@ -91,7 +91,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
FunctionsKeyboardView mFunctionsKeyboard;
|
||||
|
||||
@ViewById(R.id.docs)
|
||||
EWebView mEWebView;
|
||||
EWebView mDocsWebView;
|
||||
|
||||
@ViewById(R.id.drawer_layout)
|
||||
DrawerLayout mDrawerLayout;
|
||||
@ -201,8 +201,8 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
setUpInputMethodEnhancedBar();
|
||||
setUpFunctionsKeyboard();
|
||||
setMenuItemStatus(R.id.save, false);
|
||||
mEWebView.getWebView().getSettings().setDisplayZoomControls(true);
|
||||
mEWebView.getWebView().loadUrl(Pref.getDocumentationUrl() + "index.html");
|
||||
mDocsWebView.getWebView().getSettings().setDisplayZoomControls(true);
|
||||
mDocsWebView.getWebView().loadUrl(Pref.getDocumentationUrl() + "index.html");
|
||||
|
||||
}
|
||||
|
||||
@ -257,6 +257,18 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
mShowFunctionsButton.setColorFilter(textColor);
|
||||
}
|
||||
|
||||
public boolean onBackPressed() {
|
||||
if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
|
||||
if (mDocsWebView.getWebView().canGoBack()) {
|
||||
mDocsWebView.getWebView().goBack();
|
||||
} else {
|
||||
mDrawerLayout.closeDrawer(Gravity.START);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Click(R.id.run)
|
||||
public void runAndSaveFileIfNeeded() {
|
||||
@ -414,7 +426,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
|
||||
.title(title)
|
||||
.url(absUrl)
|
||||
.pinToLeft(v -> {
|
||||
mEWebView.getWebView().loadUrl(absUrl);
|
||||
mDocsWebView.getWebView().loadUrl(absUrl);
|
||||
mDrawerLayout.openDrawer(Gravity.START);
|
||||
})
|
||||
.show();
|
||||
|
||||
@ -49,7 +49,6 @@ var __that__ = this;
|
||||
var Promise = require('promise.js');
|
||||
var JSON = require('__json2__.js');
|
||||
var util = require('__util__.js');
|
||||
var threads = __runtime__.threads;
|
||||
var device = __runtime__.device;
|
||||
|
||||
var __asGlobal__ = function(obj, functions){
|
||||
@ -65,7 +64,7 @@ require("__general__")(__runtime__, this);
|
||||
|
||||
(function(scope){
|
||||
var modules = ['app', 'automator', 'console', 'dialogs', 'io', 'selector', 'shell', 'web', 'ui',
|
||||
"images", "timers", "events", "engines", "RootAutomator", "http", "storages", "floaty"];
|
||||
"images", "timers", "threads", "events", "engines", "RootAutomator", "http", "storages", "floaty"];
|
||||
var len = modules.length;
|
||||
for(var i = 0; i < len; i++) {
|
||||
var m = modules[i];
|
||||
|
||||
12
autojs/src/main/assets/modules/__threads__.js
Normal file
12
autojs/src/main/assets/modules/__threads__.js
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
module.exports = function(__runtime__, scope){
|
||||
var threads = Object.create(__runtime__.threads);
|
||||
|
||||
|
||||
scope.sync = function(func, lock){
|
||||
lock = lock || null;
|
||||
return new org.mozilla.javascript.Synchronizer(func, lock);
|
||||
}
|
||||
|
||||
return threads;
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.stardust.autojs.core.eventloop;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
|
||||
import com.stardust.autojs.core.looper.Timer;
|
||||
import com.stardust.autojs.runtime.ScriptBridges;
|
||||
import com.stardust.autojs.runtime.exception.ScriptException;
|
||||
|
||||
@ -19,6 +20,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
public class EventEmitter {
|
||||
|
||||
|
||||
private static class ListenerWrapper {
|
||||
Object listener;
|
||||
boolean isOnce;
|
||||
@ -52,7 +54,11 @@ public class EventEmitter {
|
||||
Iterator<ListenerWrapper> listenerIterator = mListenerWrappers.iterator();
|
||||
while (listenerIterator.hasNext()) {
|
||||
ListenerWrapper listenerWrapper = listenerIterator.next();
|
||||
mBridges.callFunction(listenerWrapper.listener, EventEmitter.this, args);
|
||||
if (mTimer != null) {
|
||||
mTimer.setImmediate(listenerWrapper.listener, args);
|
||||
} else {
|
||||
mBridges.callFunction(listenerWrapper.listener, EventEmitter.this, args);
|
||||
}
|
||||
if (listenerWrapper.isOnce) {
|
||||
listenerIterator.remove();
|
||||
}
|
||||
@ -93,11 +99,17 @@ public class EventEmitter {
|
||||
public static int defaultMaxListeners = 10;
|
||||
private int mMaxListeners = defaultMaxListeners;
|
||||
protected ScriptBridges mBridges;
|
||||
private Timer mTimer;
|
||||
|
||||
public EventEmitter(ScriptBridges bridges) {
|
||||
mBridges = bridges;
|
||||
}
|
||||
|
||||
public EventEmitter(ScriptBridges bridges, Timer timer) {
|
||||
mTimer = timer;
|
||||
mBridges = bridges;
|
||||
}
|
||||
|
||||
public EventEmitter once(String eventName, Object listener) {
|
||||
getListeners(eventName).add(listener, true);
|
||||
return this;
|
||||
|
||||
@ -0,0 +1,225 @@
|
||||
package com.stardust.autojs.core.looper;
|
||||
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/12/28.
|
||||
*/
|
||||
|
||||
public class MainThreadProxy {
|
||||
|
||||
private final Thread mThread;
|
||||
private ScriptRuntime mRuntime;
|
||||
|
||||
public MainThreadProxy(Thread thread, ScriptRuntime runtime) {
|
||||
mThread = thread;
|
||||
mRuntime = runtime;
|
||||
}
|
||||
|
||||
public int setTimeout(Object callback, long delay, Object... args) {
|
||||
return getMainTimer().setTimeout(callback, delay, args);
|
||||
}
|
||||
|
||||
private Timer getMainTimer() {
|
||||
return mRuntime.timers.getMainTimer();
|
||||
}
|
||||
|
||||
public boolean clearTimeout(int id) {
|
||||
return getMainTimer().clearTimeout(id);
|
||||
}
|
||||
|
||||
public int setInterval(Object listener, long interval, Object... args) {
|
||||
return getMainTimer().setInterval(listener, interval, args);
|
||||
}
|
||||
|
||||
public boolean clearInterval(int id) {
|
||||
return getMainTimer().clearInterval(id);
|
||||
}
|
||||
|
||||
public int setImmediate(Object listener, Object... args) {
|
||||
return getMainTimer().setImmediate(listener, args);
|
||||
}
|
||||
|
||||
public boolean clearImmediate(int id) {
|
||||
return getMainTimer().clearImmediate(id);
|
||||
}
|
||||
|
||||
public static Thread currentThread() {
|
||||
return Thread.currentThread();
|
||||
}
|
||||
|
||||
public static void yield() {
|
||||
Thread.yield();
|
||||
}
|
||||
|
||||
public static void sleep(long millis) throws InterruptedException {
|
||||
Thread.sleep(millis);
|
||||
}
|
||||
|
||||
public static void sleep(long millis, int nanos) throws InterruptedException {
|
||||
Thread.sleep(millis, nanos);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
mThread.start();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
mThread.run();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void stop() {
|
||||
mThread.stop();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void stop(Throwable obj) {
|
||||
mThread.stop(obj);
|
||||
}
|
||||
|
||||
public void interrupt() {
|
||||
mThread.interrupt();
|
||||
}
|
||||
|
||||
public static boolean interrupted() {
|
||||
return Thread.interrupted();
|
||||
}
|
||||
|
||||
public boolean isInterrupted() {
|
||||
return mThread.isInterrupted();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void destroy() {
|
||||
mThread.destroy();
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
return mThread.isAlive();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void suspend() {
|
||||
mThread.suspend();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void resume() {
|
||||
mThread.resume();
|
||||
}
|
||||
|
||||
public void setPriority(int newPriority) {
|
||||
mThread.setPriority(newPriority);
|
||||
}
|
||||
|
||||
public int getPriority() {
|
||||
return mThread.getPriority();
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
mThread.setName(name);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mThread.getName();
|
||||
}
|
||||
|
||||
public ThreadGroup getThreadGroup() {
|
||||
return mThread.getThreadGroup();
|
||||
}
|
||||
|
||||
public static int activeCount() {
|
||||
return Thread.activeCount();
|
||||
}
|
||||
|
||||
public static int enumerate(Thread[] tarray) {
|
||||
return Thread.enumerate(tarray);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int countStackFrames() {
|
||||
return mThread.countStackFrames();
|
||||
}
|
||||
|
||||
public void join(long millis) throws InterruptedException {
|
||||
mThread.join(millis);
|
||||
}
|
||||
|
||||
public void join(long millis, int nanos) throws InterruptedException {
|
||||
mThread.join(millis, nanos);
|
||||
}
|
||||
|
||||
public void join() throws InterruptedException {
|
||||
mThread.join();
|
||||
}
|
||||
|
||||
public static void dumpStack() {
|
||||
Thread.dumpStack();
|
||||
}
|
||||
|
||||
public void setDaemon(boolean on) {
|
||||
mThread.setDaemon(on);
|
||||
}
|
||||
|
||||
public boolean isDaemon() {
|
||||
return mThread.isDaemon();
|
||||
}
|
||||
|
||||
public void checkAccess() {
|
||||
mThread.checkAccess();
|
||||
}
|
||||
|
||||
public ClassLoader getContextClassLoader() {
|
||||
return mThread.getContextClassLoader();
|
||||
}
|
||||
|
||||
public void setContextClassLoader(ClassLoader cl) {
|
||||
mThread.setContextClassLoader(cl);
|
||||
}
|
||||
|
||||
public static boolean holdsLock(Object obj) {
|
||||
return Thread.holdsLock(obj);
|
||||
}
|
||||
|
||||
public StackTraceElement[] getStackTrace() {
|
||||
return mThread.getStackTrace();
|
||||
}
|
||||
|
||||
public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
|
||||
return Thread.getAllStackTraces();
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return mThread.getId();
|
||||
}
|
||||
|
||||
public Thread.State getState() {
|
||||
return mThread.getState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mThread.toString();
|
||||
}
|
||||
|
||||
public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) {
|
||||
Thread.setDefaultUncaughtExceptionHandler(eh);
|
||||
}
|
||||
|
||||
public static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
|
||||
return Thread.getDefaultUncaughtExceptionHandler();
|
||||
}
|
||||
|
||||
public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() {
|
||||
return mThread.getUncaughtExceptionHandler();
|
||||
}
|
||||
|
||||
public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) {
|
||||
mThread.setUncaughtExceptionHandler(eh);
|
||||
}
|
||||
}
|
||||
@ -109,4 +109,5 @@ public class Timer {
|
||||
Log.d(LOG_TAG, "mMaxCallbackUptimeMillisForAllThreads:" + mMaxCallbackUptimeMillis);
|
||||
return mMaxCallbackUptimeMillis > SystemClock.uptimeMillis();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||
import com.stardust.concurrent.VolatileBox;
|
||||
import com.stardust.lang.ThreadCompat;
|
||||
|
||||
import org.mozilla.javascript.NativeArray;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@ -25,6 +27,8 @@ public class TimerThread extends ThreadCompat {
|
||||
private final VolatileBox<Long> mMaxCallbackUptimeMillisForAllThreads;
|
||||
private final ScriptRuntime mRuntime;
|
||||
private Runnable mTarget;
|
||||
private boolean mRunning = false;
|
||||
private final Object mRunningLock = new Object();
|
||||
|
||||
public TimerThread(ScriptRuntime runtime, VolatileBox<Long> maxCallbackUptimeMillisForAllThreads, Runnable target) {
|
||||
super(target);
|
||||
@ -38,6 +42,7 @@ public class TimerThread extends ThreadCompat {
|
||||
mRuntime.loopers.prepare();
|
||||
mTimer = new Timer(mRuntime.bridges, mMaxCallbackUptimeMillisForAllThreads);
|
||||
sTimerMap.put(Thread.currentThread(), mTimer);
|
||||
notifyRunning();
|
||||
new Handler().post(mTarget);
|
||||
try {
|
||||
Looper.loop();
|
||||
@ -47,10 +52,18 @@ public class TimerThread extends ThreadCompat {
|
||||
}
|
||||
} finally {
|
||||
onExit();
|
||||
mTimer = null;
|
||||
sTimerMap.remove(Thread.currentThread(), mTimer);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyRunning() {
|
||||
synchronized (mRunningLock) {
|
||||
mRunning = true;
|
||||
mRunningLock.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
protected void onExit() {
|
||||
mRuntime.loopers.notifyThreadExit(this);
|
||||
@ -65,26 +78,46 @@ public class TimerThread extends ThreadCompat {
|
||||
}
|
||||
|
||||
public int setTimeout(Object callback, long delay, Object... args) {
|
||||
return mTimer.setTimeout(callback, delay, args);
|
||||
return getTimer().setTimeout(callback, delay, args);
|
||||
}
|
||||
|
||||
private Timer getTimer() {
|
||||
if (mTimer == null) {
|
||||
throw new IllegalStateException("thread is not alive");
|
||||
}
|
||||
return mTimer;
|
||||
}
|
||||
|
||||
public boolean clearTimeout(int id) {
|
||||
return mTimer.clearTimeout(id);
|
||||
return getTimer().clearTimeout(id);
|
||||
}
|
||||
|
||||
public int setInterval(Object listener, long interval, Object... args) {
|
||||
return mTimer.setInterval(listener, interval, args);
|
||||
return getTimer().setInterval(listener, interval, args);
|
||||
}
|
||||
|
||||
public boolean clearInterval(int id) {
|
||||
return mTimer.clearInterval(id);
|
||||
return getTimer().clearInterval(id);
|
||||
}
|
||||
|
||||
public int setImmediate(Object listener, Object... args) {
|
||||
return mTimer.setImmediate(listener, args);
|
||||
return getTimer().setImmediate(listener, args);
|
||||
}
|
||||
|
||||
public boolean clearImmediate(int id) {
|
||||
return mTimer.clearImmediate(id);
|
||||
return getTimer().clearImmediate(id);
|
||||
}
|
||||
|
||||
public void waitFor() throws InterruptedException {
|
||||
synchronized (mRunningLock) {
|
||||
if (mRunning)
|
||||
return;
|
||||
mRunningLock.wait();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Thread[" + getName() + "," + getPriority() + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ public class ScriptRuntime {
|
||||
public final Engines engines;
|
||||
|
||||
@ScriptVariable
|
||||
public final Threads threads;
|
||||
public Threads threads;
|
||||
|
||||
@ScriptVariable
|
||||
public final Floaty floaty;
|
||||
@ -187,7 +187,6 @@ public class ScriptRuntime {
|
||||
}
|
||||
engines = new Engines(builder.mEngineService);
|
||||
dialogs = new Dialogs(app, uiHandler, bridges);
|
||||
threads = new Threads(this);
|
||||
device = new Device(uiHandler.getContext());
|
||||
floaty = new Floaty(uiHandler, ui);
|
||||
}
|
||||
@ -195,7 +194,8 @@ public class ScriptRuntime {
|
||||
public void init() {
|
||||
if (loopers != null)
|
||||
throw new IllegalStateException("already initialized");
|
||||
timers = new Timers(bridges);
|
||||
threads = new Threads(this);
|
||||
timers = new Timers(bridges, threads);
|
||||
loopers = new Loopers(this);
|
||||
events = new Events(uiHandler.getContext(), accessibilityBridge, this);
|
||||
mThread = Thread.currentThread();
|
||||
|
||||
@ -14,6 +14,8 @@ import com.stardust.autojs.R;
|
||||
import com.stardust.autojs.core.accessibility.AccessibilityBridge;
|
||||
import com.stardust.autojs.core.eventloop.EventEmitter;
|
||||
import com.stardust.autojs.core.looper.Loopers;
|
||||
import com.stardust.autojs.core.looper.MainThreadProxy;
|
||||
import com.stardust.autojs.core.looper.Timer;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.notification.Notification;
|
||||
import com.stardust.notification.NotificationListenerService;
|
||||
@ -58,6 +60,15 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver
|
||||
return new EventEmitter(mBridges);
|
||||
}
|
||||
|
||||
public EventEmitter emitter(Thread thread) {
|
||||
Timer timer = mScriptRuntime.timers.getTimerForThread(thread);
|
||||
return new EventEmitter(mBridges, timer);
|
||||
}
|
||||
|
||||
public EventEmitter emitter(MainThreadProxy mainThreadProxy) {
|
||||
return new EventEmitter(mBridges, mScriptRuntime.timers.getMainTimer());
|
||||
}
|
||||
|
||||
public void observeKey() {
|
||||
if (mListeningKey)
|
||||
return;
|
||||
|
||||
@ -2,6 +2,7 @@ package com.stardust.autojs.runtime.api;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
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;
|
||||
@ -14,10 +15,15 @@ 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;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/12/3.
|
||||
@ -27,15 +33,33 @@ public class Threads {
|
||||
|
||||
private final HashSet<Thread> mThreads = new HashSet<>();
|
||||
private ScriptRuntime mRuntime;
|
||||
private final Thread mMainThread;
|
||||
private MainThreadProxy mMainThreadProxy;
|
||||
private int mSpawnCount = 0;
|
||||
|
||||
public Threads(ScriptRuntime runtime) {
|
||||
mRuntime = runtime;
|
||||
mMainThread = Thread.currentThread();
|
||||
mMainThreadProxy = new MainThreadProxy(Thread.currentThread(), mRuntime);
|
||||
}
|
||||
|
||||
public Thread getMainThread() {
|
||||
return mMainThread;
|
||||
}
|
||||
|
||||
public Object currentThread() {
|
||||
Thread thread = Thread.currentThread();
|
||||
if (thread == mMainThread)
|
||||
return mMainThreadProxy;
|
||||
return thread;
|
||||
}
|
||||
|
||||
public TimerThread start(Runnable runnable) {
|
||||
TimerThread thread = startThread(runnable);
|
||||
synchronized (mThreads) {
|
||||
mThreads.add(thread);
|
||||
thread.setName(thread.getName() + " (Spawn-" + mSpawnCount + ")");
|
||||
mSpawnCount++;
|
||||
}
|
||||
thread.start();
|
||||
return thread;
|
||||
@ -63,24 +87,16 @@ public class Threads {
|
||||
return new VolatileDispose();
|
||||
}
|
||||
|
||||
public List list() {
|
||||
return Collections.synchronizedList(new ArrayList<>());
|
||||
}
|
||||
|
||||
public Set set() {
|
||||
return new ConcurrentSkipListSet();
|
||||
}
|
||||
|
||||
public Map map() {
|
||||
return new ConcurrentHashMap();
|
||||
public AtomicLong atomic(long value) {
|
||||
return new AtomicLong(value);
|
||||
}
|
||||
|
||||
public AtomicLong atomic() {
|
||||
return new AtomicLong();
|
||||
}
|
||||
|
||||
public AtomicLong atomic(long value) {
|
||||
return new AtomicLong(value);
|
||||
public Lock lock() {
|
||||
return new ReentrantLock();
|
||||
}
|
||||
|
||||
public void shutDownAll() {
|
||||
|
||||
@ -19,12 +19,17 @@ public class Timers {
|
||||
private static final String LOG_TAG = "Timers";
|
||||
|
||||
private VolatileBox<Long> mMaxCallbackUptimeMillisForAllThreads = new VolatileBox<>(0L);
|
||||
private Thread mMainThread;
|
||||
private Threads mThreads;
|
||||
private Timer mMainTimer;
|
||||
|
||||
public Timers(ScriptBridges bridges) {
|
||||
mMainThread = Thread.currentThread();
|
||||
|
||||
public Timers(ScriptBridges bridges, Threads threads) {
|
||||
mMainTimer = new Timer(bridges, mMaxCallbackUptimeMillisForAllThreads);
|
||||
mThreads = threads;
|
||||
}
|
||||
|
||||
public Timer getMainTimer() {
|
||||
return mMainTimer;
|
||||
}
|
||||
|
||||
public VolatileBox<Long> getMaxCallbackUptimeMillisForAllThreads() {
|
||||
@ -32,10 +37,14 @@ public class Timers {
|
||||
}
|
||||
|
||||
private Timer getTimerForCurrentThread() {
|
||||
if (Thread.currentThread() == mMainThread) {
|
||||
return getTimerForThread(Thread.currentThread());
|
||||
}
|
||||
|
||||
public Timer getTimerForThread(Thread thread) {
|
||||
if (thread == mThreads.getMainThread()) {
|
||||
return mMainTimer;
|
||||
}
|
||||
return TimerThread.getTimerForCurrentThread();
|
||||
return TimerThread.getTimerForThread(thread);
|
||||
}
|
||||
|
||||
public int setTimeout(Object callback, long delay, Object... args) {
|
||||
@ -64,7 +73,7 @@ public class Timers {
|
||||
|
||||
public boolean hasPendingCallbacks() {
|
||||
//如果是脚本主线程,则检查所有子线程中的定时回调。mFutureCallbackUptimeMillis用来记录所有子线程中定时最久的一个。
|
||||
if (mMainThread == Thread.currentThread()) {
|
||||
if (mThreads.getMainThread() == Thread.currentThread()) {
|
||||
Log.d(LOG_TAG, "[main thread]hasPendingCallbacks:" + (mMaxCallbackUptimeMillisForAllThreads.get() > SystemClock.uptimeMillis()));
|
||||
Log.d(LOG_TAG, "mMaxCallbackUptimeMillisForAllThreads:" + mMaxCallbackUptimeMillisForAllThreads.get());
|
||||
return mMaxCallbackUptimeMillisForAllThreads.get() > SystemClock.uptimeMillis();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user