优化 脚本管理器增删文件后的更新
新增 支持插件 优化 多点找色的内存泄漏 修复 文件重命名时的后缀问题 修复 脚本抛出Throwable不能被捕捉的问题
This commit is contained in:
@@ -57,7 +57,7 @@ runtime.init();
|
||||
(function(scope){
|
||||
var modules = ['app', 'automator', 'console', 'dialogs', 'io', 'selector', 'shell', 'web', 'ui',
|
||||
"images", "timers", "threads", "events", "engines", "RootAutomator", "http", "storages", "floaty",
|
||||
"sensors", "media"];
|
||||
"sensors", "media", "plugins"];
|
||||
var len = modules.length;
|
||||
for(var i = 0; i < len; i++) {
|
||||
var m = modules[i];
|
||||
|
||||
12
autojs/src/main/assets/modules/__plugins__.js
Normal file
12
autojs/src/main/assets/modules/__plugins__.js
Normal file
@@ -0,0 +1,12 @@
|
||||
module.exports = function (runtime, scope) {
|
||||
function plugins(){
|
||||
}
|
||||
|
||||
plugins.load = function(packageName){
|
||||
var plugin = runtime.plugins.load(packageName);
|
||||
var index = require(plugin.mainScriptPath);
|
||||
return index(plugin.unwrap());
|
||||
}
|
||||
|
||||
return plugins;
|
||||
}
|
||||
@@ -84,9 +84,12 @@ public abstract class AutoJs {
|
||||
protected void init() {
|
||||
addAccessibilityServiceDelegates();
|
||||
registerActivityLifecycleCallbacks();
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, mContext, new BaseLoaderCallback(mContext) {
|
||||
|
||||
});
|
||||
try {
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, mContext, new BaseLoaderCallback(mContext) {
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ensureAccessibilityServiceEnabled();
|
||||
|
||||
@@ -67,7 +67,7 @@ public class ScriptEngineService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(ScriptExecution execution, Exception e) {
|
||||
public void onException(ScriptExecution execution, Throwable e) {
|
||||
e.printStackTrace();
|
||||
onFinish(execution);
|
||||
String message = null;
|
||||
@@ -80,7 +80,7 @@ public class ScriptEngineService {
|
||||
}
|
||||
if (execution.getEngine() instanceof JavaScriptEngine) {
|
||||
JavaScriptEngine engine = (JavaScriptEngine) execution.getEngine();
|
||||
Exception uncaughtException = engine.getUncaughtException();
|
||||
Throwable uncaughtException = engine.getUncaughtException();
|
||||
if (uncaughtException != null) {
|
||||
engine.getRuntime().console.error(uncaughtException);
|
||||
message = uncaughtException.getMessage();
|
||||
|
||||
@@ -57,6 +57,7 @@ public class ColorFinder {
|
||||
return new Point[0];
|
||||
}
|
||||
Point[] points = matOfPoint.toArray();
|
||||
OpenCVHelper.release(matOfPoint);
|
||||
if (rect != null) {
|
||||
for (int i = 0; i < points.length; i++) {
|
||||
points[i].x = mScreenMetrics.scaleX((int) (points[i].x + rect.x));
|
||||
|
||||
@@ -35,6 +35,7 @@ public class OpenCVHelper {
|
||||
callback.onInitFinish();
|
||||
return;
|
||||
}
|
||||
|
||||
mInitialized = true;
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, activity.getApplicationContext(), new LoaderCallback(activity) {
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.stardust.autojs.core.plugin;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import com.stardust.autojs.rhino.TopLevelScope;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class Plugin {
|
||||
|
||||
public static class PluginLoadException extends RuntimeException {
|
||||
public PluginLoadException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public PluginLoadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String KEY_REGISTRY = "org.autojs.plugin.sdk.registry";
|
||||
|
||||
public static Plugin load(Context context, Context packageContext, ScriptRuntime runtime, TopLevelScope scope) {
|
||||
try {
|
||||
ApplicationInfo applicationInfo = packageContext.getPackageManager().getApplicationInfo(packageContext.getPackageName(), PackageManager.GET_META_DATA);
|
||||
String registryClass = applicationInfo.metaData.getString(KEY_REGISTRY);
|
||||
if (registryClass == null) {
|
||||
throw new PluginLoadException("no registry in metadata");
|
||||
}
|
||||
Class<?> pluginClass = Class.forName(registryClass, true, packageContext.getClassLoader());
|
||||
Method loadDefault = pluginClass.getMethod("loadDefault", Context.class, Context.class, Object.class, Object.class);
|
||||
return Plugin.create(loadDefault.invoke(null, context, packageContext, runtime, scope));
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return null;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new PluginLoadException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Plugin create(Object pluginInstance) {
|
||||
if (pluginInstance == null)
|
||||
return null;
|
||||
return new Plugin(pluginInstance);
|
||||
}
|
||||
|
||||
private final Object mPluginInstance;
|
||||
private Method mGetVersion;
|
||||
private Method mGetScriptDir;
|
||||
private String mMainScriptPath;
|
||||
|
||||
public Plugin(Object pluginInstance) {
|
||||
mPluginInstance = pluginInstance;
|
||||
findMethods(pluginInstance.getClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void findMethods(Class pluginClass) {
|
||||
try {
|
||||
mGetVersion = pluginClass.getMethod("getVersion");
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
mGetScriptDir = pluginClass.getMethod("getAssetsScriptDir");
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Object unwrap() {
|
||||
return mPluginInstance;
|
||||
}
|
||||
|
||||
public String getMainScriptPath() {
|
||||
return mMainScriptPath;
|
||||
}
|
||||
|
||||
public void setMainScriptPath(String mainScriptPath) {
|
||||
mMainScriptPath = mainScriptPath;
|
||||
}
|
||||
|
||||
public String getAssetsScriptDir() {
|
||||
try {
|
||||
return (String) mGetScriptDir.invoke(mPluginInstance);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import com.stardust.autojs.core.ui.ViewExtras;
|
||||
import com.stardust.autojs.rhino.NativeArrayLikeJavaObject;
|
||||
import com.stardust.autojs.rhino.RhinoAndroidHelper;
|
||||
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;
|
||||
@@ -60,6 +61,12 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
|
||||
ScriptableObject.putProperty(mScriptable, name, Context.javaToJS(value, mScriptable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRuntime(ScriptRuntime runtime) {
|
||||
super.setRuntime(runtime);
|
||||
runtime.setTopLevelScope(mScriptable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object doExecution(JavaScriptSource source) {
|
||||
Reader reader = source.getNonNullScriptReader();
|
||||
|
||||
@@ -44,9 +44,9 @@ public interface ScriptEngine<S extends ScriptSource> {
|
||||
|
||||
String cwd();
|
||||
|
||||
void uncaughtException(Exception throwable);
|
||||
void uncaughtException(Throwable throwable);
|
||||
|
||||
Exception getUncaughtException();
|
||||
Throwable getUncaughtException();
|
||||
|
||||
void setId(int id);
|
||||
|
||||
@@ -72,7 +72,7 @@ public interface ScriptEngine<S extends ScriptSource> {
|
||||
private Map<String, Object> mTags = new HashMap<>();
|
||||
private OnDestroyListener mOnDestroyListener;
|
||||
private boolean mDestroyed = false;
|
||||
private Exception mUncaughtException;
|
||||
private Throwable mUncaughtException;
|
||||
private volatile AtomicInteger mId = new AtomicInteger(ScriptExecution.NO_ID);
|
||||
|
||||
@Override
|
||||
@@ -114,13 +114,13 @@ public interface ScriptEngine<S extends ScriptSource> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Exception throwable) {
|
||||
public void uncaughtException(Throwable throwable) {
|
||||
mUncaughtException = throwable;
|
||||
forceStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Exception getUncaughtException() {
|
||||
public Throwable getUncaughtException() {
|
||||
return mUncaughtException;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,12 +59,12 @@ public class ScriptEngineProxy<S extends ScriptSource> implements ScriptEngine<S
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Exception throwable) {
|
||||
public void uncaughtException(Throwable throwable) {
|
||||
mScriptEngine.uncaughtException(throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Exception getUncaughtException() {
|
||||
public Throwable getUncaughtException() {
|
||||
return mScriptEngine.getUncaughtException();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,14 +40,14 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu
|
||||
try {
|
||||
prepare(engine);
|
||||
Object r = doExecution(engine);
|
||||
Exception uncaughtException = engine.getUncaughtException();
|
||||
Throwable uncaughtException = engine.getUncaughtException();
|
||||
if (uncaughtException != null) {
|
||||
onException(engine, uncaughtException);
|
||||
return null;
|
||||
}
|
||||
getListener().onSuccess(this, r);
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
onException(engine, e);
|
||||
return null;
|
||||
} finally {
|
||||
@@ -56,7 +56,7 @@ public class RunnableScriptExecution extends ScriptExecution.AbstractScriptExecu
|
||||
}
|
||||
}
|
||||
|
||||
protected void onException(ScriptEngine engine, Exception e) {
|
||||
protected void onException(ScriptEngine engine, Throwable e) {
|
||||
Log.w(TAG, "onException: engine = " + engine, e);
|
||||
getListener().onException(this, e);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void onException(Exception e) {
|
||||
private void onException(Throwable e) {
|
||||
mExecutionListener.onException(mScriptExecution, e);
|
||||
super.finish();
|
||||
}
|
||||
@@ -127,7 +127,7 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
||||
super.finish();
|
||||
return;
|
||||
}
|
||||
Exception exception = mScriptEngine.getUncaughtException();
|
||||
Throwable exception = mScriptEngine.getUncaughtException();
|
||||
if (exception != null) {
|
||||
onException(exception);
|
||||
} else {
|
||||
|
||||
@@ -12,5 +12,5 @@ public interface ScriptExecutionListener extends Serializable {
|
||||
|
||||
void onSuccess(ScriptExecution execution, Object result);
|
||||
|
||||
void onException(ScriptExecution execution, Exception e);
|
||||
void onException(ScriptExecution execution, Throwable e);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class ScriptExecutionObserver implements ScriptExecutionListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(ScriptExecution execution, Exception e) {
|
||||
public void onException(ScriptExecution execution, Throwable e) {
|
||||
for (ScriptExecutionListener listener : mScriptExecutionListeners) {
|
||||
listener.onException(execution, e);
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class ScriptExecutionObserver implements ScriptExecutionListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(ScriptExecution execution, Exception e) {
|
||||
public void onException(ScriptExecution execution, Throwable e) {
|
||||
mScriptExecutionListener.onException(execution, e);
|
||||
mScriptExecutionObserver.onException(execution, e);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public class SimpleScriptExecutionListener implements ScriptExecutionListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(ScriptExecution execution, Exception e) {
|
||||
public void onException(ScriptExecution execution, Throwable e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.stardust.autojs.core.image.Colors;
|
||||
import com.stardust.autojs.core.permission.PermissionRequestProxyActivity;
|
||||
import com.stardust.autojs.core.permission.Permissions;
|
||||
import com.stardust.autojs.rhino.AndroidClassLoader;
|
||||
import com.stardust.autojs.rhino.TopLevelScope;
|
||||
import com.stardust.autojs.runtime.api.AbstractShell;
|
||||
import com.stardust.autojs.runtime.api.AppUtils;
|
||||
import com.stardust.autojs.runtime.api.Console;
|
||||
@@ -26,6 +27,7 @@ import com.stardust.autojs.runtime.api.Files;
|
||||
import com.stardust.autojs.runtime.api.Floaty;
|
||||
import com.stardust.autojs.core.looper.Loopers;
|
||||
import com.stardust.autojs.runtime.api.Media;
|
||||
import com.stardust.autojs.runtime.api.Plugins;
|
||||
import com.stardust.autojs.runtime.api.Sensors;
|
||||
import com.stardust.autojs.runtime.api.Threads;
|
||||
import com.stardust.autojs.runtime.api.Timers;
|
||||
@@ -193,6 +195,9 @@ public class ScriptRuntime {
|
||||
@ScriptVariable
|
||||
public final Media media;
|
||||
|
||||
@ScriptVariable
|
||||
public final Plugins plugins;
|
||||
|
||||
private Images images;
|
||||
|
||||
private static WeakReference<Context> applicationContext;
|
||||
@@ -201,6 +206,7 @@ public class ScriptRuntime {
|
||||
private Supplier<AbstractShell> mShellSupplier;
|
||||
private ScreenMetrics mScreenMetrics = new ScreenMetrics();
|
||||
private Thread mThread;
|
||||
private TopLevelScope mTopLevelScope;
|
||||
|
||||
|
||||
protected ScriptRuntime(Builder builder) {
|
||||
@@ -223,6 +229,7 @@ public class ScriptRuntime {
|
||||
floaty = new Floaty(uiHandler, ui, this);
|
||||
files = new Files(this);
|
||||
media = new Media(context, this);
|
||||
plugins = new Plugins(context, this);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
@@ -236,6 +243,17 @@ public class ScriptRuntime {
|
||||
sensors = new Sensors(uiHandler.getContext(), this);
|
||||
}
|
||||
|
||||
public TopLevelScope getTopLevelScope() {
|
||||
return mTopLevelScope;
|
||||
}
|
||||
|
||||
public void setTopLevelScope(TopLevelScope topLevelScope) {
|
||||
if (mTopLevelScope != null) {
|
||||
throw new IllegalStateException("top level has already exists");
|
||||
}
|
||||
mTopLevelScope = topLevelScope;
|
||||
}
|
||||
|
||||
public static void setApplicationContext(Context context) {
|
||||
applicationContext = new WeakReference<>(context);
|
||||
}
|
||||
@@ -358,7 +376,7 @@ public class ScriptRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
public void exit(Exception e) {
|
||||
public void exit(Throwable e) {
|
||||
engines.myEngine().uncaughtException(e);
|
||||
exit();
|
||||
}
|
||||
@@ -389,7 +407,7 @@ public class ScriptRuntime {
|
||||
ignoresException(floaty::closeAll);
|
||||
try {
|
||||
events.emit("exit");
|
||||
} catch (Exception ignored) {
|
||||
} catch (Throwable ignored) {
|
||||
console.error("exception on exit: ", ignored);
|
||||
}
|
||||
ignoresException(threads::shutDownAll);
|
||||
@@ -412,7 +430,7 @@ public class ScriptRuntime {
|
||||
private void ignoresException(Runnable r) {
|
||||
try {
|
||||
r.run();
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.stardust.autojs.runtime.api;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.stardust.autojs.core.plugin.Plugin;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.pio.PFiles;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Plugins {
|
||||
|
||||
private final Context mContext;
|
||||
private final ScriptRuntime mRuntime;
|
||||
private File mPluginCacheDir;
|
||||
|
||||
public Plugins(Context context, ScriptRuntime runtime) {
|
||||
mContext = context;
|
||||
mRuntime = runtime;
|
||||
mPluginCacheDir = new File(mContext.getCacheDir(), "plugin-scripts/");
|
||||
}
|
||||
|
||||
public Plugin load(String packageName) {
|
||||
try {
|
||||
Context packageContext = mContext.createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
|
||||
Plugin plugin = Plugin.load(mContext, packageContext, mRuntime, mRuntime.getTopLevelScope());
|
||||
if (plugin == null) {
|
||||
return null;
|
||||
}
|
||||
File scriptCacheDir = getScriptCacheDir(packageName);
|
||||
PFiles.copyAssetDir(packageContext.getAssets(), plugin.getAssetsScriptDir(), scriptCacheDir.getPath(), null);
|
||||
plugin.setMainScriptPath(new File(scriptCacheDir, "index.js").getPath());
|
||||
return plugin;
|
||||
} catch (Exception e) {
|
||||
throw new Plugin.PluginLoadException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private File getScriptCacheDir(String packageName) {
|
||||
File dir = new File(mPluginCacheDir, packageName + "/");
|
||||
dir.mkdirs();
|
||||
return dir;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
PFiles.deleteRecursively(mPluginCacheDir);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public class VMBridge_custom extends VMBridge_jdk15 {
|
||||
try {
|
||||
Object result = adapterWrapper.invoke(cf, target, topScope, proxy, method, args);
|
||||
return castReturnValue(method, result);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
// notify the script thread to exit
|
||||
com.stardust.autojs.runtime.ScriptRuntime runtime = engine.getRuntime();
|
||||
|
||||
Reference in New Issue
Block a user