api(dialogs): change dialog event callback thread to caller thread
This commit is contained in:
@@ -119,11 +119,13 @@ module.exports = function(__runtime__, scope){
|
|||||||
"negative": {method: "negativeText"},
|
"negative": {method: "negativeText"},
|
||||||
"negativeColor": {adapter: parseColor},
|
"negativeColor": {adapter: parseColor},
|
||||||
"cancelable": null,
|
"cancelable": null,
|
||||||
"canceledOnTouchOutside": null
|
"canceledOnTouchOutside": null,
|
||||||
|
autoDismiss: null
|
||||||
};
|
};
|
||||||
|
|
||||||
dialogs.build = function(properties){
|
dialogs.build = function(properties){
|
||||||
var builder = __runtime__.dialogs.newBuilder();
|
var builder = Object.create(__runtime__.dialogs.newBuilder());
|
||||||
|
builder.thread = threads.currentThread();
|
||||||
for(var name in properties){
|
for(var name in properties){
|
||||||
if(!properties.hasOwnProperty(name)){
|
if(!properties.hasOwnProperty(name)){
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -5,12 +5,14 @@ import android.os.Looper;
|
|||||||
import android.os.MessageQueue;
|
import android.os.MessageQueue;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.dx.util.IntSet;
|
||||||
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;
|
||||||
import com.stardust.autojs.runtime.api.Timers;
|
import com.stardust.autojs.runtime.api.Timers;
|
||||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||||
import com.stardust.lang.ThreadCompat;
|
import com.stardust.lang.ThreadCompat;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,6 +31,8 @@ public class Loopers implements MessageQueue.IdleHandler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private volatile ThreadLocal<Boolean> waitWhenIdle = new ThreadLocal<>();
|
private volatile ThreadLocal<Boolean> waitWhenIdle = new ThreadLocal<>();
|
||||||
|
private volatile ThreadLocal<HashSet<Integer>> waitIds = new ThreadLocal<>();
|
||||||
|
private volatile ThreadLocal<Integer> maxWaitId = new ThreadLocal<>();
|
||||||
private volatile ThreadLocal<CopyOnWriteArrayList<LooperQuitHandler>> looperQuitHanders = new ThreadLocal<>();
|
private volatile ThreadLocal<CopyOnWriteArrayList<LooperQuitHandler>> looperQuitHanders = new ThreadLocal<>();
|
||||||
private volatile Looper mServantLooper;
|
private volatile Looper mServantLooper;
|
||||||
private Timers mTimers;
|
private Timers mTimers;
|
||||||
@@ -75,7 +79,7 @@ public class Loopers implements MessageQueue.IdleHandler {
|
|||||||
if (mTimers.hasPendingCallbacks()) {
|
if (mTimers.hasPendingCallbacks()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (waitWhenIdle.get()) {
|
if (waitWhenIdle.get() || !waitIds.get().isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CopyOnWriteArrayList<LooperQuitHandler> handlers = looperQuitHanders.get();
|
CopyOnWriteArrayList<LooperQuitHandler> handlers = looperQuitHanders.get();
|
||||||
@@ -123,6 +127,17 @@ public class Loopers implements MessageQueue.IdleHandler {
|
|||||||
mServantLooper.quit();
|
mServantLooper.quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int waitWhenIdle() {
|
||||||
|
int id = maxWaitId.get();
|
||||||
|
maxWaitId.set(id + 1);
|
||||||
|
waitIds.get().add(id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doNotWaitWhenIdle(int waitId) {
|
||||||
|
waitIds.get().remove(waitId);
|
||||||
|
}
|
||||||
|
|
||||||
public void waitWhenIdle(boolean b) {
|
public void waitWhenIdle(boolean b) {
|
||||||
waitWhenIdle.set(b);
|
waitWhenIdle.set(b);
|
||||||
}
|
}
|
||||||
@@ -162,6 +177,8 @@ public class Loopers implements MessageQueue.IdleHandler {
|
|||||||
LooperHelper.prepare();
|
LooperHelper.prepare();
|
||||||
Looper.myQueue().addIdleHandler(this);
|
Looper.myQueue().addIdleHandler(this);
|
||||||
waitWhenIdle.set(Looper.myLooper() == Looper.getMainLooper());
|
waitWhenIdle.set(Looper.myLooper() == Looper.getMainLooper());
|
||||||
|
waitIds.set(new HashSet<>());
|
||||||
|
maxWaitId.set(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyThreadExit(TimerThread thread) {
|
public void notifyThreadExit(TimerThread thread) {
|
||||||
|
|||||||
@@ -53,13 +53,35 @@ public class JsDialog {
|
|||||||
private final EventEmitter mEmitter;
|
private final EventEmitter mEmitter;
|
||||||
private final UiHandler mUiHandler;
|
private final UiHandler mUiHandler;
|
||||||
private final MaterialDialog mDialog;
|
private final MaterialDialog mDialog;
|
||||||
|
private final JsDialogBuilder mBuilder;
|
||||||
|
|
||||||
public JsDialog(MaterialDialog dialog, EventEmitter emitter, UiHandler uiHandler) {
|
public JsDialog(JsDialogBuilder builder, EventEmitter emitter, UiHandler uiHandler) {
|
||||||
mDialog = dialog;
|
mBuilder = builder;
|
||||||
|
mDialog = builder.build();
|
||||||
mEmitter = emitter;
|
mEmitter = emitter;
|
||||||
mUiHandler = uiHandler;
|
mUiHandler = uiHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JsDialog show() {
|
||||||
|
checkWindowType();
|
||||||
|
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||||
|
mDialog.show();
|
||||||
|
} else {
|
||||||
|
mUiHandler.post(mDialog::show);
|
||||||
|
}
|
||||||
|
mBuilder.onShowCalled();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkWindowType() {
|
||||||
|
Context context = mDialog.getContext();
|
||||||
|
if (!DialogUtils.isActivityContext(context)) {
|
||||||
|
Window window = mDialog.getWindow();
|
||||||
|
if (window != null)
|
||||||
|
window.setType(WindowManager.LayoutParams.TYPE_PHONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public MaterialDialog.Builder getBuilder() {
|
public MaterialDialog.Builder getBuilder() {
|
||||||
return mDialog.getBuilder();
|
return mDialog.getBuilder();
|
||||||
}
|
}
|
||||||
@@ -695,22 +717,5 @@ public class JsDialog {
|
|||||||
return EventEmitter.defaultMaxListeners();
|
return EventEmitter.defaultMaxListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsDialog show() {
|
|
||||||
checkWindowType();
|
|
||||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
|
||||||
mDialog.show();
|
|
||||||
} else {
|
|
||||||
mUiHandler.post(mDialog::show);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkWindowType() {
|
|
||||||
Context context = mDialog.getContext();
|
|
||||||
if (!DialogUtils.isActivityContext(context)) {
|
|
||||||
Window window = mDialog.getWindow();
|
|
||||||
if (window != null)
|
|
||||||
window.setType(WindowManager.LayoutParams.TYPE_PHONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ import com.afollestad.materialdialogs.MaterialDialog;
|
|||||||
import com.afollestad.materialdialogs.StackingBehavior;
|
import com.afollestad.materialdialogs.StackingBehavior;
|
||||||
import com.afollestad.materialdialogs.Theme;
|
import com.afollestad.materialdialogs.Theme;
|
||||||
import com.stardust.autojs.core.eventloop.EventEmitter;
|
import com.stardust.autojs.core.eventloop.EventEmitter;
|
||||||
|
import com.stardust.autojs.core.looper.Loopers;
|
||||||
|
import com.stardust.autojs.core.looper.Timer;
|
||||||
|
import com.stardust.autojs.core.looper.TimerThread;
|
||||||
import com.stardust.autojs.runtime.ScriptBridges;
|
import com.stardust.autojs.runtime.ScriptBridges;
|
||||||
|
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||||
import com.stardust.util.ArrayUtils;
|
import com.stardust.util.ArrayUtils;
|
||||||
import com.stardust.util.UiHandler;
|
import com.stardust.util.UiHandler;
|
||||||
|
|
||||||
@@ -33,12 +37,18 @@ public class JsDialogBuilder extends MaterialDialog.Builder {
|
|||||||
|
|
||||||
private final EventEmitter mEmitter;
|
private final EventEmitter mEmitter;
|
||||||
private final UiHandler mUiHandler;
|
private final UiHandler mUiHandler;
|
||||||
|
private final Timer mTimer;
|
||||||
|
private final Loopers mLoopers;
|
||||||
private JsDialog mDialog;
|
private JsDialog mDialog;
|
||||||
|
private volatile int mWaitId = -1;
|
||||||
|
|
||||||
public JsDialogBuilder(@NonNull Context context, ScriptBridges bridges, UiHandler uiHandler) {
|
|
||||||
|
public JsDialogBuilder(Context context, ScriptRuntime runtime) {
|
||||||
super(context);
|
super(context);
|
||||||
mEmitter = new EventEmitter(bridges);
|
mTimer = runtime.timers.getTimerForCurrentThread();
|
||||||
this.mUiHandler = uiHandler;
|
mLoopers = runtime.loopers;
|
||||||
|
mEmitter = new EventEmitter(runtime.bridges, mTimer);
|
||||||
|
mUiHandler = runtime.uiHandler;
|
||||||
setUpEvents();
|
setUpEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,16 +74,24 @@ public class JsDialogBuilder extends MaterialDialog.Builder {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dismissListener(dialog -> emit("dismiss", dialog));
|
dismissListener(dialog -> {
|
||||||
|
mTimer.postDelayed(() -> mLoopers.doNotWaitWhenIdle(mWaitId), 0);
|
||||||
|
emit("dismiss", dialog);
|
||||||
|
});
|
||||||
cancelListener(dialog -> emit("cancel", dialog));
|
cancelListener(dialog -> emit("cancel", dialog));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onShowCalled() {
|
||||||
|
mTimer.postDelayed(() -> mWaitId = mLoopers.waitWhenIdle(), 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public JsDialog getDialog() {
|
public JsDialog getDialog() {
|
||||||
return mDialog;
|
return mDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsDialog buildDialog() {
|
public JsDialog buildDialog() {
|
||||||
mDialog = new JsDialog(super.build(), mEmitter, mUiHandler);
|
mDialog = new JsDialog(this, mEmitter, mUiHandler);
|
||||||
return mDialog;
|
return mDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ public class ScriptRuntime {
|
|||||||
images = new Images(context, this, builder.mScreenCaptureRequester);
|
images = new Images(context, this, builder.mScreenCaptureRequester);
|
||||||
}
|
}
|
||||||
engines = new Engines(builder.mEngineService, this);
|
engines = new Engines(builder.mEngineService, this);
|
||||||
dialogs = new Dialogs(app, uiHandler, bridges);
|
dialogs = new Dialogs(this);
|
||||||
device = new Device(context);
|
device = new Device(context);
|
||||||
floaty = new Floaty(uiHandler, ui, this);
|
floaty = new Floaty(uiHandler, ui, this);
|
||||||
files = new Files(this);
|
files = new Files(this);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import com.stardust.autojs.annotation.ScriptVariable;
|
|||||||
import com.stardust.autojs.core.ui.dialog.BlockedMaterialDialog;
|
import com.stardust.autojs.core.ui.dialog.BlockedMaterialDialog;
|
||||||
import com.stardust.autojs.core.ui.dialog.JsDialogBuilder;
|
import com.stardust.autojs.core.ui.dialog.JsDialogBuilder;
|
||||||
import com.stardust.autojs.runtime.ScriptBridges;
|
import com.stardust.autojs.runtime.ScriptBridges;
|
||||||
|
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||||
import com.stardust.util.ArrayUtils;
|
import com.stardust.util.ArrayUtils;
|
||||||
import com.stardust.util.UiHandler;
|
import com.stardust.util.UiHandler;
|
||||||
|
|
||||||
@@ -23,18 +24,14 @@ import com.stardust.util.UiHandler;
|
|||||||
|
|
||||||
public class Dialogs {
|
public class Dialogs {
|
||||||
|
|
||||||
private AppUtils mAppUtils;
|
|
||||||
private UiHandler mUiHandler;
|
|
||||||
private ContextThemeWrapper mThemeWrapper;
|
private ContextThemeWrapper mThemeWrapper;
|
||||||
private ScriptBridges mScriptBridges;
|
private final ScriptRuntime mRuntime;
|
||||||
|
|
||||||
@ScriptVariable
|
@ScriptVariable
|
||||||
public final NonUiDialogs nonUiDialogs = new NonUiDialogs();
|
public final NonUiDialogs nonUiDialogs = new NonUiDialogs();
|
||||||
|
|
||||||
public Dialogs(AppUtils appUtils, UiHandler uiHandler, ScriptBridges scriptBridges) {
|
public Dialogs(ScriptRuntime runtime) {
|
||||||
mAppUtils = appUtils;
|
mRuntime = runtime;
|
||||||
mUiHandler = uiHandler;
|
|
||||||
mScriptBridges = scriptBridges;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
@@ -74,7 +71,7 @@ public class Dialogs {
|
|||||||
private Context getContext() {
|
private Context getContext() {
|
||||||
if (mThemeWrapper != null)
|
if (mThemeWrapper != null)
|
||||||
return mThemeWrapper;
|
return mThemeWrapper;
|
||||||
mThemeWrapper = new ContextThemeWrapper(mUiHandler.getContext().getApplicationContext(), R.style.Theme_AppCompat_Light);
|
mThemeWrapper = new ContextThemeWrapper(mRuntime.uiHandler.getContext().getApplicationContext(), R.style.Theme_AppCompat_Light);
|
||||||
return mThemeWrapper;
|
return mThemeWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,21 +135,21 @@ public class Dialogs {
|
|||||||
|
|
||||||
|
|
||||||
private BlockedMaterialDialog.Builder dialogBuilder(Object callback) {
|
private BlockedMaterialDialog.Builder dialogBuilder(Object callback) {
|
||||||
Context context = mAppUtils.getCurrentActivity();
|
Context context = mRuntime.app.getCurrentActivity();
|
||||||
if (context == null || ((Activity) context).isFinishing()) {
|
if (context == null || ((Activity) context).isFinishing()) {
|
||||||
context = getContext();
|
context = getContext();
|
||||||
}
|
}
|
||||||
return (BlockedMaterialDialog.Builder) new BlockedMaterialDialog.Builder(context, mUiHandler, mScriptBridges, callback)
|
return (BlockedMaterialDialog.Builder) new BlockedMaterialDialog.Builder(context, mRuntime.uiHandler, mRuntime.bridges, callback)
|
||||||
.theme(Theme.LIGHT);
|
.theme(Theme.LIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
public MaterialDialog.Builder newBuilder() {
|
public MaterialDialog.Builder newBuilder() {
|
||||||
Context context = mAppUtils.getCurrentActivity();
|
Context context = mRuntime.app.getCurrentActivity();
|
||||||
if (context == null || ((Activity) context).isFinishing()) {
|
if (context == null || ((Activity) context).isFinishing()) {
|
||||||
context = getContext();
|
context = getContext();
|
||||||
}
|
}
|
||||||
return new JsDialogBuilder(context, mScriptBridges, mUiHandler)
|
return new JsDialogBuilder(context, mRuntime)
|
||||||
.theme(Theme.LIGHT);
|
.theme(Theme.LIGHT);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class Timers {
|
|||||||
return mMaxCallbackUptimeMillisForAllThreads;
|
return mMaxCallbackUptimeMillisForAllThreads;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Timer getTimerForCurrentThread() {
|
public Timer getTimerForCurrentThread() {
|
||||||
return getTimerForThread(Thread.currentThread());
|
return getTimerForThread(Thread.currentThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user