最近在配合公司同事搭建移动端测试框架,其中需要维护设备池的连接。考虑到wifi连接的过程中可能存在网络中导致的ADB连接中断,所以做了一个小服务程序来保证设备池中有设备连接断开后,能再第一时间将设备重新连接。
需求:
- 获取需要维持连接的列表
- 检测连接状态,尝试连接所有没有连接的设备
实现思路:
- 子线程不断去检索出需要维持连接的状态信息,放到待连接队列中
- 另外的子线程去待连接队列中获取需要连接的设备然后尝试连接,并将最终的连接状态更新到数据库表中
技术要点:
-
多线程
-
线程池技术:
newScheduledThreadPool, scheduleAtFixedRate, scheduleWithFixedDelay
-
线程并发访问共享资源:
LinkedBlockingQueue
- 获取待连接设备
public class GetDeviceExecutor implements Runnable {
private DeviceModelDao mDao;
private ADB mADB;
private BlockingQueue<DeviceModel> mDeviceModels;
protected GetDeviceExecutor(DeviceModelDao pDao, ADB pADB, BlockingQueue<DeviceModel> pDeviceModels) {
if (pDao == null) {
throw new IllegalArgumentException("DeviceModelDao cannot be null...");
}
if (pADB == null) {
throw new IllegalArgumentException("DeviceModelDao cannot be null...");
}
if (pDeviceModels == null) {
throw new IllegalArgumentException("DeviceModelDao cannot be null...");
}
mDao = pDao;
mADB = pADB;
mDeviceModels = pDeviceModels;
}
@Override
public void run() {
List<DeviceModel> devices = mDao.getDevices();
List<DeviceModel> devicesConnectedByWIFI = mADB.getDevicesConnectedByWIFI();
// 获取需要连接的设备
devices.removeAll(devicesConnectedByWIFI);
// 获取需要连接的设备 且 不在当前连接队列中的设备
devices.removeAll(mDeviceModels);
// 把需要连接 且 不在当前待连接队列中的设备
for (DeviceModel device : devices) {
mDeviceModels.offer(device);
}
}
}
- 连接设备
public class ConnectDeviceExecutor implements Runnable {
private DeviceModelDao mDao;
private ADB mADB;
private BlockingQueue<DeviceModel> mDeviceModels;
protected ConnectDeviceExecutor(DeviceModelDao pDao, ADB pADB, BlockingQueue<DeviceModel> pDeviceModels) {
mDao = pDao;
mADB = pADB;
mDeviceModels = pDeviceModels;
}
@Override
public void run() {
for (DeviceModel device : mDeviceModels) {
System.out.println("Connect "+device.getUdid()+" ...");
int connected = mADB.connectDeviceByIp(device);
if (connected == 1) {
try {
mDeviceModels.take();
} catch (InterruptedException pE) {
pE.printStackTrace();
}
} else {
System.out.println(device.getUdid() + " connect failed...");
}
device.setState(connected);
mDao.updateDeviceModelState(device);
}
}
}
- 封装到ConnectService类中
public class ConnectService {
private ADB mADB;
private DeviceModelDao mDao;
/**
* 需要尝试连接的
*/
private BlockingQueue<DeviceModel> mDeviceModels;
private ScheduledExecutorService mExecutor = Executors.newScheduledThreadPool(3);
private final ConnectDeviceExecutor mConnectDeviceExecutor;
private final GetDeviceExecutor mGetDeviceExecutor;
protected ConnectService() {
mDao = new DeviceModelDao();
mADB = new ADB(new CommandLine(), new ADBParser());
mDeviceModels = new LinkedBlockingQueue<>(16);
mGetDeviceExecutor = new GetDeviceExecutor(mDao, mADB, mDeviceModels);
mConnectDeviceExecutor = new ConnectDeviceExecutor(mDao, mADB, mDeviceModels);
}
public void start() {
mExecutor.scheduleWithFixedDelay(mGetDeviceExecutor, 0, 3, TimeUnit.SECONDS);
mExecutor.scheduleAtFixedRate(mConnectDeviceExecutor, 0, 1, TimeUnit.SECONDS);
}
public void stop() {
mExecutor.shutdown();
}
public BlockingQueue<DeviceModel> getDeviceModels() {
return mDeviceModels;
}
}
网友评论