mirror of
https://github.com/TonyJiangWJ/Auto.js.git
synced 2026-06-12 21:01:32 +08:00
fix: RootAutomatorEngine.forceStop not working
This commit is contained in:
parent
7b4629aa1d
commit
8034dc7b6b
@ -9,8 +9,8 @@ android {
|
||||
applicationId "com.stardust.scriptdroid"
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 23
|
||||
versionCode 159
|
||||
versionName "2.0.16 Beta"
|
||||
versionCode 160
|
||||
versionName "2.0.16 Alpha3"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
ndk {
|
||||
|
||||
@ -69,6 +69,11 @@
|
||||
"type": "markdown",
|
||||
"path":"documentation"
|
||||
},
|
||||
{
|
||||
"title": "需要Root权限的触摸与多点触摸",
|
||||
"type": "markdown",
|
||||
"path":"documentation"
|
||||
},
|
||||
{
|
||||
"title": "UI(用户界面)",
|
||||
"type": "markdown",
|
||||
|
||||
@ -41,6 +41,8 @@ engines模块包含了一些与脚本引擎有关的函数,包括运行其他
|
||||
|
||||
停止所有正在运行的脚本并显示停止的脚本数量。包括当前脚本自身。
|
||||
|
||||
### engines.myEngine()
|
||||
|
||||
# ScriptExecution
|
||||
|
||||
执行脚本时返回的对象,可以通过他获取执行的引擎、
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
|
||||
注意:本章节的函数在后续版本很可能有改动!请勿过分依赖本章节函数的副作用。推荐使用RootAutomator(见《需要Root权限的触摸与多点触摸》)代替本章的触摸函数。
|
||||
|
||||
以下函数均需要root权限,可以实现任意位置的点击、滑动、长按、模拟物理按键等。
|
||||
|
||||
这些函数通常首字母大写以表示其特殊的权限。
|
||||
这些函数均不返回任何值。
|
||||
并且,这些函数的执行是异步的、非实时的,在不同机型上所用的时间不同。脚本不会等待动作执行完成才继续执行。因此最好在每个函数之后加上适当的sleep来达到期望的效果。
|
||||
|
||||
|
||||
例如:
|
||||
```
|
||||
Tap(100, 100);
|
||||
|
||||
@ -10,7 +10,7 @@ var ra = RootAutomator(context);
|
||||
### RootAutomator.tap(x, y\[, id\])
|
||||
* x \<Number\> 横坐标
|
||||
* y \<Number\> 纵坐标
|
||||
* id \<Number\> 多点触摸id。默认值为1,可以通过setDefaultId指定。
|
||||
* id \<Number\> 多点触摸id,可选,默认为1,可以通过setDefaultId指定。
|
||||
|
||||
点击位置(x, y)。其中id是一个整数值,用于区分多点触摸,不同的id表示不同的"手指",例如:
|
||||
```
|
||||
@ -29,7 +29,7 @@ ra.exit();
|
||||
* x2 \<Number\> 滑动终点横坐标
|
||||
* y2 \<Number\> 滑动终点纵坐标
|
||||
* duration \<Number\> 滑动时长,单位毫秒,默认值为300
|
||||
* id \<Number\> 多点触摸id
|
||||
* id \<Number\> 多点触摸id,可选,默认为1
|
||||
|
||||
模拟一次从(x1, y1)到(x2, y2)的时间为duration毫秒的滑动。
|
||||
|
||||
@ -37,28 +37,36 @@ ra.exit();
|
||||
* x \<Number\> 横坐标
|
||||
* y \<Number\> 纵坐标
|
||||
* duration \<Number\> 按下时长
|
||||
* id \<Number\> 多点触摸id
|
||||
* id \<Number\> 多点触摸id,可选,默认为1
|
||||
|
||||
模拟按下位置(x, y),时长为duration毫秒。
|
||||
|
||||
### RootAutomator.longPress(x, y[\, id\])
|
||||
* x \<Number\> 横坐标
|
||||
* y \<Number\> 纵坐标
|
||||
* duration \<Number\> 按下时长
|
||||
* id \<Number\> 多点触摸id,可选,默认为1
|
||||
|
||||
模拟长按位置(x, y)。
|
||||
|
||||
以上为简单模拟触摸操作的函数。如果要模拟一些复杂的手势,需要更底层的函数。
|
||||
|
||||
### RootAutomator.touchDown(x, y[\, id\])
|
||||
* x \<Number\> 横坐标
|
||||
* y \<Number\> 纵坐标
|
||||
* id \<Number\> 多点触摸id
|
||||
* id \<Number\> 多点触摸id,可选,默认为1
|
||||
|
||||
模拟手指按下位置(x, y)。
|
||||
|
||||
### RootAutomator.touchMove(x, y[\, id\])
|
||||
* x \<Number\> 横坐标
|
||||
* y \<Number\> 纵坐标
|
||||
* id \<Number\> 多点触摸id
|
||||
* id \<Number\> 多点触摸id,可选,默认为1
|
||||
|
||||
模拟移动手指到位置(x, y)。
|
||||
|
||||
### RootAutomator.touchUp([\id\])
|
||||
* id \<Number\> 多点触摸id
|
||||
### RootAutomator.touchUp(\[id\])
|
||||
* id \<Number\> 多点触摸id,可选,默认为1
|
||||
|
||||
模拟手指弹起。
|
||||
|
||||
|
||||
@ -1,27 +1,28 @@
|
||||
"auto";
|
||||
var ra = new RootAutomator();
|
||||
ra.setScreenMetrics(1080, 1920);
|
||||
|
||||
setScreenMetrics(1080, 1920);
|
||||
launchApp("QQ");
|
||||
|
||||
sleep(1500);
|
||||
|
||||
//点击动态图标
|
||||
Tap(891, 1851);
|
||||
ra.tap(891, 1851);
|
||||
//点击好友动态
|
||||
Tap(192, 453);
|
||||
ra.tap(192, 453);
|
||||
//点击头像
|
||||
Tap(155, 638);
|
||||
ra.tap(155, 638);
|
||||
//点击留言
|
||||
Tap(747, 775);
|
||||
ra.tap(747, 775);
|
||||
|
||||
while(true){
|
||||
if(currentPackage() == 'com.tencent.mobileqq'){
|
||||
//点击箭头图标
|
||||
Tap(1029, 433);
|
||||
ra.tap(1029, 433);
|
||||
//点击删除
|
||||
Tap(530, 820);
|
||||
ra.tap(530, 820);
|
||||
//点击确定
|
||||
Tap(331, 1122);
|
||||
ra.tap(331, 1122);
|
||||
}
|
||||
sleep(200);
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@ -2,7 +2,7 @@ module.exports = function(__runtime__, scope){
|
||||
function RootAutomator(){
|
||||
this.__ra__ = Object.create(new com.stardust.autojs.runtime.api.RootAutomator(scope.context));
|
||||
var methods = ["sendEvent", "touch", "setScreenMetrics", "touchX", "touchY", "sendSync", "sendMtSync", "tap",
|
||||
"swipe","touchDown", "touchUp", "touchMove", "getDefaultId", "setDefaultId", "exit"];
|
||||
"swipe", "press", "longPress", "touchDown", "touchUp", "touchMove", "getDefaultId", "setDefaultId", "exit"];
|
||||
for(var i = 0; i < methods.length; i++){
|
||||
var method = methods[i];
|
||||
this[method] = this.__ra__[method].bind(this.__ra__);
|
||||
|
||||
@ -5,18 +5,19 @@ module.exports = function(__runtime__, scope){
|
||||
var engines = {};
|
||||
|
||||
engines.execScript = function(name, script, config){
|
||||
config = fillConfig(config);
|
||||
return rtEngines.execScript(name, script, config);
|
||||
return rtEngines.execScript(name, script, fillConfig(config));
|
||||
}
|
||||
|
||||
engines.execScriptFile = function(path, config){
|
||||
config = fillConfig(config);
|
||||
return rtEngines.execScriptFile(path, config);
|
||||
return rtEngines.execScriptFile(path, fillConfig(config));
|
||||
}
|
||||
|
||||
engines.execAutoFile = function(path, config){
|
||||
config = fillConfig(config);
|
||||
return rtEngines.execAutoFile(path, config);
|
||||
return rtEngines.execAutoFile(path, fillConfig(config));
|
||||
}
|
||||
|
||||
engines.myEngine = function(){
|
||||
return scope.__engine__;
|
||||
}
|
||||
|
||||
engines.stopAll = rtEngines.stopAll.bind(rtEngines);
|
||||
|
||||
@ -45,17 +45,17 @@ module.exports = function(__runtime__, scope){
|
||||
return __runtime__.info.getLatestActivity();
|
||||
}
|
||||
|
||||
scope.waitForActivity = function(activity, delay){
|
||||
delay = delay || 200;
|
||||
scope.waitForActivity = function(activity, period){
|
||||
period = period || 200;
|
||||
while(scope.currentActivity() != activity){
|
||||
sleep(delay);
|
||||
sleep(period);
|
||||
}
|
||||
}
|
||||
|
||||
scope.waitForPackage = function(packageName, delay){
|
||||
delay = delay || 200;
|
||||
scope.waitForPackage = function(packageName, period){
|
||||
period = period || 200;
|
||||
while(scope.currentPackage() != packageName){
|
||||
sleep(delay);
|
||||
sleep(period);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -245,6 +245,7 @@ public class SimpleActionAutomator {
|
||||
mAccessibilityBridge.ensureServiceEnabled();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean performAction(SimpleAction simpleAction) {
|
||||
ensureAccessibilityServiceEnabled();
|
||||
|
||||
@ -28,6 +28,9 @@ public abstract class JavaScriptEngine extends ScriptEngine.AbstractScriptEngine
|
||||
}
|
||||
|
||||
public void setRuntime(ScriptRuntime runtime) {
|
||||
if (mRuntime != null) {
|
||||
throw new IllegalStateException("a runtime has been set");
|
||||
}
|
||||
mRuntime = runtime;
|
||||
put("__runtime__", runtime);
|
||||
}
|
||||
|
||||
@ -7,7 +7,10 @@ import android.util.Log;
|
||||
import com.stardust.autojs.runtime.api.AbstractShell;
|
||||
import com.stardust.autojs.runtime.api.ProcessShell;
|
||||
import com.stardust.autojs.core.inputevent.InputDevices;
|
||||
import com.stardust.autojs.runtime.api.Shell;
|
||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||
import com.stardust.autojs.script.AutoFileSource;
|
||||
import com.stardust.concurrent.VolatileBox;
|
||||
import com.stardust.pio.PFile;
|
||||
|
||||
import java.io.File;
|
||||
@ -34,7 +37,6 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
|
||||
public RootAutomatorEngine(Context context, String deviceNameOrPath) {
|
||||
mContext = context;
|
||||
mDeviceNameOrPath = getDeviceNameOrPath(context, deviceNameOrPath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -42,14 +44,14 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
|
||||
this(context, InputDevices.getTouchDeviceName());
|
||||
}
|
||||
|
||||
public AbstractShell.Result execute(String autoFile) {
|
||||
public void execute(String autoFile) {
|
||||
mExecutablePath = getExecutablePath(mContext);
|
||||
AbstractShell.Result r = ProcessShell.execCommand(new String[]{
|
||||
Log.d(LOG_TAG, "exec: " + autoFile);
|
||||
AbstractShell.Result result = ProcessShell.execCommand(new String[]{
|
||||
"chmod 777 " + mExecutablePath,
|
||||
mExecutablePath + " \"" + autoFile + "\" -d " + mDeviceNameOrPath
|
||||
}, true);
|
||||
Log.d(LOG_TAG, "exec: " + autoFile + " result:" + r);
|
||||
return r;
|
||||
Log.d(LOG_TAG, "result = " + result);
|
||||
}
|
||||
|
||||
|
||||
@ -90,17 +92,24 @@ public class RootAutomatorEngine extends ScriptEngine.AbstractScriptEngine<AutoF
|
||||
|
||||
@Override
|
||||
public Object execute(AutoFileSource source) {
|
||||
return execute(source.getFile().getAbsolutePath());
|
||||
execute(source.getFile().getAbsolutePath());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forceStop() {
|
||||
ProcessShell.exec("killall " + mExecutablePath, true);
|
||||
mThread.interrupt();
|
||||
ProcessShell.exec("killall " + mExecutablePath, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
mThread = Thread.currentThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void destroy() {
|
||||
super.destroy();
|
||||
Log.d(LOG_TAG, "Shell exit");
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,6 +68,7 @@ public class ProcessShell extends AbstractShell {
|
||||
@Override
|
||||
public void exit() {
|
||||
if (mProcess != null) {
|
||||
Log.d(TAG, "exit: pid = " + ProcessUtils.getProcessPid(mProcess));
|
||||
mProcess.destroy();
|
||||
mProcess = null;
|
||||
}
|
||||
@ -195,11 +196,14 @@ public class ProcessShell extends AbstractShell {
|
||||
}
|
||||
os.writeBytes(COMMAND_EXIT);
|
||||
os.flush();
|
||||
Log.d(TAG, "pid = " + ProcessUtils.getProcessPid(process));
|
||||
commandResult.code = process.waitFor();
|
||||
commandResult.result = readAll(process.getInputStream());
|
||||
commandResult.error = readAll(process.getErrorStream());
|
||||
Log.d(TAG, commandResult.toString());
|
||||
} catch (Exception e) {
|
||||
commandResult.code = -1;
|
||||
commandResult.error = e.getMessage();
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
|
||||
@ -3,22 +3,26 @@ package com.stardust.autojs.runtime.api;
|
||||
import android.content.Context;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.stardust.autojs.core.inputevent.InputDevices;
|
||||
import com.stardust.autojs.engine.RootAutomatorEngine;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
import com.stardust.util.ScreenMetrics;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.*;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.ABS_MT_POSITION_X;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.ABS_MT_POSITION_Y;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.ABS_MT_TOUCH_MAJOR;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.ABS_MT_TRACKING_ID;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.BTN_TOOL_FINGER;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.BTN_TOUCH;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.EV_ABS;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.EV_KEY;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.EV_SYN;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.SYN_MT_REPORT;
|
||||
import static com.stardust.autojs.core.inputevent.InputEventCodes.SYN_REPORT;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/7/16.
|
||||
@ -124,6 +128,24 @@ public class RootAutomator {
|
||||
swipe(x1, y1, x2, y2, 300, mDefaultId);
|
||||
}
|
||||
|
||||
public void press(int x, int y, int duration, int id) throws IOException {
|
||||
touchDown(x, y, id);
|
||||
sleep(duration);
|
||||
touchUp(id);
|
||||
}
|
||||
|
||||
public void press(int x, int y, int duration) throws IOException {
|
||||
press(x, y, duration, getDefaultId());
|
||||
}
|
||||
|
||||
public void longPress(int x, int y, int id) throws IOException {
|
||||
press(x, y, ViewConfiguration.getLongPressTimeout() + 200, id);
|
||||
}
|
||||
|
||||
public void longPress(int x, int y) throws IOException {
|
||||
press(x, y, ViewConfiguration.getLongPressTimeout() + 200, getDefaultId());
|
||||
}
|
||||
|
||||
public void touchDown(int x, int y, int id) throws IOException {
|
||||
sendEvent(EV_ABS, ABS_MT_TRACKING_ID, id);
|
||||
sendEvent(EV_KEY, BTN_TOUCH, 0x00000001);
|
||||
@ -168,10 +190,11 @@ public class RootAutomator {
|
||||
mDefaultId = defaultId;
|
||||
}
|
||||
|
||||
private void sleep(long duration) {
|
||||
private void sleep(long duration) throws IOException {
|
||||
try {
|
||||
Thread.sleep(duration);
|
||||
} catch (InterruptedException e) {
|
||||
exit();
|
||||
throw new ScriptInterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +69,7 @@ public class Shell extends AbstractShell {
|
||||
private volatile RuntimeException mInitException;
|
||||
private volatile boolean mInitialized = false;
|
||||
private volatile boolean mWaitingExit = false;
|
||||
private final boolean mShouldReadOutput;
|
||||
private Callback mCallback;
|
||||
|
||||
public Shell(Context context) {
|
||||
@ -76,7 +77,12 @@ public class Shell extends AbstractShell {
|
||||
}
|
||||
|
||||
public Shell(Context context, boolean root) {
|
||||
this(context, root, true);
|
||||
}
|
||||
|
||||
public Shell(Context context, boolean root, boolean shouldReadOutput) {
|
||||
super(context, root);
|
||||
mShouldReadOutput = shouldReadOutput;
|
||||
}
|
||||
|
||||
public Shell() {
|
||||
@ -96,7 +102,7 @@ public class Shell extends AbstractShell {
|
||||
TermSettings settings = new TermSettings(mContext.getResources(), PreferenceManager.getDefaultSharedPreferences(mContext));
|
||||
try {
|
||||
mTermSession = new MyShellTermSession(settings, initialCommand);
|
||||
mTermSession.initializeEmulator(40, 40);
|
||||
mTermSession.initializeEmulator(1024, 40);
|
||||
} catch (IOException e) {
|
||||
mInitException = new UncheckedIOException(e);
|
||||
}
|
||||
@ -181,6 +187,9 @@ public class Shell extends AbstractShell {
|
||||
}
|
||||
}
|
||||
|
||||
public TermSession getTermSession() {
|
||||
return mTermSession;
|
||||
}
|
||||
|
||||
private class MyShellTermSession extends ShellTermSession {
|
||||
|
||||
@ -193,7 +202,9 @@ public class Shell extends AbstractShell {
|
||||
PipedInputStream pipedInputStream = new PipedInputStream(8192);
|
||||
mBufferedReader = new BufferedReader(new InputStreamReader(pipedInputStream));
|
||||
mOutputStream = new PipedOutputStream(pipedInputStream);
|
||||
startReadingThread();
|
||||
if (mShouldReadOutput) {
|
||||
startReadingThread();
|
||||
}
|
||||
}
|
||||
|
||||
private void startReadingThread() {
|
||||
@ -215,7 +226,7 @@ public class Shell extends AbstractShell {
|
||||
}
|
||||
|
||||
private void onNewLine(String line) {
|
||||
Log.d(TAG, line);
|
||||
//Log.d(TAG, line);
|
||||
if (!mInitialized) {
|
||||
if (isRoot() && line.endsWith(" $ su")) {
|
||||
notifyInitialized();
|
||||
@ -277,6 +288,8 @@ public class Shell extends AbstractShell {
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
if (!mShouldReadOutput)
|
||||
return;
|
||||
mReadingThread.interrupt();
|
||||
try {
|
||||
mBufferedReader.close();
|
||||
|
||||
@ -24,7 +24,7 @@ public class ProcessUtils {
|
||||
|
||||
}
|
||||
|
||||
private static int getProcessPid(Process process) {
|
||||
public static int getProcessPid(Process process) {
|
||||
try {
|
||||
Field pid = process.getClass().getDeclaredField("pid");
|
||||
pid.setAccessible(true);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user