Resolving Lingering Threads After Main Thread Completion in Android App Performance Testing

The article describes a situation where background threads continue running after the main thread ends during Android app performance testing, analyzes the cause—sleep calls in auxiliary threads—and demonstrates how to correctly terminate them using Thread.join and a helper method.

FunTester
FunTester
FunTester
Resolving Lingering Threads After Main Thread Completion in Android App Performance Testing

During Android app performance testing, the author encountered an issue where the main thread finished but the program kept running without obvious activity, later traced to auxiliary threads that remained in sleep() state.

Initial code creates several threads (StartApp, Logcat, PerformanceThread) and starts them without properly waiting for their completion, leading to lingering processes after the main loop ends.

Problematic thread implementations contain loops with sleep() calls that prevent the threads from terminating promptly, causing the observed behavior.

To fix the issue, the author moves WiFi‑switch logic into the StartApp thread and uses the join() method to ensure each auxiliary thread finishes before the main thread proceeds.

Corrected main method:

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(); // new start app thread
        Logcat logcat = new Logcat(); // new log thread
        PerformanceThread performanceThread = new PerformanceThread("monkey", package_name); // performance monitor
        performanceThread.start();
        startApp.start();
        logcat.start();
        execCmdAdb(command, "monkey" + getNow() + ".log");
        startApp.stopThread();
        logcat.stopLoacat();
        performanceThread.stopRecord();
        // wait for all threads to finish
        logcat.join();
        performanceThread.join();
        startApp.join();
        Date end = Common.getInstance().getDate();
        Common.getInstance().outputTimeDiffer(start, end, "第" + i + "次");
    }
    output("结束monkey了!");
}

Alternatively, a helper method can join multiple threads at once:

public static void joinThread(Thread... threads) {
    for (Thread thread : threads) {
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

By applying join() (or the joinThread helper), the main thread reliably waits for all child threads to complete, eliminating the confusing situation where the program appears to run without visible execution after the main thread ends.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaAndroidPerformance TestingmultithreadingThread Join
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.