Stabilizing Android Home‑Page Refresh with UiAutomator and Multithreading

This article explains how to use UiAutomator scripts combined with Java multithreading to continuously refresh an Android app’s home page while capturing logs and performance metrics, including full code examples for command execution, timestamp handling, and test loops.

FunTester
FunTester
FunTester
Stabilizing Android Home‑Page Refresh with UiAutomator and Multithreading

The author needed to verify the stability and performance of an Android app when the home page is refreshed repeatedly. The solution involves writing a UiAutomator test script, executing it via an ADB command, and using Java multithreading to record logcat output and performance data concurrently.

Multithreaded Test Runner

package monkeytest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import source.Common;
import source.PerformanceThread;

public class HomeRefresh {
    public static String ADB_PATH = Common.ADB_PATH;
    public static String package_name = Common.HEAD_PAGEKAGE;

    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            Date start = Common.getInstance().getDate();
            Logcat logcat = new Logcat(); // create log recording thread
            PerformanceThread performanceThread = new PerformanceThread("homerefresh", package_name); // performance monitoring
            performanceThread.start();
            logcat.start();
            String command = "adb shell uiautomator runtest demo.jar --nohup -c happyjuzi.AppCase#testHomeRefresh";
            execCmdAdb(command, "homerefresh" + getNow() + ".log");
            logcat.stopLoacat();
            performanceThread.stopRecord();
            Date end = Common.getInstance().getDate();
            Common.getInstance().outputTimeDiffer(start, end);
        }
    }

    /**
     * Execute an ADB command.
     * @param cmd   Command string
     * @param fileName   Output file name
     */
    public static void execCmdAdb(String cmd, String fileName) {
        System.out.println("Executing command: " + cmd);
        String OSname = System.getProperty("os.name");
        Common.getInstance().saveToFile(Common.getInstance().getNow() + "Start!" + Common.LINE, fileName); // save start marker
        try {
            Process p = null;
            if (OSname.contains("Mac")) {
                p = Runtime.getRuntime().exec(ADB_PATH + cmd);
            } else {
                p = Runtime.getRuntime().exec("cmd /c " + cmd);
            }
            // Standard output
            InputStream input = p.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));
            String line = "";
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("//   ")) {
                    continue;
                }
                if (line.startsWith("//")) {
                    Common.getInstance().saveToFile(line, fileName); // save comment lines
                }
                if (line.contains("Exception")) {
                    Common.getInstance().saveToFile("error-homerefresh" + getNow(), "error-homerefresh" + getNow() + ".log");
                }
            }
            reader.close();
            input.close();
            // Error output
            InputStream errorInput = p.getErrorStream();
            BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorInput));
            String eline = "";
            while ((eline = errorReader.readLine()) != null) {
                Common.getInstance().saveToFile(eline, fileName); // save error lines
            }
            errorReader.close();
            errorInput.close();
        } catch (IOException e) {
            Common.getInstance().output("Execution " + cmd + " failed!");
            e.printStackTrace();
        }
        Common.getInstance().saveToFile(Common.LINE + Common.getInstance().getNow() + "End!", fileName); // save end marker
    }

    /**
     * Get current time formatted as MM-dd-HH-mm.
     * @return Timestamp string without year or seconds.
     */
    private static String getNow() {
        Date time = new Date();
        SimpleDateFormat now = new SimpleDateFormat("MM-dd-HH-mm");
        String c = now.format(time);
        return c;
    }

    public void output(String text) {
        System.out.println(text);
    }

    public void output(Object... object) {
        if (object.length == 1) {
            output(object[0].toString());
            return;
        }
        for (int i = 0; i < object.length; i++) {
            System.out.println("Item " + (i + 1) + ": " + object[i]);
        }
    }
}

Test Method for Repeated Refresh

public void testHeadHomeRefresh() {
    for (int i = 0; i < 20; i++) {
        startHead();
        waitForUiObjectByResourceId("com.ss.android.article.news:id/b_y");
        sleep(1000);
        for (int k = 0; k < 15; k++) {
            swipeDown();
            sleep(1500);
        }
        stopHead();
    }
}

The testHeadHomeRefresh method runs twenty cycles of opening the home page, waiting for a specific UI element, pausing, performing fifteen downward swipes with delays, and then closing the page, thereby simulating continuous user interaction for stability testing.

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 TestingmultithreadingADBUIAutomator
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.