diff --git a/autojs/src/main/assets/modules/__ui__.js b/autojs/src/main/assets/modules/__ui__.js index 794adbfa..a4827cbc 100644 --- a/autojs/src/main/assets/modules/__ui__.js +++ b/autojs/src/main/assets/modules/__ui__.js @@ -10,7 +10,9 @@ module.exports = function(__runtime__, scope){ ui.setContentView = function(view){ ui.view = view; ui.__view_cache__ = {}; - activity.setContentView(view); + ui.run(function(){ + activity.setContentView(view); + }); } ui.id = function(id){ @@ -43,12 +45,16 @@ module.exports = function(__runtime__, scope){ color = android.graphics.Color.parseColor(color); } if(android.os.Build.VERSION.SDK_INT >= 21){ - activity.getWindow().setStatusBarColor(color); + ui.run(function(){ + activity.getWindow().setStatusBarColor(color); + }); } } ui.finish = function(){ - activity.finish(); + ui.run(function(){ + activity.finish(); + }); } ui.findViewByStringId = function(view, id){ @@ -97,5 +103,7 @@ module.exports = function(__runtime__, scope){ return ui[name]; } }; + + return proxy; } \ No newline at end of file diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/ConvertLayoutInflater.java b/autojs/src/main/java/com/stardust/autojs/core/ui/ConvertLayoutInflater.java index 6aa66adf..7766828d 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/ui/ConvertLayoutInflater.java +++ b/autojs/src/main/java/com/stardust/autojs/core/ui/ConvertLayoutInflater.java @@ -11,6 +11,9 @@ import com.stardust.autojs.core.ui.widget.JsFrameLayout; import com.stardust.autojs.core.ui.xml.XmlConverter; import com.stardust.util.MapEntries; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; import java.util.Map; /** @@ -54,7 +57,6 @@ public class ConvertLayoutInflater implements JsLayoutInflater { @Override public View inflate(Context context, String xml) { - try { String androidLayoutXml = XmlConverter.convertToAndroidLayout(xml); JsFrameLayout root = new JsFrameLayout(context); diff --git a/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java index 3a44dc82..83ba5028 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java @@ -16,6 +16,12 @@ import com.stardust.util.Callback; public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine { + public interface ExecuteCallback { + void onResult(Object r); + + void onException(Exception e); + } + private Handler mHandler; private boolean mLooping = false; @@ -30,15 +36,21 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine { } - public void execute(final ScriptSource source, final Callback callback) { - Runnable r = new Runnable() { - @Override - public void run() { + public void execute(final ScriptSource source, final ExecuteCallback callback) { + Runnable r = () -> { + try { Object o = LoopBasedJavaScriptEngine.super.execute((JavaScriptSource) source); if (callback != null) - callback.call(o); - + callback.onResult(o); + } catch (Exception e) { + if (callback == null) { + throw e; + } else { + callback.onException(e); + } } + + }; mHandler.post(r); if (!mLooping && Looper.myLooper() != Looper.getMainLooper()) { @@ -56,7 +68,9 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine { @Override public synchronized void destroy() { - Loopers.quitForThread(getThread()); + Thread thread = getThread(); + if (thread != null) + Loopers.quitForThread(thread); super.destroy(); } 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 e3cc2c2d..b591d820 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java @@ -13,6 +13,7 @@ import com.stardust.automator.UiObjectCollection; import com.stardust.pio.PFiles; import com.stardust.pio.UncheckedIOException; +import org.mozilla.javascript.Callable; import org.mozilla.javascript.Context; import org.mozilla.javascript.ContextFactory; import org.mozilla.javascript.ImporterTopLevel; @@ -43,6 +44,7 @@ import java.util.Locale; public class RhinoJavaScriptEngine extends JavaScriptEngine { private static final String LOG_TAG = "RhinoJavaScriptEngine"; + private static ThreadLocal mExceptionHandlerThreadLocal = new ThreadLocal<>(); private static int contextCount = 0; private static StringScriptSource sInitScript; @@ -163,13 +165,17 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine { return context; } + public static void setUncaghtExceptionHandler(Thread.UncaughtExceptionHandler handler) { + mExceptionHandlerThreadLocal.set(handler); + } + private class WrapFactory extends org.mozilla.javascript.WrapFactory { @Override public Object wrap(Context cx, Scriptable scope, Object obj, Class staticType) { if (staticType == String.class) { return getRuntime().bridges.toString(obj); } - if (staticType == UiObjectCollection.class ) { + if (staticType == UiObjectCollection.class) { return getRuntime().bridges.toArray(obj); } @@ -196,6 +202,21 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine { cx.setInstructionObserverThreshold(10000); return cx; } + + @Override + protected Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { + Thread.UncaughtExceptionHandler exceptionHandler = mExceptionHandlerThreadLocal.get(); + if (exceptionHandler == null) + return super.doTopCall(callable, cx, scope, thisObj, args); + else { + try { + return super.doTopCall(callable, cx, scope, thisObj, args); + } catch (Exception e) { + exceptionHandler.uncaughtException(Thread.currentThread(), e); + return null; + } + } + } } 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 b7c06985..4933e4f6 100644 --- a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java +++ b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java @@ -5,16 +5,20 @@ import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; +import com.stardust.autojs.engine.LoopBasedJavaScriptEngine; +import com.stardust.autojs.engine.RhinoJavaScriptEngine; import com.stardust.autojs.engine.ScriptEngine; import com.stardust.autojs.engine.ScriptEngineManager; +import com.stardust.autojs.script.JavaScriptSource; import com.stardust.autojs.script.ScriptSource; +import com.stardust.lang.ThreadCompat; import com.stardust.util.IntentExtras; /** * Created by Stardust on 2017/2/5. */ -public class ScriptExecuteActivity extends AppCompatActivity { +public class ScriptExecuteActivity extends AppCompatActivity implements Thread.UncaughtExceptionHandler { private static final String EXTRA_EXECUTION = ScriptExecuteActivity.class.getName() + ".execution"; @@ -47,6 +51,7 @@ public class ScriptExecuteActivity extends AppCompatActivity { mScriptSource = mScriptExecution.getSource(); mScriptEngine = mScriptExecution.getEngine(); mExecutionListener = mScriptExecution.getListener(); + RhinoJavaScriptEngine.setUncaghtExceptionHandler(this); runScript(); } @@ -60,6 +65,7 @@ public class ScriptExecuteActivity extends AppCompatActivity { } } + @SuppressWarnings("unchecked") private void doExecution() { mScriptEngine.setTag(ScriptEngine.TAG_SOURCE, mScriptSource); mExecutionListener.onStart(mScriptExecution); @@ -86,6 +92,12 @@ public class ScriptExecuteActivity extends AppCompatActivity { mScriptExecution = null; } + @Override + public void uncaughtException(Thread t, Throwable e) { + mExecutionListener.onException(mScriptExecution, (Exception) e); + super.finish(); + } + private static class ActivityScriptExecution extends ScriptExecution.AbstractScriptExecution { private ScriptEngine mScriptEngine; diff --git a/autojs/src/main/java/com/stardust/autojs/rhino/AndroidContextFactory.java b/autojs/src/main/java/com/stardust/autojs/rhino/AndroidContextFactory.java index a8fb4518..25252b27 100644 --- a/autojs/src/main/java/com/stardust/autojs/rhino/AndroidContextFactory.java +++ b/autojs/src/main/java/com/stardust/autojs/rhino/AndroidContextFactory.java @@ -50,4 +50,5 @@ public class AndroidContextFactory extends ShellContextFactory { return cx; } + } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/UI.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/UI.java index 458bb0f7..488d8648 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/UI.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/UI.java @@ -51,4 +51,6 @@ public class UI extends ProxyObject { } + + } diff --git a/inrt/src/main/java/com/stardust/auojs/inrt/rt/AutoJs.java b/inrt/src/main/java/com/stardust/auojs/inrt/rt/AutoJs.java index 28663dc2..232478af 100644 --- a/inrt/src/main/java/com/stardust/auojs/inrt/rt/AutoJs.java +++ b/inrt/src/main/java/com/stardust/auojs/inrt/rt/AutoJs.java @@ -35,6 +35,7 @@ import com.stardust.util.ScreenMetrics; import com.stardust.util.Supplier; import com.stardust.util.UiHandler; import com.stardust.view.accessibility.AccessibilityInfoProvider; +import com.stardust.view.accessibility.AccessibilityNotificationObserver; import com.stardust.view.accessibility.AccessibilityService; import com.stardust.view.accessibility.AccessibilityServiceUtils; import com.stardust.view.accessibility.NotificationListener; @@ -58,7 +59,7 @@ public class AutoJs { } private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder(); - private final NotificationListener.AccessibilityNotificationObserver mNotificationObserver; + private final AccessibilityNotificationObserver mNotificationObserver; private ScriptEngineManager mScriptEngineManager; private final Context mContext; private final UiHandler mUiHandler; @@ -74,7 +75,7 @@ public class AutoJs { mUiHandler = new UiHandler(context); mAppUtils = new AppUtils(context); mGlobalConsole = new GlobalStardustConsole(mUiHandler); - mNotificationObserver = new NotificationListener.AccessibilityNotificationObserver(context); + mNotificationObserver = new AccessibilityNotificationObserver(context); mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager()); mScriptEngineService = buildScriptEngineService(); addAccessibilityServiceDelegates(); @@ -198,7 +199,7 @@ public class AutoJs { } @Override - public NotificationListener.AccessibilityNotificationObserver getNotificationObserver() { + public AccessibilityNotificationObserver getNotificationObserver() { return mNotificationObserver; }