diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java index 49bfa37e..566448be 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java @@ -1,9 +1,10 @@ package com.stardust.autojs.engine; +import android.os.Looper; import android.util.Log; -import android.widget.TextView; import com.stardust.autojs.BuildConfig; +import com.stardust.autojs.execution.ScriptExecutionListener; import com.stardust.autojs.rhino.AndroidContextFactory; import com.stardust.autojs.rhino.RhinoAndroidHelper; import com.stardust.autojs.runtime.exception.ScriptInterruptedException; @@ -34,10 +35,9 @@ import java.util.Locale; * Created by Stardust on 2017/4/2. */ -public class RhinoJavaScriptEngine extends JavaScriptEngine { +public class RhinoJavaScriptEngine extends JavaScriptEngine { private static final String LOG_TAG = "RhinoJavaScriptEngine"; - private static ThreadLocal sExceptionHandlerThreadLocal = new ThreadLocal<>(); private static int contextCount = 0; private static StringScriptSource sInitScript; @@ -47,6 +47,7 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine { private Scriptable mScriptable; private Thread mThread; private android.content.Context mAndroidContext; + private Thread.UncaughtExceptionHandler mUiThreadExceptionHandler; public RhinoJavaScriptEngine(android.content.Context context) { mAndroidContext = context; @@ -147,23 +148,28 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine { } public Context createContext() { - if (!ContextFactory.hasExplicitGlobal()) { - ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mAndroidContext.getCacheDir(), "classes"))); - } - Context context = new RhinoAndroidHelper(mAndroidContext).enterContext(); + // if (!ContextFactory.hasExplicitGlobal()) { + // ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mAndroidContext.getCacheDir(), "classes"))); + //} + Context context = new InterruptibleAndroidContextFactory(new File(mAndroidContext.getCacheDir(), "classes")).enterContext();//new RhinoAndroidHelper(mAndroidContext).enterContext(); contextCount++; + setupContext(context); + return context; + } + + protected void setupContext(Context context) { context.setOptimizationLevel(-1); context.setLanguageVersion(Context.VERSION_ES6); context.setLocale(Locale.getDefault()); context.setWrapFactory(new WrapFactory()); - return context; } - public static void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler) { - sExceptionHandlerThreadLocal.set(handler); + public void setUiThreadExceptionHandler(Thread.UncaughtExceptionHandler uiThreadExceptionHandler) { + mUiThreadExceptionHandler = uiThreadExceptionHandler; } private class WrapFactory extends org.mozilla.javascript.WrapFactory { + @Override public Object wrap(Context cx, Scriptable scope, Object obj, Class staticType) { if (obj instanceof String) { @@ -175,14 +181,16 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine { } return super.wrap(cx, scope, obj, staticType); } + } - private static class InterruptibleAndroidContextFactory extends AndroidContextFactory { + private class InterruptibleAndroidContextFactory extends AndroidContextFactory { public InterruptibleAndroidContextFactory(File cacheDirectory) { super(cacheDirectory); } + @Override protected void observeInstructionCount(Context cx, int instructionCount) { if (Thread.currentThread().isInterrupted()) { @@ -199,17 +207,15 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine { @Override protected Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { - Thread.UncaughtExceptionHandler exceptionHandler = sExceptionHandlerThreadLocal.get(); - if (exceptionHandler == null) - return super.doTopCall(callable, cx, scope, thisObj, args); - else { + if (Looper.myLooper() == Looper.getMainLooper()) { try { return super.doTopCall(callable, cx, scope, thisObj, args); } catch (Exception e) { - exceptionHandler.uncaughtException(Thread.currentThread(), e); + mUiThreadExceptionHandler.uncaughtException(Thread.currentThread(), e); return null; } } + return super.doTopCall(callable, cx, scope, thisObj, args); } } diff --git a/autojs/src/main/java/com/stardust/autojs/execution/LoopedBasedJavaScriptExecution.java b/autojs/src/main/java/com/stardust/autojs/execution/LoopedBasedJavaScriptExecution.java index dc8f4894..d9cacf31 100644 --- a/autojs/src/main/java/com/stardust/autojs/execution/LoopedBasedJavaScriptExecution.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/LoopedBasedJavaScriptExecution.java @@ -23,6 +23,10 @@ public class LoopedBasedJavaScriptExecution extends RunnableScriptExecution { long delay = getConfig().delay; sleep(delay); final LoopBasedJavaScriptEngine javaScriptEngine = (LoopBasedJavaScriptEngine) engine; + javaScriptEngine.setUiThreadExceptionHandler((t, e) -> { + javaScriptEngine.forceStop(); + getListener().onException(this, (Exception) e); + }); final long interval = getConfig().interval; javaScriptEngine.getRuntime().loopers.setMainLooperQuitHandler(new Loopers.LooperQuitHandler() { long times = getConfig().loopTimes == 0 ? Integer.MAX_VALUE : getConfig().loopTimes; diff --git a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java index a812fda6..a0caafc6 100644 --- a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java @@ -49,7 +49,7 @@ public class ScriptExecuteActivity extends AppCompatActivity implements Thread.U mScriptSource = mScriptExecution.getSource(); mScriptEngine = mScriptExecution.getEngine(); mExecutionListener = mScriptExecution.getListener(); - RhinoJavaScriptEngine.setUncaughtExceptionHandler(this); + ((RhinoJavaScriptEngine) mScriptEngine).setUiThreadExceptionHandler((t, e) -> onException((Exception) e)); runScript(); } @@ -119,6 +119,7 @@ public class ScriptExecuteActivity extends AppCompatActivity implements Thread.U mScriptEngineManager = manager; } + @Override public ScriptEngine getEngine() { if (mScriptEngine == null) {