import android.os.Handler; import android.os.Looper; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; /** * UI线程执行代码工具类 *
* 提供在工作线程同步执行主线程任务的能力,调用线程会阻塞直到任务完成。 * 适用于需要在工作线程中获取主线程操作结果的场景。 *
*/ public final class UiThreadSync { private static final Handler MAIN = new Handler(Looper.getMainLooper()); private static final long DEFAULT_TIMEOUT_MS = 5000; // 默认超时时间5秒 private UiThreadSync() { // 工具类,防止实例化 } /** * 在工作线程同步执行主线程任务 ** 如果调用线程已经是主线程,则直接执行任务;否则会将任务投递到主线程并等待执行完成。 * 注意:任务中不应包含需要消息队列的其他异步操作,以免导致死锁。 *
* * @param r 要执行的任务 * @throws RuntimeException 如果任务执行抛出异常、等待时被中断或超时 */ public static void runCode(Runnable r) { runCode(r, DEFAULT_TIMEOUT_MS); } /** * 在工作线程同步执行主线程任务(带超时控制) ** 如果调用线程已经是主线程,则直接执行任务;否则会将任务投递到主线程并等待执行完成。 *
* * @param r 要执行的任务 * @param timeoutMs 超时时间(毫秒),0表示无限等待 * @throws RuntimeException 如果任务执行抛出异常、等待时被中断或超时 * @throws IllegalArgumentException 如果timeoutMs为负数 */ public static void runCode(Runnable r, long timeoutMs) { if (r == null) { throw new NullPointerException("Runnable cannot be null"); } if (timeoutMs < 0) { throw new IllegalArgumentException("Timeout cannot be negative: " + timeoutMs); } // 如果已经在主线程,直接执行(不抛异常) if (Looper.myLooper() == Looper.getMainLooper()) { r.run(); return; } final CountDownLatch latch = new CountDownLatch(1); final AtomicReference