plugins - Plugins
Auto.js provides a mechanism to load plugins. It allows users to write an APK that contains Activities, Services, C/C++ libraries, etc., install it on an Android device, and then load and call it from Auto.js.
A plugin is an independently installable APK. After installing it, you can load it via the $plugins module and call its exported APIs.
Starting from Pro 9.2, plugins can be merged into the packaged APK, so no separate installation is needed after packaging.
Tips
In Pro 9.2, Auto.js Pro includes a built-in plugin store. You can download plugins there. See the blog post Auto.js Pro 9.2 Release Notes.
$plugins.load(packageName)
packageName{string} Plugin package name to load
Load a plugin and return the object exported by module.exports from the plugin module.
Throws PluginLoadException if the plugin is not installed.
How to develop a plugin
Tip
You can find the full example project here: Plugin SDK
In this example, the plugin package name is org.autojs.plugin.sdk.demo. In real projects, the package name may differ.
Integrate the Plugin SDK
Create a new Android project and add the following to the project's build.gradle:
allprojects {
repositories {
// ...
maven { url 'https://jitpack.io' }
}
}Add the dependency to the module's build.gradle (e.g. app):
dependencies {
// ...
implementation 'com.github.hyb1996:Auto.js-Plugin-SDK:0.2'
}For more information, see Jitpack.io.
Plugin configuration
1. Create PluginHelloWorld extending Plugin
public class PluginHelloWorld extends Plugin {
public PluginHelloWorld(Context context, Context selfContext, Object runtime, Object topLevelScope) {
super(context, selfContext, runtime, topLevelScope);
}
// Assets path for the plugin's JavaScript glue layer
@Override
public String getAssetsScriptDir() {
return "plugin-helloworld";
}
// Plugin public API, callable from JavaScript
public String getStringFromJava() {
return "Hello, Auto.js!";
}
// Plugin public API, callable from JavaScript
public void say(String message) {
getSelfContext().startActivity(new Intent(getSelfContext(), HelloWorldActivity.class)
.putExtra("message", message)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
}2. Create MyPluginRegistry extending PluginRegistry
public class MyPluginRegistry extends PluginRegistry {
static {
// Register default plugin
registerDefaultPlugin(new PluginLoader() {
@Override
public Plugin load(Context context, Context selfContext, Object runtime, Object topLevelScope) {
return new PluginHelloWorld(context, selfContext, runtime, topLevelScope);
}
});
}
}Configure the following meta-data in AndroidManifest.xml. Use "org.autojs.plugin.sdk.registry" as name, and set value to the fully qualified name of MyPluginRegistry.
<application
...>
<meta-data
android:name="org.autojs.plugin.sdk.registry"
android:value="org.autojs.plugin.sdk.demo.MyPluginRegistry" />
<activity
android:name=".HelloWorldActivity"
android:exported="true" />
<service
android:name=".HelloworldPluginService"
android:exported="true" />
</application>3. Write the JavaScript glue layer
Add an index.js file under the corresponding assets directory (returned by Plugin.getAssetsScriptDir) to export the plugin API as the glue layer.
module.exports = function (plugin) {
let runtime = plugin.runtime;
let scope = plugin.topLevelScope;
function helloworld() {
}
helloworld.stringFromJava = plugin.getStringFromJava();
helloworld.say = function (message) {
plugin.say(message);
}
return helloworld;
}4. Call it from Auto.js Pro
Build the plugin APK (assembleDebug / assembleRelease) and install it on the device. Then call it from Auto.js Pro:
let helloworld = $plugins.load("org.autojs.plugin.sdk.demo");
console.log(helloworld.stringFromJava);
helloworld.say("Hello, Auto.js Pro Plugin");5. Call via an independent Service (AIDL style)
You can implement a Service in the plugin. Auto.js Pro can start and bind it, and you can call the service interface from JS via AIDL-style calls.
Override getService in the plugin.
// Plugin service class (optional). Used for AIDL-style communication with Auto.js Pro. Can return null.
@Override
public ComponentName getService() {
return new ComponentName(getSelfContext().getPackageName(), HelloworldPluginService.class.getName());
}Create a Service component (make sure to register it in AndroidManifest with exported="true"), extending PluginService.
public class HelloworldPluginService extends PluginService {
private static final String ACTION_ADD = "add";
@Override
protected Result onRemoteCall(@NonNull String action, @NonNull Map<String, Object> args, @Nullable RemoteCallback callback) throws RuntimeException {
switch (action) {
case ACTION_ADD:
return invokeAdd(args);
}
return Result.notImplemented(action);
}
private Result invokeAdd(Map<String, Object> args) {
Number a = PluginUtils.getNotNull(args, "a");
Number b = PluginUtils.getNotNull(args, "b");
double sum = a.doubleValue() + b.doubleValue();
return new Result(Collections.singletonMap("sum", sum));
}
}Add glue layer code in index.js:
helloworld.remoteAdd = function (a, b) {
return plugin.waitForConnection().call('add', {
a: a,
b: b
}, null).get('sum');
}Then call it from Auto.js Pro:
let helloworld = $plugins.load("org.autojs.plugin.sdk.demo");
console.log(helloworld.remoteAdd(1, 2));