本人在做APP性能测试的过程中,曾经遇到过一个比较尴尬的问题,主线程已经结束,但是程序依然在执行,但没有找到在执行什么,一时非常苦恼。先分享一下自己的代码,再说我找到的原因。

public static void main(String[] args) {
String timess = args[0];
int times = Common.getInstance().changeStringToInt(timess);
for (int i = 0; i < times; i++) {
Date start = Common.getInstance().getDate();
StartApp startApp = new StartApp();// 新建启动app线程
Logcat logcat = new Logcat();// 新建记录log线程
PerformanceThread performanceThread = new PerformanceThread("monkey", package_name);// 性能监控
performanceThread.start();
startApp.start();
logcat.start();
execCmdAdb(command, "monkey" + getNow() + ".log");
startApp.stopThread();
logcat.stopLoacat();
performanceThread.stopRecord();
Date end = Common.getInstance().getDate();
Common.getInstance().outputTimeDiffer(start, end, "第" + i + "次");
}
output("结束monkey了!");
}

就是新启了几个线程,我猜测应该是这些线程没有很好的结束掉,导致后面出现很多问题。经过检查发现在启动APP的线程里面。这个线程做的事情就是每分钟启动一次APP,并检查一下WiFi状态,使WiFi保持开/关,十分钟反转一下WiFi的状态。主线程结束后,这些进程还在sleep()休眠状态,所以才会没找到执行的代码。分享一下这个类有问题的代码:

@Override
public void run() {
while (MKEY) {
int num = Common.getInstance().getRandomInt(4);
if (num == 1) {
stopJuziApp();
Common.getInstance().sleep(500);
}
Common.getInstance().sleep(60 * 1000);
keepWifiONorOFF(WIFISTATUS);
startJuziApp();
}
}
public void run() {
while (WIFIKEY) {
for (int i = 0; i < 10; i++) {
if (WIFIKEY) {
break;
}
Common.getInstance().sleep(60 * 1000);
keepWifiONorOFF(WIFISTATUS);
}
WIFISTATUS = !WIFISTATUS;// 反转WiFi状态
}
}


就是因为这里面的sleep()导致了之前的原因,后来我把WiFiswitch的代码改掉了,放在startAPP里面方法里面了。然后在用java多线程里面的join方法在每个线程加入到主线程,这样就可以避免主线程结束而其他线程还在运行的尴尬了。分享改之后的代码:

public static void main(String[] args) throws InterruptedException {
String timess = args[0];
int times = Common.getInstance().changeStringToInt(timess);
for (int i = 0; i < times; i++) {
Date start = Common.getInstance().getDate();
StartApp startApp = new StartApp();// 新建启动app线程
Logcat logcat = new Logcat();// 新建记录log线程
PerformanceThread performanceThread = new PerformanceThread("monkey", package_name);// 性能监控
performanceThread.start();
startApp.start();
logcat.start();
execCmdAdb(command, "monkey" + getNow() + ".log");
startApp.stopThread();
logcat.stopLoacat();
performanceThread.stopRecord();
logcat.join();
performanceThread.join();
startApp.join();
Date end = Common.getInstance().getDate();
Common.getInstance().outputTimeDiffer(start, end, "第" + i + "次");
}
output("结束monkey了!");
}

或者可以封装一个方法来完成:

    public static void main(String[] args) throws InterruptedException {
String timess = args[0];
int times = Common.getInstance().changeStringToInt(timess);
for (int i = 0; i < times; i++) {
Date start = Common.getInstance().getDate();
StartApp startApp = new StartApp();// 新建启动app线程
Logcat logcat = new Logcat();// 新建记录log线程
PerformanceThread performanceThread = new PerformanceThread("monkey", package_name);// 性能监控
performanceThread.start();
startApp.start();
logcat.start();
execCmdAdb(command, "monkey" + getNow() + ".log");
startApp.stopThread();
logcat.stopLoacat();
performanceThread.stopRecord();
joinThread(logcat, startApp, performanceThread);
Date end = Common.getInstance().getDate();
Common.getInstance().outputTimeDiffer(start, end, "第" + i + "次");
}
output("结束monkey了!");
}

/**
* 把所有线程加入到主线程里面
*
* @param threads
*/
public static void joinThread(Thread... threads) {
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}