增加 可选特性continuation

增加 协程示例
This commit is contained in:
hyb1996
2018-12-12 17:31:48 +08:00
parent 7e7a7556e8
commit 975940dced
23 changed files with 450 additions and 261 deletions

View File

@@ -16,16 +16,7 @@ runtime.init();
}
})();
//初始化不依赖环境的模块
global.JSON = require('__json2__.js');
global.util = require('__util__.js');
global.device = runtime.device;
//设置JavaScriptBridges用于与Java层的交互和数据转换
runtime.bridges.setBridges(require('__bridges__.js'));
//一些内部函数
//内部函数
global.__asGlobal__ = function (obj, functions) {
var len = functions.length;
for (var i = 0; i < len; i++) {
@@ -50,7 +41,6 @@ runtime.init();
exit(err);
} else if (err instanceof Error) {
exit(new org.mozilla.javascript.EvaluatorException(err.name + ": " + err.message, err.fileName, err.lineNumber));
//new java.lang.RuntimeException(err.name + ": " + err.message + "\n" + err.stack));
} else {
exit();
}
@@ -58,12 +48,24 @@ runtime.init();
}
};
// 初始化基础模块
global.timers = require('__timers__.js')(runtime, global);
//初始化不依赖环境的模块
global.JSON = require('__json2__.js');
global.util = require('__util__.js');
global.device = runtime.device;
global.Promise = require('promise.js');
//设置JavaScriptBridges用于与Java层的交互和数据转换
runtime.bridges.setBridges(require('__bridges__.js'));
//初始化全局函数
require("__globals__")(runtime, global);
//初始化一般模块
(function (scope) {
var modules = ['app', 'automator', 'console', 'dialogs', 'io', 'selector', 'shell', 'web', 'ui',
"images", "timers", "threads", "events", "engines", "RootAutomator", "http", "storages", "floaty",
"images", "threads", "events", "engines", "RootAutomator", "http", "storages", "floaty",
"sensors", "media", "plugins", "continuation"];
var len = modules.length;
for (var i = 0; i < len; i++) {
@@ -72,11 +74,6 @@ runtime.init();
}
})(global);
global.Promise = require('promise.js');
global.Promise.prototype.await = function () {
return continuation.await(this);
}
importClass(android.view.KeyEvent);
importClass(com.stardust.autojs.core.util.Shell);
importClass(android.graphics.Paint);

View File

@@ -44,5 +44,21 @@ module.exports = function (runtime, global) {
throw new TypeError('cannot await ' + any);
}
continuation.delay = function (millis) {
var cont = continuation.create();
setTimeout(()=>{
cont.resume();
}, millis);
cont.await();
}
continuation.__defineGetter__('enabled', function () {
return engines.myEngine().hasFeature("continuation");
});
global.Promise.prototype.await = function () {
return continuation.await(this);
}
return continuation;
}

View File

@@ -41,7 +41,7 @@ module.exports = function (runtime, scope) {
http.request = function (url, options, callback) {
var cont = null;
if (!callback && ui.isUiThread()) {
if (!callback && ui.isUiThread() && continuation.enabled) {
cont = continuation.create();
}
var call = http.client().newCall(http.buildRequest(url, options));
@@ -59,7 +59,7 @@ module.exports = function (runtime, scope) {
callback && callback(null, ex);
}
}));
if(cont) {
if (cont) {
return cont.await();
}
}

View File

