Android多设备并发之启动Appium Service实现流程

1.adb devices命令检测连接到PC端的所有设备,获取到已连接到的PC端的设备信息

2.将设备信息 端口 相关信息保存在List集合中 首先要实现能够在Java中执行dos环境下的命令

代码如下:
public class CmdUtil {
public static Logger logger = Logger.getLogger(CmdUtil.class);
/**

  • 执行dos环境下命令工具方法
    /
    public static List execDosCmd(String cmdPara) {
    //1、实例化runtime对象,运行时对象
    Runtime runtime = Runtime.getRuntime();
    //2、通过runtime对象的exec方法去执行dos命令
    try {
    //exec方法新建一个新得进程,去执行dos命令,返回得是process对象-管理这个进程
    //cmd /c 打开窗口需要关闭
    Process process = runtime.exec(“cmd /c “+cmdPara);
    //IO操作
    //得到process对象的输入流
    InputStream inputStream = process.getInputStream();
    //字节流转换成字符流才能进行读取
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
    //读取里面的内容
    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    //读取到的每一行内容
    //初始化一个list集合,用于保存命令的结果输出
    List list = new ArrayList<>();
    String content =””;
    while((content=bufferedReader.readLine()) != null) {
    //判断Appium启动成功与否
    if(content.contains(“Appium REST http interface listener started on”)){
    logger.info(“Appium启动成功!!!”);
    }
    //把输出内容保存到list集合中
    list.add(content);
    }
    //返回给调用者
    return list;
    } catch (IOException e) {
    e.printStackTrace();
    }
    return null;
    }
    /
    *
    • 用来获取当前连接到PC端的所有设备deviceName
      */
      public static List getUdidList(){
      //1、执行adb devices命令
      List results = execDosCmd(“adb devices”);
      //初始化一个List集合,用来保存解析的结果
      List udidList = new ArrayList();
      for (int i = 0; i < results.size(); i++) {
      //3、跳过第一行List of devices attached,以及跳过最后空白行的处理
      if(i != 0 && i !=(results.size()-1)){
      //4、通过制表符分割字符串emulator-5554 device
      String line = results.get(i);
      String[] arr = line.split("\t");
      //把数组的第一个元素也就是deviceName保存到udidList中
      udidList.add(arr[0]);
      }
      }
      //如果当前没有设备链接上PC,没有必要继续执行下去
      if(udidList.size() == 0){
      //做日志
      logger.info(“当前没有设备链接到PC端,请检查”);
      System.exit(0);
      }
      return udidList;
      }
      }

3.检测端口是否被占用,如果有则杀死进程释放对应端口

public class PortUtil {
public static Logger logger = Logger.getLogger(PortUtil.class);
/**
* 获取端口列表 4723->4725->4727->…
* 8200->8202-8204->…
* @param startPort 起始端口 4723 / 8200
* @param deviceNum 设备的数量
/
public static List getPortList(int startPort,int deviceNum){
//保存所有的端口号的
List portList = new ArrayList();
while(portList.size() != deviceNum){
//端口的检测与释放
if(checkPortIfUsed(startPort)){
logger.info(“端口【”+startPort+"】被占用");
//根据端口号获取进程号,然后再杀死进程
int pid = getPidByPort(startPort);
killProcessByPid(pid);
}
portList.add(startPort);
startPort = startPort + 2;
}
return portList;
}
/
*
* 检测端口是否有被占用
/
public static Boolean checkPortIfUsed(int port){
List result = CmdUtil.execDosCmd("netstat -ano | findstr "+port);
if(result.size() == 0){
return false;
}else{
return true;
}
}
/
*
* 根据端口得到对应进程的PID
/
public static int getPidByPort(int port){
List result = CmdUtil.execDosCmd(“netstat -ano | findstr “+port);
for (int i = 0; i < result.size(); i++) {
//通过/s进行字符串的分割 获取第一行
String[] content = result.get(0).split(”\s”);
//数组的最后一个元素即为PID
//String类型转换成int
return Integer.parseInt(content[content.length-1]);
}
return 0;//正常退出
}
/
*
* 根据pid杀死对应的进程
*/
public static void killProcessByPid(int pid){
List result = CmdUtil.execDosCmd(“taskkill -f -pid “+pid);
if(result.get(0).contains(pid+””)){
logger.info(“杀死进程【”+pid+"】成功");
}
}
}

4.根据收集到的信息启动appium service,测试结束,杀死所有的Appium Server

/**

  • 管理Appium服务的工具类,启动/关闭
    /
    public class AppiumServerUtil {
    //初始化log4j日志对象
    public static Logger logger = Logger.getLogger(AppiumServerUtil.class);
    // Appium main.js的路径
    public static final String appiumJsPath = “C:\Users\Pactera\AppData\Local\Programs\Appium\resources\app\node_modules\appium\build\lib\main.js”;
    // Appium运行时日志的存储路径
    public static final String appiumLogPath = “D:\workspace2\app_test_cxq\log\appium.log”;
    //appium监听端口的集合
    public static List appiumPortList;
    //uiautomator2引擎集合
    public static List uiautomator2PortList;
    /
    *
    • 启动appium服务

    • @author caoqingqing

    • @date 2020年9月24日
      */
      public static void startAppiumServer(){
      // 1、得到所有的deviceName列表
      List udidList = CmdUtil.getUdidList();
      // 2、得到Appium监听的端口列表4723 4725 4727…
      // 3、组装所有启动Appium服务的命令与参数,类似于node main.js -a 127.0.0.1 -p 4723
      appiumPortList = PortUtil.getPortList(4723, udidList.size());
      uiautomator2PortList = PortUtil.getPortList(8200, udidList.size());
      // 3、组装所有启动Appium服务的命令与参数,类似于node main.js -a 127.0.0.1 -p 4723
      // --session-overried
      // 由设备的数量去决定启动Appium服务的命令参数有多少条
      for (int i = 0; i < udidList.size(); i++) {
      // Appium日志地址
      String logPath = appiumLogPath + “appium” + i + “.log”;
      String command = “node " + appiumJsPath + " -a 127.0.0.1” + " -p " + appiumPortList.get(i) + " --log "
      + logPath + " --session-override";
      //4、启动Appium Server
      //进程阻塞:第一个Appium起来之后常驻进程运行,运行第二条启动Appium的时候会出现阻塞的问题,整个程序是单进程
      //多线程–》每一个Appium Server都是通过单独的线程执行(Java自带的多线程)
      new Thread(new Runnable() {
      @Override
      public void run() {
      //启动Appium Server
      CmdUtil.execDosCmd(command);
      }
      }).start();

      }
      }
      /**

    • 测试结束,杀死所有的Appium Server
      */
      public static void stopAppiumServer(){
      logger.info("=测试结束,关闭所有的Appium Server==");
      for (Integer port : appiumPortList) {
      int pid = PortUtil.getPidByPort(port);
      PortUtil.killProcessByPid(pid);
      }
      }
      }

**tips:**由于appium的启动需要依赖于特定的端口,如果参数中的端口(如:4723)被占用,那么appium启动将会失败

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值