修复 ui线程下ui.xxx.on等函数不存在的问题

修复 非ui线程下ui.xxx.on等函数报错的问题
新增 注册ui.xxx支持增加成员
修复 多线程环境没有调用Context.exit()可能造成的内存泄漏
This commit is contained in:
hyb1996 2018-10-16 15:16:11 +08:00
parent d2e0899c8b
commit 4dcb19e4fe
25 changed files with 405 additions and 161 deletions

View File

@ -42,23 +42,6 @@ function wrap(value){
return value;
}
bridges.asArray = function (list) {
var arr = [];
for (var i = 0; i < list.size(); i++) {
arr.push(list.get(i));
}
for (var key in list) {
if (typeof (key) == 'number')
continue;
var v = list[key];
if (typeof (v) == 'function') {
arr[key] = v.bind(list);
} else {
arr[key] = v;
}
}
return arr;
};
bridges.toArray = function (iterable) {
var iterator = iterable.iterator();
var arr = [];

View File

@ -13,7 +13,6 @@ import com.stardust.app.SimpleActivityLifecycleCallbacks;
import com.stardust.autojs.core.accessibility.AccessibilityBridge;
import com.stardust.autojs.core.console.GlobalStardustConsole;
import com.stardust.autojs.core.console.StardustConsole;
import com.stardust.autojs.core.image.OpenCVHelper;
import com.stardust.autojs.core.image.capture.ScreenCaptureRequestActivity;
import com.stardust.autojs.core.image.capture.ScreenCaptureRequester;
import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder;
@ -21,10 +20,10 @@ import com.stardust.autojs.core.util.Shell;
import com.stardust.autojs.engine.LoopBasedJavaScriptEngine;
import com.stardust.autojs.engine.RootAutomatorEngine;
import com.stardust.autojs.engine.ScriptEngineManager;
import com.stardust.autojs.rhino.InterruptibleAndroidContextFactory;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig;
import com.stardust.autojs.runtime.api.AppUtils;
import com.stardust.autojs.runtime.api.Console;
import com.stardust.autojs.script.AutoFileSource;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.util.ScreenMetrics;
@ -34,8 +33,10 @@ import com.stardust.view.accessibility.AccessibilityNotificationObserver;
import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.view.accessibility.LayoutInspector;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.OpenCVLoader;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Scriptable;
import java.io.File;
/**
* Created by Stardust on 2017/11/29.
@ -105,11 +106,15 @@ public abstract class AutoJs {
engine.setRuntime(createRuntime());
return engine;
});
LoopBasedJavaScriptEngine.initEngine();
initContextFactory();
mScriptEngineManager.registerEngine(AutoFileSource.ENGINE, () -> new RootAutomatorEngine(mContext));
}
protected void initContextFactory() {
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mContext.getCacheDir(), "classes")));
}
protected ScriptRuntime createRuntime() {
return new ScriptRuntime.Builder()
.setConsole(new StardustConsole(mUiHandler, mGlobalConsole))

View File

@ -1,7 +1,5 @@
package com.stardust.autojs.core.looper;
import android.content.pm.PackageManager;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.lang.ThreadCompat;

View File

@ -4,16 +4,12 @@ import android.os.Handler;
import android.os.Looper;
import android.support.annotation.CallSuper;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
import com.stardust.autojs.runtime.ScriptBridges;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.concurrent.VolatileBox;
import com.stardust.lang.ThreadCompat;
import org.mozilla.javascript.NativeArray;
import java.util.concurrent.ConcurrentHashMap;
/**
@ -43,6 +39,7 @@ public class TimerThread extends ThreadCompat {
mRuntime.loopers.prepare();
mTimer = new Timer(mRuntime, mMaxCallbackUptimeMillisForAllThreads);
sTimerMap.put(Thread.currentThread(), mTimer);
((RhinoJavaScriptEngine) mRuntime.engines.myEngine()).enterContext();
notifyRunning();
new Handler().post(mTarget);
try {
@ -54,6 +51,7 @@ public class TimerThread extends ThreadCompat {
} finally {
onExit();
mTimer = null;
org.mozilla.javascript.Context.exit();
sTimerMap.remove(Thread.currentThread(), mTimer);
}
}

View File

@ -1,5 +1,6 @@
package com.stardust.autojs.core.ui;
import android.util.Log;
import android.view.View;
import com.stardust.autojs.R;
@ -13,6 +14,7 @@ import org.mozilla.javascript.Scriptable;
public class ViewExtras {
private static final String LOG_TAG = "ViewExtras";
private NativeView mNativeView;
private ViewAttributes mViewAttributes;
@ -20,6 +22,7 @@ public class ViewExtras {
public static ViewExtras get(View view) {
ViewExtras extras;
Object tag = view.getTag(R.id.view_tag_view_extras);
Log.d(LOG_TAG, "view = " + view + ", tag = " + tag);
if (tag instanceof ViewExtras) {
extras = (ViewExtras) tag;
} else {
@ -34,7 +37,7 @@ public class ViewExtras {
ViewExtras extras = get(view);
ViewAttributes attributes = extras.getViewAttributes();
if (attributes == null) {
attributes = ViewAttributesFactory.create(parser, view);
attributes = ViewAttributesFactory.create(parser, view);
extras.setViewAttributes(attributes);
}
return attributes;

View File

@ -11,7 +11,6 @@ public class ResourceParser {
private final Drawables mDrawables;
public ResourceParser(Drawables drawables) {
mDrawables = drawables;
}

View File

@ -25,8 +25,4 @@ public class JsTabLayout extends TabLayout {
public JsTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setupWithViewPager(NativeObject viewPager) {
setupWithViewPager(UI.unwrapJsViewObject(viewPager, ViewPager.class));
}
}

View File

@ -8,12 +8,8 @@ import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
import android.util.Log;
import com.stardust.autojs.R;
import com.stardust.autojs.runtime.api.UI;
import org.mozilla.javascript.NativeObject;
public class JsToolbar extends Toolbar {
@ -47,9 +43,4 @@ public class JsToolbar extends Toolbar {
}
return (Activity) context;
}
public void setupWithDrawer(NativeObject object) {
setupWithDrawer(UI.unwrapJsViewObject(object, DrawerLayout.class));
}
}

View File

@ -88,9 +88,5 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
super.init();
}
public static void initEngine(){
RhinoJavaScriptEngine.initEngine();
}
}

View File

@ -1,25 +1,23 @@
package com.stardust.autojs.engine;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import com.stardust.app.GlobalAppContext;
import com.stardust.autojs.BuildConfig;
import com.stardust.autojs.core.ui.ViewExtras;
import com.stardust.autojs.core.ui.nativeview.NativeView;
import com.stardust.autojs.rhino.AndroidContextFactory;
import com.stardust.autojs.rhino.RhinoAndroidHelper;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.autojs.rhino.TopLevelScope;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.autojs.script.StringScriptSource;
import com.stardust.automator.UiObject;
import com.stardust.automator.UiObjectCollection;
import com.stardust.pio.PFiles;
import com.stardust.pio.UncheckedIOException;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.commonjs.module.RequireBuilder;
@ -28,9 +26,10 @@ import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptPr
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Locale;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
/**
@ -44,18 +43,17 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
private static final String LOG_TAG = "RhinoJavaScriptEngine";
private static final String MODULES_PATH = "modules";
private static int contextCount = 0;
private static StringScriptSource sInitScript;
private static final ConcurrentHashMap<Context, RhinoJavaScriptEngine> sContextEngineMap = new ConcurrentHashMap<>();
private Context mContext;
private Scriptable mScriptable;
private TopLevelScope mScriptable;
private Thread mThread;
private android.content.Context mAndroidContext;
public RhinoJavaScriptEngine(android.content.Context context) {
mAndroidContext = context;
mContext = createContext();
mContext = enterContext();
mScriptable = createScope(mContext);
}
@ -92,8 +90,6 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
Log.d(LOG_TAG, "on destroy");
sContextEngineMap.remove(getContext());
Context.exit();
contextCount--;
Log.d(LOG_TAG, "contextCount = " + contextCount);
}
public Thread getThread() {
@ -142,15 +138,14 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
return mScriptable;
}
protected Scriptable createScope(Context context) {
ImporterTopLevel importerTopLevel = new ImporterTopLevel();
importerTopLevel.initStandardObjects(context, false);
return importerTopLevel;
protected TopLevelScope createScope(Context context) {
TopLevelScope topLevelScope = new TopLevelScope();
topLevelScope.initStandardObjects(context, false);
return topLevelScope;
}
public Context createContext() {
public Context enterContext() {
Context context = new RhinoAndroidHelper(mAndroidContext).enterContext();
contextCount++;
setupContext(context);
sContextEngineMap.put(context, this);
return context;
@ -163,12 +158,6 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
context.setWrapFactory(new WrapFactory());
}
public static void initEngine() {
if (!ContextFactory.hasExplicitGlobal()) {
android.content.Context context = GlobalAppContext.get();
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(context.getCacheDir(), "classes")));
}
}
public static RhinoJavaScriptEngine getEngineOfContext(Context context) {
return sContextEngineMap.get(context);
@ -178,43 +167,34 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
@Override
public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {
Object result;
if (obj instanceof String) {
return getRuntime().bridges.toString(obj.toString());
result = getRuntime().bridges.toString(obj.toString());
} else if (staticType == UiObjectCollection.class) {
UiObjectCollection collection = (UiObjectCollection) obj;
Object[] array = new Object[collection.size()];
for (int i = 0; i < array.length; i++) {
array[i] = wrapAsJavaObject(cx, scope, collection.get(i), UiObject.class);
}
NativeArray nativeArray = new NativeArray(array);
nativeArray.setPrototype(new NativeJavaObject(scope, collection, staticType));
result = nativeArray;
} else {
result = super.wrap(cx, scope, obj, staticType);
}
if (staticType == UiObjectCollection.class) {
return getRuntime().bridges.asArray(obj);
}
return 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) {
return ViewExtras.getNativeView(scope, (View) javaObject, staticType, getRuntime());
result = ViewExtras.getNativeView(scope, (View) javaObject, staticType, getRuntime());
} else {
result = super.wrapAsJavaObject(cx, scope, javaObject, staticType);
}
return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
}
}
private static class InterruptibleAndroidContextFactory extends AndroidContextFactory {
public InterruptibleAndroidContextFactory(File cacheDirectory) {
super(cacheDirectory);
}
@Override
protected void observeInstructionCount(Context cx, int instructionCount) {
if (Thread.currentThread().isInterrupted() && Looper.myLooper() != Looper.getMainLooper()) {
throw new ScriptInterruptedException();
}
}
@Override
protected Context makeContext() {
Context cx = super.makeContext();
cx.setInstructionObserverThreshold(10000);
return cx;
//Log.d(LOG_TAG, "wrapAsJavaObject: java = " + javaObject + ", result = " + result + ", scope = " + scope);
return result;
}
}

View File

@ -230,10 +230,6 @@ public class ScriptExecuteActivity extends AppCompatActivity {
}
}
public void setSupportActionBar(@Nullable NativeObject toolbar) {
super.setSupportActionBar(UI.unwrapJsViewObject(toolbar, Toolbar.class));
}
private static class ActivityScriptExecution extends ScriptExecution.AbstractScriptExecution {
private ScriptEngine mScriptEngine;

View File

@ -0,0 +1,55 @@
package com.stardust.autojs.rhino;
import android.os.Looper;
import android.util.Log;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import org.mozilla.javascript.Context;
import java.io.File;
import java.util.concurrent.atomic.AtomicInteger;
public class InterruptibleAndroidContextFactory extends AndroidContextFactory {
private AtomicInteger mContextCount = new AtomicInteger();
private static final String LOG_TAG = "ContextFactory";
/**
* Create a new factory. It will cache generated code in the given directory
*
* @param cacheDirectory the cache directory
*/
public InterruptibleAndroidContextFactory(File cacheDirectory) {
super(cacheDirectory);
}
@Override
protected void observeInstructionCount(Context cx, int instructionCount) {
if (Thread.currentThread().isInterrupted() && Looper.myLooper() != Looper.getMainLooper()) {
throw new ScriptInterruptedException();
}
}
@Override
protected Context makeContext() {
Context cx = super.makeContext();
cx.setInstructionObserverThreshold(10000);
return cx;
}
@Override
protected void onContextCreated(Context cx) {
super.onContextCreated(cx);
int i = mContextCount.incrementAndGet();
Log.d(LOG_TAG, "onContextCreated: count = " + i);
}
@Override
protected void onContextReleased(Context cx) {
super.onContextReleased(cx);
int i = mContextCount.decrementAndGet();
Log.d(LOG_TAG, "onContextReleased: count = " + i);
}
}