@@ -65,7 +65,7 @@ module.exports = function (runtime, scope) {
if(landscape === false){
orientation = ScreenCapturer.ORIENTATION_PORTRAIT;
}
return ResultAdapter.promise(javaImages.requestScreenCapture(orientation)).await();
return ResultAdapter.wait(javaImages.requestScreenCapture(orientation));
}
images.save = function (img, path, format, quality) {

View File

@@ -1,12 +1,26 @@
module.exports = function(__runtime__, scope){
var threads = Object.create(__runtime__.threads);
module.exports = function (__runtime__, scope) {
var threads = Object.create(__runtime__.threads);
scope.sync = function(func, lock){
scope.sync = function (func, lock) {
lock = lock || null;
return new org.mozilla.javascript.Synchronizer(func, lock);
}
}
return threads;
global.Promise.prototype.wait = function () {
var disposable = threads.disposable();
promise.then(result => {
disposable.setAndNotify({ result: result });
}).catch(error => {
cont.resumeError({ error: error });
});
var r = cont.blockedGet();
if (r.error) {
throw r.error;
}
return r.result;
}
return threads;
}

View File

@@ -47,7 +47,7 @@ ResultAdapter.prototype.setError = function (error) {
ResultAdapter.prototype.callback = function () {
var that = this;
return function (result, error) {
if(that.result !== undefined){
if (that.result !== undefined) {
that.result = {
result: result,
error: error
@@ -63,21 +63,33 @@ ResultAdapter.prototype.callback = function () {
}
ResultAdapter.prototype.get = function () {
if(this.result){
if (this.result) {
return getOrThrow(this.result);
}
this.result = null;
return this.impl.get();
}
ResultAdapter.promise = function(promiseAdapter) {
return new Promise(function(resolve, reject){
promiseAdapter.onResolve(function(result) {
ResultAdapter.promise = function (promiseAdapter) {
return new Promise(function (resolve, reject) {
promiseAdapter.onResolve(function (result) {
resolve(result);
}).onReject(function(error){
}).onReject(function (error) {
reject(error);
});
})
}
ResultAdapter.wait = function (promise) {
var proto = Object.getPrototypeOf(promise);
if (!proto || proto.constructor !== Promise) {
promise = ResultAdapter.promise(promise);
}
if (continuation.enabled) {
return promise.await();
} else {
return promise.wait();
}
}
module.exports = ResultAdapter;

View File

@@ -63,7 +63,6 @@ public class BlockedMaterialDialog extends MaterialDialog {
private VolatileDispose<Object> mResultBox;
private UiHandler mUiHandler;
private Object mCallback;
private Continuation mContinuation;
private ScriptBridges mScriptBridges;
private boolean mNotified = false;
@@ -75,10 +74,6 @@ public class BlockedMaterialDialog extends MaterialDialog {
mCallback = callback;
if (Looper.getMainLooper() != Looper.myLooper()) {
mResultBox = new VolatileDispose<>();
} else {
if (mCallback == null) {
mContinuation = runtime.createContinuation();
}
}
}
@@ -96,9 +91,6 @@ public class BlockedMaterialDialog extends MaterialDialog {
if (mCallback != null) {
mScriptBridges.callFunction(mCallback, null, new Object[]{r});
}
if (mContinuation != null) {
mContinuation.resumeWith(Continuation.Result.Companion.success(r));
}
if (mResultBox != null) {
mResultBox.setAndNotify(r);
}
@@ -179,9 +171,6 @@ public class BlockedMaterialDialog extends MaterialDialog {
} else {
mUiHandler.post(Builder.super::show);
}
if (mContinuation != null) {
mContinuation.suspend();
}
if (mResultBox != null) {
return mResultBox.blockedGetOrThrow(ScriptInterruptedException.class);
} else {

View File

@@ -46,8 +46,7 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
Object o = LoopBasedJavaScriptEngine.super.execute((JavaScriptSource) source);
if (callback != null)
callback.onResult(o);
} catch (ContinuationPending pending) {
pending.printStackTrace();
} catch (ContinuationPending ignored) {
} catch (Exception e) {
if (callback == null) {
throw e;
@@ -61,8 +60,17 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
mHandler.post(r);
if (!mLooping && Looper.myLooper() != Looper.getMainLooper()) {
mLooping = true;
Looper.loop();
mLooping = false;
while (true) {
try {
Looper.loop();
} catch (ContinuationPending ignored) {
continue;
} catch (Throwable t) {
mLooping = false;
throw t;
}
break;
}
}
}
@@ -79,8 +87,7 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
@Override
public synchronized void destroy() {
Thread thread = getThread();
if (thread != null)
LooperHelper.quitForThread(thread);
LooperHelper.quitForThread(thread);
super.destroy();
}

View File

@@ -1,197 +0,0 @@
package com.stardust.autojs.engine;
import android.util.Log;
import android.view.View;
import com.stardust.autojs.BuildConfig;
import com.stardust.autojs.core.ui.ViewExtras;
import com.stardust.autojs.engine.module.AssetAndUrlModuleSourceProvider;
import com.stardust.autojs.rhino.RhinoAndroidHelper;
import com.stardust.autojs.rhino.TopLevelScope;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.automator.UiObjectCollection;
import com.stardust.pio.UncheckedIOException;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.commonjs.module.RequireBuilder;
import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Collections;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by Stardust on 2017/4/2.
*/
public class RhinoJavaScriptEngine extends JavaScriptEngine {
public static final String SOURCE_NAME_INIT = "<init>";
private static final String LOG_TAG = "RhinoJavaScriptEngine";
private static final String MODULES_PATH = "modules";
private static Script sInitScript;
private static final ConcurrentHashMap<Context, RhinoJavaScriptEngine> sContextEngineMap = new ConcurrentHashMap<>();
private Context mContext;
private TopLevelScope mScriptable;
private Thread mThread;
private android.content.Context mAndroidContext;
public RhinoJavaScriptEngine(android.content.Context context) {
mAndroidContext = context;
mContext = enterContext();
mScriptable = createScope(mContext);
}
@Override
public void put(String name, Object value) {
ScriptableObject.putProperty(mScriptable, name, Context.javaToJS(value, mScriptable));
}
@Override
public void setRuntime(ScriptRuntime runtime) {
super.setRuntime(runtime);
runtime.setTopLevelScope(mScriptable);
}
@Override
public Object doExecution(JavaScriptSource source) {
Reader reader = source.getNonNullScriptReader();
try {
reader = preprocess(reader);
Script script = mContext.compileReader(reader, source.toString(), 1, null);
return mContext.executeScriptWithContinuations(script, mScriptable);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
protected Reader preprocess(Reader script) throws IOException {
return script;
}
@Override
public void forceStop() {
Log.d(LOG_TAG, "forceStop: interrupt Thread: " + mThread);
mThread.interrupt();
}
@Override
public synchronized void destroy() {
super.destroy();
Log.d(LOG_TAG, "on destroy");
sContextEngineMap.remove(getContext());
Context.exit();
}
public Thread getThread() {
return mThread;
}
@SuppressWarnings("unchecked")
@Override
public void init() {
mThread = Thread.currentThread();
ScriptableObject.putProperty(mScriptable, "__engine__", this);
initRequireBuilder(mContext, mScriptable);
mContext.executeScriptWithContinuations(getInitScript(), mScriptable);
}
private Script getInitScript() {
if (sInitScript == null || BuildConfig.DEBUG) {
try {
Reader reader = new InputStreamReader(mAndroidContext.getAssets().open("init.js"));
sInitScript = mContext.compileReader(reader, SOURCE_NAME_INIT, 1, null);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
return sInitScript;
}
void initRequireBuilder(Context context, Scriptable scope) {
AssetAndUrlModuleSourceProvider provider = new AssetAndUrlModuleSourceProvider(mAndroidContext, MODULES_PATH,
Collections.singletonList(new File("/").toURI()));
new RequireBuilder()
.setModuleScriptProvider(new SoftCachingModuleScriptProvider(provider))
.setSandboxed(true)
.createRequire(context, scope)
.install(scope);
}
public Context getContext() {
return mContext;
}
public Scriptable getScriptable() {
return mScriptable;
}
protected TopLevelScope createScope(Context context) {
TopLevelScope topLevelScope = new TopLevelScope();
topLevelScope.initStandardObjects(context, false);
return topLevelScope;
}
public Context enterContext() {
Context context = new RhinoAndroidHelper(mAndroidContext).enterContext();
setupContext(context);
sContextEngineMap.put(context, this);
return context;
}
protected void setupContext(Context context) {
context.setOptimizationLevel(-1);
context.setLanguageVersion(Context.VERSION_ES6);
context.setLocale(Locale.getDefault());
context.setWrapFactory(new WrapFactory());
}
public static RhinoJavaScriptEngine getEngineOfContext(Context context) {
return sContextEngineMap.get(context);
}
private class WrapFactory extends org.mozilla.javascript.WrapFactory {
@Override
public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {
Object result;
if (obj instanceof String) {
result = getRuntime().bridges.toString(obj.toString());
} else if (staticType == UiObjectCollection.class) {
result = getRuntime().bridges.asArray(obj);
} else {
result = super.wrap(cx, scope, obj, staticType);
}
return result;
}
@Override
public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class<?> staticType) {
Scriptable result;
if (javaObject instanceof View) {
result = ViewExtras.getNativeView(scope, (View) javaObject, staticType, getRuntime());
} else {
result = super.wrapAsJavaObject(cx, scope, javaObject, staticType);
}
//Log.d(LOG_TAG, "wrapAsJavaObject: java = " + javaObject + ", result = " + result + ", scope = " + scope);
return result;
}
}
}

View File

@@ -0,0 +1,191 @@
package com.stardust.autojs.engine
import android.util.Log
import android.view.View
import com.stardust.autojs.BuildConfig
import com.stardust.autojs.core.ui.ViewExtras
import com.stardust.autojs.engine.module.AssetAndUrlModuleSourceProvider
import com.stardust.autojs.execution.ExecutionConfig
import com.stardust.autojs.project.ScriptConfig
import com.stardust.autojs.rhino.RhinoAndroidHelper
import com.stardust.autojs.rhino.TopLevelScope
import com.stardust.autojs.runtime.ScriptRuntime
import com.stardust.autojs.script.JavaScriptSource
import com.stardust.automator.UiObjectCollection
import com.stardust.pio.UncheckedIOException
import org.mozilla.javascript.Context
import org.mozilla.javascript.Script
import org.mozilla.javascript.Scriptable
import org.mozilla.javascript.ScriptableObject
import org.mozilla.javascript.commonjs.module.RequireBuilder
import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider
import java.io.File
import java.io.IOException
import java.io.InputStreamReader
import java.io.Reader
import java.net.URI
import java.util.Locale
import java.util.concurrent.ConcurrentHashMap
/**
* Created by Stardust on 2017/4/2.
*/
open class RhinoJavaScriptEngine(private val mAndroidContext: android.content.Context) : JavaScriptEngine() {
val context: Context
private val mScriptable: TopLevelScope
lateinit var thread: Thread
private set
private val initScript: Script
get() {
return sInitScript ?: {
try {
val reader = InputStreamReader(mAndroidContext.assets.open("init.js"))
val script = context.compileReader(reader, SOURCE_NAME_INIT, 1, null)
sInitScript = script
script
} catch (e: IOException) {
throw UncheckedIOException(e)
}
}()
}
val scriptable: Scriptable
get() = mScriptable
init {
this.context = enterContext()
mScriptable = createScope(this.context)
}
override fun put(name: String, value: Any?) {
ScriptableObject.putProperty(mScriptable, name, Context.javaToJS(value, mScriptable))
}
override fun setRuntime(runtime: ScriptRuntime) {
super.setRuntime(runtime)
runtime.topLevelScope = mScriptable
}
public override fun doExecution(source: JavaScriptSource): Any {
var reader = source.nonNullScriptReader
try {
reader = preprocess(reader)
val script = context.compileReader(reader, source.toString(), 1, null)
return if (hasFeature(ScriptConfig.FEATURE_CONTINUATION)) {
context.executeScriptWithContinuations(script, mScriptable)
} else {
script.exec(context, mScriptable)
}
} catch (e: IOException) {
throw UncheckedIOException(e)
}
}
fun hasFeature(feature: String): Boolean {
val config = getTag(ExecutionConfig.tag) as ExecutionConfig?
return config != null && config.scriptConfig.hasFeature(feature)
}
@Throws(IOException::class)
protected fun preprocess(script: Reader): Reader {
return script
}
override fun forceStop() {
Log.d(LOG_TAG, "forceStop: interrupt Thread: $thread")
thread.interrupt()
}
@Synchronized
override fun destroy() {
super.destroy()
Log.d(LOG_TAG, "on destroy")
sContextEngineMap.remove(context)
Context.exit()
}
override fun init() {
thread = Thread.currentThread()
ScriptableObject.putProperty(mScriptable, "__engine__", this)
initRequireBuilder(context, mScriptable)
context.executeScriptWithContinuations(initScript, mScriptable)
}
internal fun initRequireBuilder(context: Context, scope: Scriptable) {
val provider = AssetAndUrlModuleSourceProvider(mAndroidContext, MODULES_PATH,
listOf<URI>(File("/").toURI()))
RequireBuilder()
.setModuleScriptProvider(SoftCachingModuleScriptProvider(provider))
.setSandboxed(true)
.createRequire(context, scope)
.install(scope)
}
protected fun createScope(context: Context): TopLevelScope {
val topLevelScope = TopLevelScope()
topLevelScope.initStandardObjects(context, false)
return topLevelScope
}
fun enterContext(): Context {
val context = RhinoAndroidHelper(mAndroidContext).enterContext()
setupContext(context)
sContextEngineMap[context] = this
return context
}
protected fun setupContext(context: Context) {
context.optimizationLevel = -1
context.languageVersion = Context.VERSION_ES6
context.locale = Locale.getDefault()
context.wrapFactory = WrapFactory()
}
private inner class WrapFactory : org.mozilla.javascript.WrapFactory() {
override fun wrap(cx: Context, scope: Scriptable, obj: Any?, staticType: Class<*>?): Any? {
return when {
obj is String -> runtime.bridges.toString(obj.toString())
staticType == UiObjectCollection::class.java -> runtime.bridges.asArray(obj)
else -> super.wrap(cx, scope, obj, staticType)
}
}
override fun wrapAsJavaObject(cx: Context?, scope: Scriptable, javaObject: Any?, staticType: Class<*>?): Scriptable? {
//Log.d(LOG_TAG, "wrapAsJavaObject: java = " + javaObject + ", result = " + result + ", scope = " + scope);
return if (javaObject is View) {
ViewExtras.getNativeView(scope, javaObject, staticType, runtime)
} else {
super.wrapAsJavaObject(cx, scope, javaObject, staticType)
}
}
}
companion object {
val SOURCE_NAME_INIT = "<init>"
private val LOG_TAG = "RhinoJavaScriptEngine"
private val MODULES_PATH = "modules"
private var sInitScript: Script? = null
private val sContextEngineMap = ConcurrentHashMap<Context, RhinoJavaScriptEngine>()
fun getEngineOfContext(context: Context): RhinoJavaScriptEngine? {
return sContextEngineMap[context]
}
}
}

View File

@@ -2,6 +2,7 @@ package com.stardust.autojs.execution
import android.os.Parcel
import android.os.Parcelable
import com.stardust.autojs.project.ScriptConfig
import java.util.*
/**
@@ -13,8 +14,7 @@ data class ExecutionConfig(var workingDirectory: String = "",
var delay: Long = 0,
var interval: Long = 0,
var loopTimes: Int = 1,
var uiMode: Boolean = false,
var features: Int = 0) : Parcelable {
var scriptConfig: ScriptConfig = ScriptConfig()) : Parcelable {
private val mArguments = HashMap<String, Any>()
@@ -88,9 +88,6 @@ data class ExecutionConfig(var workingDirectory: String = "",
val default: ExecutionConfig
get() = ExecutionConfig()
@JvmStatic
val featureContinuation = 1
override fun createFromParcel(parcel: Parcel): ExecutionConfig {
return ExecutionConfig(parcel)
}

View File

@@ -8,13 +8,14 @@ import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.autojs.script.ScriptSource;
import com.stardust.lang.ThreadCompat;
import org.mozilla.javascript.ContinuationPending;
/**
* Created by Stardust on 2017/5/1.
*/
public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecution implements Runnable {
private static final String TAG = "RunnableJSExecution";
private ScriptEngine mScriptEngine;
private ScriptEngineManager mScriptEngineManager;

View File

@@ -18,4 +18,5 @@ public class LaunchConfig {
public void setHideLogs(boolean hideLogs) {
mHideLogs = hideLogs;
}
}

View File

@@ -1,7 +1,6 @@
package com.stardust.autojs.project;
import android.content.Context;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import com.google.gson.Gson;
@@ -12,7 +11,9 @@ import com.stardust.pio.PFiles;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Stardust on 2018/1/24.
@@ -51,31 +52,38 @@ public class ProjectConfig {
@SerializedName("icon")
private String mIcon;
@SerializedName("scripts")
private Map<String, ScriptConfig> mScriptConfigs = new HashMap<>();
@SerializedName("useFeatures")
private List<String> mFeatures = new ArrayList<>();
public static ProjectConfig fromJson(String json) {
if (json == null) {
return null;
}
ProjectConfig config = GSON.fromJson(json, ProjectConfig.class);
if(!isValid(config)){
if (!isValid(config)) {
return null;
}
return config;
}
private static boolean isValid(ProjectConfig config) {
if(TextUtils.isEmpty(config.getName())){
if (TextUtils.isEmpty(config.getName())) {
return false;
}
if(TextUtils.isEmpty(config.getPackageName())){
if (TextUtils.isEmpty(config.getPackageName())) {
return false;
}
if(TextUtils.isEmpty(config.getVersionName())){
if (TextUtils.isEmpty(config.getVersionName())) {
return false;
}
if(TextUtils.isEmpty(config.getMainScriptFile())){
if (TextUtils.isEmpty(config.getMainScriptFile())) {
return false;
}
if(config.getVersionCode() == -1){
if (config.getVersionCode() == -1) {
return false;
}
return true;
@@ -160,6 +168,10 @@ public class ProjectConfig {
return this;
}
public Map<String, ScriptConfig> getScriptConfigs() {
return mScriptConfigs;
}
public List<String> getAssets() {
if (mAssets == null) {
mAssets = Collections.emptyList();
@@ -210,4 +222,30 @@ public class ProjectConfig {
public String getBuildDir() {
return "build";
}
public List<String> getFeatures() {
return mFeatures;
}
public void setFeatures(List<String> features) {
mFeatures = features;
}
public ScriptConfig getScriptConfig(String path) {
ScriptConfig config = mScriptConfigs.get(path);
if (config == null) {
config = new ScriptConfig();
}
if(mFeatures.isEmpty()){
return config;
}
ArrayList<String> features = new ArrayList<>(config.getFeatures());
for (String feature : mFeatures) {
if (!features.contains(feature)) {
features.add(feature);
}
}
config.setFeatures(features);
return config;
}
}

View File

@@ -18,9 +18,10 @@ public class ProjectLauncher {
mMainScriptFile = new File(mProjectDir, mProjectConfig.getMainScriptFile());
}
public void launch(ScriptEngineService service){
public void launch(ScriptEngineService service) {
ExecutionConfig config = new ExecutionConfig();
config.setWorkingDirectory(mProjectDir);
config.getScriptConfig().setFeatures(mProjectConfig.getFeatures());
service.execute(new JavaScriptFileSource(mMainScriptFile), config);
}

View File

@@ -0,0 +1,18 @@
package com.stardust.autojs.project
import com.google.gson.annotations.SerializedName
data class ScriptConfig(
@SerializedName("useFeatures") var features: List<String>,
@SerializedName("uiMode") var uiMode: Boolean
) {
constructor() : this(emptyList(), false)
fun hasFeature(feature: String): Boolean {
return features.contains(feature)
}
companion object {
val FEATURE_CONTINUATION = "continuation"
}
}

View File

@@ -65,7 +65,7 @@ public class Dialogs {
builder.content(content);
}
return ((BlockedMaterialDialog.Builder) builder).showAndGet();
}
}
private Context getContext() {
if (mThemeWrapper != null)

View File

@@ -23,7 +23,7 @@ public class VMBridge_custom extends VMBridge_jdk15 {
protected Object newInterfaceProxy(Object proxyHelper, ContextFactory cf, InterfaceAdapter adapter, Object target, Scriptable topScope) {
Context context = Context.getCurrentContext();
InterfaceAdapterWrapper adapterWrapper = new InterfaceAdapterWrapper(adapter, context);
RhinoJavaScriptEngine engine = RhinoJavaScriptEngine.getEngineOfContext(context);
RhinoJavaScriptEngine engine = RhinoJavaScriptEngine.Companion.getEngineOfContext(context);
// --- The following code is copied from super class --
Constructor<?> c = (Constructor) proxyHelper;
InvocationHandler handler = (proxy, method, args) -> {
@@ -50,6 +50,8 @@ public class VMBridge_custom extends VMBridge_jdk15 {
try {
Object result = adapterWrapper.invoke(cf, target, topScope, proxy, method, args);
return castReturnValue(method, result);
} catch (ContinuationPending pending) {
return defaultValue(method.getReturnType());
} catch (Throwable e) {
e.printStackTrace();
// notify the script thread to exit
@@ -143,6 +145,7 @@ public class VMBridge_custom extends VMBridge_jdk15 {
public Object invokeImpl(Context cx, Object target, Scriptable topScope, Object thisObject, Method method, Object[] args) {
cx.isContinuationsTopCall = true;
return mInterfaceAdapter.invokeImpl(cx, target, topScope, thisObject, method, args);
}
}