直接上示例然后进行源码解读
先看一下monkeyrunner基本操作脚本
device = mr.waitForConnection() #连接设备,等待
device.touch(300,300,'DOWN_AND_UP')
1、获取device实例,使用默认连接
public static MonkeyDevice waitForConnection(PyObject[] args, String[] kws) {
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
long timeoutMs;
try {
double timeoutInSecs = JythonUtils.getFloat(ap, 0);
timeoutMs = (long) (timeoutInSecs * 1000.0);
} catch (PyException e) {
timeoutMs = Long.MAX_VALUE;
}
IMonkeyDevice device = backend.waitForConnection(timeoutMs,
ap.getString(1, ".*"));
MonkeyDevice monkeyDevice = new MonkeyDevice(device);
return monkeyDevice;
}
这部分原理后续进行讲解
2、device是monkeyDevice的一个实例对象调用其方法touch();
public void touch(PyObject[] args, String[] kws) {
ArgParser ap = JythonUtils.createArgParser(args, kws);
Preconditions.checkNotNull(ap);
int x = ap.getInt(0);
int y = ap.getInt(1);
TouchPressType type = TouchPressType.fromIdentifier(ap.getString(2));
if (type == null) {
LOG.warning(String.format("Invalid TouchPressType specified (%s) default used instead",
ap.getString(2)));
type = TouchPressType.DOWN_AND_UP;
}
impl.touch(x, y, type); //
}
这里的PyObject[] args, String[] kws参数本来是没有的,应该是我下载源码的版本不对,这里直接传入xy坐标和类型就可以了都是调用一样的方法
3、imp是IMonkeyDevice的实例对象,他实现对应的类是AdbMonkeyDevice(public class AdbMonkeyDevice implements IMonkeyDevice),调用其touch方法
@Override
public void touch(int x, int y, TouchPressType type) {
try {
switch (type) {
case DOWN:
manager.touchDown(x, y);
break;
case UP:
manager.touchUp(x, y);
break;
case DOWN_AND_UP:
manager.tap(x, y);
break;
}
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending touch event: " + x + " " + y + " " + type, e);
}
}
manager又是MonkeyManager的实例对象,看他的构造函数
*/
public class MonkeyManager {
private static Logger LOG = Logger.getLogger(MonkeyManager.class.getName());
private Socket monkeySocket;
private BufferedWriter monkeyWriter;
private BufferedReader monkeyReader;
/**
* Create a new MonkeyMananger to talk to the specified device.
*
* @param monkeySocket the already connected socket on which to send protocol messages.
*/
public MonkeyManager(Socket monkeySocket) {
try {
this.monkeySocket = monkeySocket;
monkeyWriter = new BufferedWriter(new OutputStreamWriter(monkeySocket.getOutputStream()));
monkeyReader = new BufferedReader(new InputStreamReader(monkeySocket.getInputStream()));
} catch(IOException e) {
throw new RuntimeException(e);
}
}
这里会新建一个socket端口的输入输出流,后面会用monkeyWriter这个实例写数据
AdbMonkeyDevice创建实例的时候会传入相关参数如下:
public class AdbMonkeyDevice implements IMonkeyDevice {
private static final Logger LOG = Logger.getLogger(AdbMonkeyDevice.class.getName());
private static final String[] ZERO_LENGTH_STRING_ARRAY = new String[0];
private static final long MANAGER_CREATE_TIMEOUT_MS = 30 * 1000; // 30 seconds
private static final long MANAGER_CREATE_WAIT_TIME_MS = 1000; // wait 1 second
private final ExecutorService executor = Executors.newCachedThreadPool();
private final IDevice device;
private MonkeyManager manager;
public AdbMonkeyDevice(IDevice device) {
this.device = device;
this.manager = createManager("127.0.0.1", 12345);
Preconditions.checkNotNull(this.manager);
}
这样就相对于创建AdbMonkeyDevice实例的时候也为MonkeyManager创建了一个socket端口用于发送命令参数
4、继续看
manager.tap(x, y);
这个方法,
public boolean touchUp(int x, int y) throws IOException {
return sendMonkeyEvent("touch up " + x + " " + y);
}
private boolean sendMonkeyEvent(String command) throws IOException {
synchronized (this) {
String monkeyResponse = sendMonkeyEventAndGetResponse(command);
return parseResponseForSuccess(monkeyResponse);
}
}
private String sendMonkeyEventAndGetResponse(String command) throws IOException {
command = command.trim();
LOG.info("Monkey Command: " + command + ".");
// send a single command and get the response
monkeyWriter.write(command + "\n");
monkeyWriter.flush();
return monkeyReader.readLine();
}
可以看到最终是调用MonkeyManager类的monkeyWriter.write(command + "\n");这个来往socket端口写入数据的,
monkeyReader.readLine();这个是socket端口返回来的响应码