View File

@ -0,0 +1,6 @@
package com.stardust.autojs.rhino;
import org.mozilla.javascript.ImporterTopLevel;
public class TopLevelScope extends ImporterTopLevel {
}

View File

@ -19,8 +19,6 @@ public class ScriptBridges {
Object toArray(Iterable o);
Object asArray(Object o);
Object toString(Object obj);
}
@ -47,12 +45,6 @@ public class ScriptBridges {
return mBridges.toArray(c);
}
public Object asArray(Object o) {
checkBridges();
return mBridges.asArray(o);
}
public Object toString(Object obj) {
checkBridges();
return mBridges.toString(obj);

View File

@ -1,20 +1,14 @@
package com.stardust.autojs.runtime.api;
import android.widget.RadioGroup;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.engine.JavaScriptEngine;
import com.stardust.autojs.execution.ExecutionConfig;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.script.AutoFileSource;
import com.stardust.autojs.script.JavaScriptFileSource;
import com.stardust.autojs.script.JavaScriptSource;
import com.stardust.autojs.script.StringScriptSource;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/8/4.
*/
@ -22,7 +16,7 @@ import java.util.List;
public class Engines {
private ScriptEngineService mEngineService;
private ScriptEngine<JavaScriptSource> mScriptEngine;
private JavaScriptEngine mScriptEngine;
private ScriptRuntime mScriptRuntime;
public Engines(ScriptEngineService engineService, ScriptRuntime scriptRuntime) {
@ -55,13 +49,13 @@ public class Engines {
}
public void setCurrentEngine(ScriptEngine<JavaScriptSource> engine) {
public void setCurrentEngine(JavaScriptEngine engine) {
if (mScriptEngine != null)
throw new IllegalStateException();
mScriptEngine = engine;
}
public ScriptEngine<JavaScriptSource> myEngine() {
public JavaScriptEngine myEngine() {
return mScriptEngine;
}
}

View File

@ -1,6 +1,5 @@
package com.stardust.autojs.runtime.api;
import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.pio.PFileInterface;
import com.stardust.pio.PFiles;
@ -22,6 +21,7 @@ public class Files {
mRuntime = runtime;
}
// FIXME: 2018/10/16 is not correct in sub-directory?
public String path(String relativePath) {
String cwd = cwd();
if (cwd == null || relativePath == null || relativePath.startsWith("/"))

View File

@ -4,7 +4,6 @@ import android.support.annotation.NonNull;
import com.stardust.autojs.core.looper.MainThreadProxy;
import com.stardust.autojs.core.looper.TimerThread;
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.concurrent.VolatileDispose;
@ -56,10 +55,7 @@ public class Threads {
@NonNull
private TimerThread createThread(Runnable runnable) {
return new TimerThread(mRuntime, mRuntime.timers.getMaxCallbackUptimeMillisForAllThreads(),
() -> {
((RhinoJavaScriptEngine) mRuntime.engines.myEngine()).createContext();
runnable.run();
}
runnable
) {
@Override
protected void onExit() {

View File

@ -63,21 +63,6 @@ public class UI extends ProxyObject {
return mResourceParser;
}
@SuppressWarnings("unchecked")
public static <V extends View> V unwrapJsViewObject(@Nullable NativeObject object, Class<V> c) {
if (object == null)
return null;
if (!object.containsKey("__javaObject__")) {
throw new ClassCastException("object " + object + " cannot be cast to " + c.getName());
}
Object view = object.get("__javaObject__");
if (!c.isInstance(view)) {
throw new ClassCastException("object " + object + " cannot be cast to " + c.getName());
}
return (V) view;
}
public Object getBindingContext() {
return mProperties.get("bindingContext");
}

View File

@ -0,0 +1,238 @@
package org.mozilla.javascript;
import org.mozilla.javascript.debug.DebuggableScript;
import org.mozilla.javascript.xml.XMLLib;
public class ContextWrapper extends Context {
private final Context mContext;
public ContextWrapper(Context context) {
mContext = context;
}
public static Context getCurrentContext() {
return Context.getCurrentContext();
}
public static Context enter() {
return Context.enter();
}
@Deprecated
public static Context enter(Context cx) {
return Context.enter(cx);
}
public static void exit() {
Context.exit();
}
@Deprecated
public static Object call(ContextAction action) {
return Context.call(action);
}
public static Object call(ContextFactory factory, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args) {
return Context.call(factory, callable, scope, thisObj, args);
}
@Deprecated
public static void addContextListener(ContextListener listener) {
Context.addContextListener(listener);
}
@Deprecated
public static void removeContextListener(ContextListener listener) {
Context.removeContextListener(listener);
}
@Override
public void setLanguageVersion(int version) {
mContext.setLanguageVersion(version);
}
public static boolean isValidLanguageVersion(int version) {
return Context.isValidLanguageVersion(version);
}
public static void checkLanguageVersion(int version) {
Context.checkLanguageVersion(version);
}
public static void reportWarning(String message, String sourceName, int lineno, String lineSource, int lineOffset) {
Context.reportWarning(message, sourceName, lineno, lineSource, lineOffset);
}
public static void reportWarning(String message) {
Context.reportWarning(message);
}
public static void reportWarning(String message, Throwable t) {
Context.reportWarning(message, t);
}
public static void reportError(String message, String sourceName, int lineno, String lineSource, int lineOffset) {
Context.reportError(message, sourceName, lineno, lineSource, lineOffset);
}
public static void reportError(String message) {
Context.reportError(message);
}
public static EvaluatorException reportRuntimeError(String message, String sourceName, int lineno, String lineSource, int lineOffset) {
return Context.reportRuntimeError(message, sourceName, lineno, lineSource, lineOffset);
}
public static EvaluatorException reportRuntimeError(String message) {
return Context.reportRuntimeError(message);
}
@Override
public ScriptableObject initStandardObjects(ScriptableObject scope, boolean sealed) {
return mContext.initStandardObjects(scope, sealed);
}
@Override
public ScriptableObject initSafeStandardObjects(ScriptableObject scope, boolean sealed) {
return mContext.initSafeStandardObjects(scope, sealed);
}
public static Object getUndefinedValue() {
return Context.getUndefinedValue();
}
@Override
public Object executeScriptWithContinuations(Script script, Scriptable scope) throws ContinuationPending {
return mContext.executeScriptWithContinuations(script, scope);
}
@Override
public Object callFunctionWithContinuations(Callable function, Scriptable scope, Object[] args) throws ContinuationPending {
return mContext.callFunctionWithContinuations(function, scope, args);
}
@Override
public ContinuationPending captureContinuation() {
return mContext.captureContinuation();
}
@Override
public Object resumeContinuation(Object continuation, Scriptable scope, Object functionResult) throws ContinuationPending {
return mContext.resumeContinuation(continuation, scope, functionResult);
}
@Override
public Scriptable newObject(Scriptable scope) {
return mContext.newObject(scope);
}
@Override
public Scriptable newObject(Scriptable scope, String constructorName) {
return mContext.newObject(scope, constructorName);
}
@Override
public Scriptable newObject(Scriptable scope, String constructorName, Object[] args) {
return mContext.newObject(scope, constructorName, args);
}
@Override
public Scriptable newArray(Scriptable scope, int length) {
return mContext.newArray(scope, length);
}
@Override
public Scriptable newArray(Scriptable scope, Object[] elements) {
return mContext.newArray(scope, elements);
}
public static boolean toBoolean(Object value) {
return Context.toBoolean(value);
}
public static double toNumber(Object value) {
return Context.toNumber(value);
}
public static String toString(Object value) {
return Context.toString(value);
}
public static Scriptable toObject(Object value, Scriptable scope) {
return Context.toObject(value, scope);
}
@Deprecated
public static Scriptable toObject(Object value, Scriptable scope, Class<?> staticType) {
return Context.toObject(value, scope, staticType);
}
public static Object javaToJS(Object value, Scriptable scope) {
return Context.javaToJS(value, scope);
}
public static Object jsToJava(Object value, Class<?> desiredType) throws EvaluatorException {
return Context.jsToJava(value, desiredType);
}
@Deprecated
public static Object toType(Object value, Class<?> desiredType) throws IllegalArgumentException {
return Context.toType(value, desiredType);
}
public static RuntimeException throwAsScriptRuntimeEx(Throwable e) {
return Context.throwAsScriptRuntimeEx(e);
}
public static boolean isValidOptimizationLevel(int optimizationLevel) {
return Context.isValidOptimizationLevel(optimizationLevel);
}
public static void checkOptimizationLevel(int optimizationLevel) {
Context.checkOptimizationLevel(optimizationLevel);
}
@Deprecated
public static void setCachingEnabled(boolean cachingEnabled) {
Context.setCachingEnabled(cachingEnabled);
}
public static DebuggableScript getDebuggableView(Script script) {
return Context.getDebuggableView(script);
}
@Override
public boolean hasFeature(int featureIndex) {
return mContext.hasFeature(featureIndex);
}
@Override
public XMLLib.Factory getE4xImplementationFactory() {
return mContext.getE4xImplementationFactory();
}
@Override
public void setGenerateObserverCount(boolean generateObserverCount) {
mContext.setGenerateObserverCount(generateObserverCount);
}
@Override
public void observeInstructionCount(int instructionCount) {
mContext.observeInstructionCount(instructionCount);
}
@Override
public GeneratedClassLoader createClassLoader(ClassLoader parent) {
return mContext.createClassLoader(parent);
}
@Override
public void addActivationName(String name) {
mContext.addActivationName(name);
}
@Override
public void removeActivationName(String name) {
mContext.removeActivationName(name);
}
}

View File

@ -3,6 +3,8 @@ package org.mozilla.javascript;
import android.os.Looper;
import android.util.Log;
import com.stardust.autojs.engine.RhinoJavaScriptEngine;
import org.mozilla.javascript.jdk15.VMBridge_jdk15;
import java.lang.reflect.Constructor;
@ -19,6 +21,9 @@ public class VMBridge_custom extends VMBridge_jdk15 {
@Override
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);
// --- The following code is copied from super class --
Constructor<?> c = (Constructor) proxyHelper;
InvocationHandler handler = (proxy, method, args) -> {
@ -43,25 +48,19 @@ public class VMBridge_custom extends VMBridge_jdk15 {
// If so, catch any exception of invoking
// Because an exception on ui thread will cause the whole app to crash
try {
Object result = adapter.invoke(cf, target, topScope, proxy, method, args);
Object result = adapterWrapper.invoke(cf, target, topScope, proxy, method, args);
return castReturnValue(method, result);
} catch (Exception e) {
e.printStackTrace();
// notify the script thread to exit
Object jsRuntime = topScope.get("runtime", null);
Log.d(LOG_TAG, "jsRuntime = " + jsRuntime);
if (jsRuntime instanceof NativeJavaObject) {
Object runtime = ((NativeJavaObject) jsRuntime).unwrap();
Log.d(LOG_TAG, "runtime = " + runtime);
if(runtime instanceof com.stardust.autojs.runtime.ScriptRuntime){
((com.stardust.autojs.runtime.ScriptRuntime) runtime).exit(e);
}
}
com.stardust.autojs.runtime.ScriptRuntime runtime = engine.getRuntime();
Log.d(LOG_TAG, "runtime = " + runtime);
runtime.exit(e);
// even if we caught the exception, we must return a value to for the method call.
return defaultValue(method.getReturnType());
}
} else {
return castReturnValue(method, adapter.invoke(cf, target, topScope, proxy, method, args));
return castReturnValue(method, adapterWrapper.invoke(cf, target, topScope, proxy, method, args));
}
};
@ -115,4 +114,36 @@ public class VMBridge_custom extends VMBridge_jdk15 {
}
return null;
}
private class InterfaceAdapterWrapper {
private final InterfaceAdapter mInterfaceAdapter;
private final Context mCallerContext;
private InterfaceAdapterWrapper(InterfaceAdapter interfaceAdapter, Context callerContext) {
mInterfaceAdapter = interfaceAdapter;
mCallerContext = callerContext;
}
public Object invoke(ContextFactory cf, Object target, Scriptable topScope, Object thisObject, Method method, Object[] args) {
ContextAction action = cx -> invokeImpl(cx, target, topScope, thisObject, method, args);
return call(cf, action);
}
private Object call(ContextFactory cf, ContextAction action) {
Context cx = Context.enter(null, cf);
//TODO null check
cx.setWrapFactory(mCallerContext.getWrapFactory());
try {
return action.run(cx);
} finally {
Context.exit();
}
}
public Object invokeImpl(Context cx, Object target, Scriptable topScope, Object thisObject, Method method, Object[] args) {
return mInterfaceAdapter.invokeImpl(cx, target, topScope, thisObject, method, args);
}
}
}

View File

@ -446,7 +446,9 @@ public class UiGlobalSelector {
for (ListFilter filter : mFilters) {
str.append(filter.toString()).append(".");
}
str.deleteCharAt(str.length() - 1);
if(str.length() > 0){
str.deleteCharAt(str.length() - 1);
}
return str.toString();
}
}

View File

@ -42,7 +42,7 @@ public class UiObjectCollection {
}
public UiObject[] toArray(){
return mNodes.toArray(new UiObject[mNodes.size()]);
return mNodes.toArray(new UiObject[0]);
}
public boolean performAction(int action) {

View File

@ -60,7 +60,7 @@ public class AccessibilityInfoProvider implements AccessibilityDelegate {
return;
try {
ComponentName componentName = new ComponentName(latestPackageStr, latestClassStr);
mLatestActivity = mPackageManager.getActivityInfo(componentName, 0).name;
mLatestActivity = mPackageManager.getActivityInfo(componentName, PackageManager.MATCH_DEFAULT_ONLY).name;
} catch (PackageManager.NameNotFoundException ignored) {
return;
}

View File

@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":430,"versionName":"4.0.4 Alpha","enabled":true,"outputFile":"commonRelease-4.0.4 Alpha.apk","fullName":"commonRelease","baseName":"common-release"},"path":"commonRelease-4.0.4 Alpha.apk","properties":{}}]
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":431,"versionName":"4.0.4 Alpha2","enabled":true,"outputFile":"commonRelease-4.0.4 Alpha2.apk","fullName":"commonRelease","baseName":"common-release"},"path":"commonRelease-4.0.4 Alpha2.apk","properties":{}}]

View File

@ -1,6 +1,6 @@
{
"appVersionCode": 430,
"appVersionName": "4.0.4 Alpha",
"appVersionCode": 431,
"appVersionName": "4.0.4 Alpha2",
"target": 28,
"mini": 17,
"compile": 28,