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.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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Object> 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Thread.UncaughtExceptionHandler> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -50,4 +50,5 @@ public class AndroidContextFactory extends ShellContextFactory {
|
||||
return cx;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -51,4 +51,6 @@ public class UI extends ProxyObject {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user