fix: app crash when ui script throws exception
This commit is contained in:
@@ -10,7 +10,9 @@ module.exports = function(__runtime__, scope){
|
|||||||
ui.setContentView = function(view){
|
ui.setContentView = function(view){
|
||||||
ui.view = view;
|
ui.view = view;
|
||||||
ui.__view_cache__ = {};
|
ui.__view_cache__ = {};
|
||||||
|
ui.run(function(){
|
||||||
activity.setContentView(view);
|
activity.setContentView(view);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.id = function(id){
|
ui.id = function(id){
|
||||||
@@ -43,12 +45,16 @@ module.exports = function(__runtime__, scope){
|
|||||||
color = android.graphics.Color.parseColor(color);
|
color = android.graphics.Color.parseColor(color);
|
||||||
}
|
}
|
||||||
if(android.os.Build.VERSION.SDK_INT >= 21){
|
if(android.os.Build.VERSION.SDK_INT >= 21){
|
||||||
|
ui.run(function(){
|
||||||
activity.getWindow().setStatusBarColor(color);
|
activity.getWindow().setStatusBarColor(color);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.finish = function(){
|
ui.finish = function(){
|
||||||
|
ui.run(function(){
|
||||||
activity.finish();
|
activity.finish();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.findViewByStringId = function(view, id){
|
ui.findViewByStringId = function(view, id){
|
||||||
@@ -97,5 +103,7 @@ module.exports = function(__runtime__, scope){
|
|||||||
return ui[name];
|
return ui[name];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,9 @@ import com.stardust.autojs.core.ui.widget.JsFrameLayout;
|
|||||||
import com.stardust.autojs.core.ui.xml.XmlConverter;
|
import com.stardust.autojs.core.ui.xml.XmlConverter;
|
||||||
import com.stardust.util.MapEntries;
|
import com.stardust.util.MapEntries;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,7 +57,6 @@ public class ConvertLayoutInflater implements JsLayoutInflater {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View inflate(Context context, String xml) {
|
public View inflate(Context context, String xml) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String androidLayoutXml = XmlConverter.convertToAndroidLayout(xml);
|
String androidLayoutXml = XmlConverter.convertToAndroidLayout(xml);
|
||||||
JsFrameLayout root = new JsFrameLayout(context);
|
JsFrameLayout root = new JsFrameLayout(context);
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ import com.stardust.util.Callback;
|
|||||||
|
|
||||||
public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
|
public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
|
||||||
|
|
||||||
|
public interface ExecuteCallback {
|
||||||
|
void onResult(Object r);
|
||||||
|
|
||||||
|
void onException(Exception e);
|
||||||
|
}
|
||||||
|
|
||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
private boolean mLooping = false;
|
private boolean mLooping = false;
|
||||||
|
|
||||||
@@ -30,15 +36,21 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void execute(final ScriptSource source, final Callback<Object> callback) {
|
public void execute(final ScriptSource source, final ExecuteCallback callback) {
|
||||||
Runnable r = new Runnable() {
|
Runnable r = () -> {
|
||||||
@Override
|
try {
|
||||||
public void run() {
|
|
||||||
Object o = LoopBasedJavaScriptEngine.super.execute((JavaScriptSource) source);
|
Object o = LoopBasedJavaScriptEngine.super.execute((JavaScriptSource) source);
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.call(o);
|
callback.onResult(o);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (callback == null) {
|
||||||
|
throw e;
|
||||||
|
} else {
|
||||||
|
callback.onException(e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
mHandler.post(r);
|
mHandler.post(r);
|
||||||
if (!mLooping && Looper.myLooper() != Looper.getMainLooper()) {
|
if (!mLooping && Looper.myLooper() != Looper.getMainLooper()) {
|
||||||
@@ -56,7 +68,9 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void destroy() {
|
public synchronized void destroy() {
|
||||||
Loopers.quitForThread(getThread());
|
Thread thread = getThread();
|
||||||
|
if (thread != null)
|
||||||
|
Loopers.quitForThread(thread);
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.stardust.automator.UiObjectCollection;
|
|||||||
import com.stardust.pio.PFiles;
|
import com.stardust.pio.PFiles;
|
||||||
import com.stardust.pio.UncheckedIOException;
|
import com.stardust.pio.UncheckedIOException;
|
||||||
|
|
||||||
|
import org.mozilla.javascript.Callable;
|
||||||
import org.mozilla.javascript.Context;
|
import org.mozilla.javascript.Context;
|
||||||
import org.mozilla.javascript.ContextFactory;
|
import org.mozilla.javascript.ContextFactory;
|
||||||
import org.mozilla.javascript.ImporterTopLevel;
|
import org.mozilla.javascript.ImporterTopLevel;
|
||||||
@@ -43,6 +44,7 @@ import java.util.Locale;
|
|||||||
public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||||
|
|
||||||
private static final String LOG_TAG = "RhinoJavaScriptEngine";
|
private static final String LOG_TAG = "RhinoJavaScriptEngine";
|
||||||
|
private static ThreadLocal<Thread.UncaughtExceptionHandler> mExceptionHandlerThreadLocal = new ThreadLocal<>();
|
||||||
|
|
||||||
private static int contextCount = 0;
|
private static int contextCount = 0;
|
||||||
private static StringScriptSource sInitScript;
|
private static StringScriptSource sInitScript;
|
||||||
@@ -163,6 +165,10 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setUncaghtExceptionHandler(Thread.UncaughtExceptionHandler handler) {
|
||||||
|
mExceptionHandlerThreadLocal.set(handler);
|
||||||
|
}
|
||||||
|
|
||||||
private class WrapFactory extends org.mozilla.javascript.WrapFactory {
|
private class WrapFactory extends org.mozilla.javascript.WrapFactory {
|
||||||
@Override
|
@Override
|
||||||
public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {
|
public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {
|
||||||
@@ -196,6 +202,21 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
|||||||
cx.setInstructionObserverThreshold(10000);
|
cx.setInstructionObserverThreshold(10000);
|
||||||
return cx;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,16 +5,20 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
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.ScriptEngine;
|
||||||
import com.stardust.autojs.engine.ScriptEngineManager;
|
import com.stardust.autojs.engine.ScriptEngineManager;
|
||||||
|
import com.stardust.autojs.script.JavaScriptSource;
|
||||||
import com.stardust.autojs.script.ScriptSource;
|
import com.stardust.autojs.script.ScriptSource;
|
||||||
|
import com.stardust.lang.ThreadCompat;
|
||||||
import com.stardust.util.IntentExtras;
|
import com.stardust.util.IntentExtras;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/2/5.
|
* 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";
|
private static final String EXTRA_EXECUTION = ScriptExecuteActivity.class.getName() + ".execution";
|
||||||
@@ -47,6 +51,7 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
|||||||
mScriptSource = mScriptExecution.getSource();
|
mScriptSource = mScriptExecution.getSource();
|
||||||
mScriptEngine = mScriptExecution.getEngine();
|
mScriptEngine = mScriptExecution.getEngine();
|
||||||
mExecutionListener = mScriptExecution.getListener();
|
mExecutionListener = mScriptExecution.getListener();
|
||||||
|
RhinoJavaScriptEngine.setUncaghtExceptionHandler(this);
|
||||||
runScript();
|
runScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,6 +65,7 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private void doExecution() {
|
private void doExecution() {
|
||||||
mScriptEngine.setTag(ScriptEngine.TAG_SOURCE, mScriptSource);
|
mScriptEngine.setTag(ScriptEngine.TAG_SOURCE, mScriptSource);
|
||||||
mExecutionListener.onStart(mScriptExecution);
|
mExecutionListener.onStart(mScriptExecution);
|
||||||
@@ -86,6 +92,12 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
|||||||
mScriptExecution = null;
|
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 static class ActivityScriptExecution extends ScriptExecution.AbstractScriptExecution {
|
||||||
|
|
||||||
private ScriptEngine mScriptEngine;
|
private ScriptEngine mScriptEngine;
|
||||||
|
|||||||
@@ -50,4 +50,5 @@ public class AndroidContextFactory extends ShellContextFactory {
|
|||||||
return cx;
|
return cx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,4 +51,6 @@ public class UI extends ProxyObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import com.stardust.util.ScreenMetrics;
|
|||||||
import com.stardust.util.Supplier;
|
import com.stardust.util.Supplier;
|
||||||
import com.stardust.util.UiHandler;
|
import com.stardust.util.UiHandler;
|
||||||
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
||||||
|
import com.stardust.view.accessibility.AccessibilityNotificationObserver;
|
||||||
import com.stardust.view.accessibility.AccessibilityService;
|
import com.stardust.view.accessibility.AccessibilityService;
|
||||||
import com.stardust.view.accessibility.AccessibilityServiceUtils;
|
import com.stardust.view.accessibility.AccessibilityServiceUtils;
|
||||||
import com.stardust.view.accessibility.NotificationListener;
|
import com.stardust.view.accessibility.NotificationListener;
|
||||||
@@ -58,7 +59,7 @@ public class AutoJs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
|
private final AccessibilityActionRecorder mAccessibilityActionRecorder = new AccessibilityActionRecorder();
|
||||||
private final NotificationListener.AccessibilityNotificationObserver mNotificationObserver;
|
private final AccessibilityNotificationObserver mNotificationObserver;
|
||||||
private ScriptEngineManager mScriptEngineManager;
|
private ScriptEngineManager mScriptEngineManager;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final UiHandler mUiHandler;
|
private final UiHandler mUiHandler;
|
||||||
@@ -74,7 +75,7 @@ public class AutoJs {
|
|||||||
mUiHandler = new UiHandler(context);
|
mUiHandler = new UiHandler(context);
|
||||||
mAppUtils = new AppUtils(context);
|
mAppUtils = new AppUtils(context);
|
||||||
mGlobalConsole = new GlobalStardustConsole(mUiHandler);
|
mGlobalConsole = new GlobalStardustConsole(mUiHandler);
|
||||||
mNotificationObserver = new NotificationListener.AccessibilityNotificationObserver(context);
|
mNotificationObserver = new AccessibilityNotificationObserver(context);
|
||||||
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
|
mAccessibilityInfoProvider = new AccessibilityInfoProvider(context.getPackageManager());
|
||||||
mScriptEngineService = buildScriptEngineService();
|
mScriptEngineService = buildScriptEngineService();
|
||||||
addAccessibilityServiceDelegates();
|
addAccessibilityServiceDelegates();
|
||||||
@@ -198,7 +199,7 @@ public class AutoJs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NotificationListener.AccessibilityNotificationObserver getNotificationObserver() {
|
public AccessibilityNotificationObserver getNotificationObserver() {
|
||||||
return mNotificationObserver;
|
return mNotificationObserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user