Java 版本 MainHandlerUtils.java
package com.example.utils;
import android.os.Handler;
import android.os.Looper;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* MainHandlerUtils 工具类
* 用于在主线程(UI线程)执行任务
*/
public final class MainHandlerUtils {
private static final Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());
private MainHandlerUtils() {
throw new UnsupportedOperationException("MainHandlerUtils cannot be instantiated");
}
public static void post(Runnable runnable) {
MAIN_HANDLER.post(runnable);
}
public static void postDelayed(Runnable runnable, long delayMillis) {
MAIN_HANDLER.postDelayed(runnable, delayMillis);
}
public static void remove(Runnable runnable) {
MAIN_HANDLER.removeCallbacks(runnable);
}
public static boolean isMainThread() {
return Looper.myLooper() == Looper.getMainLooper();
}
public static void runOnMainThread(Runnable runnable) {
if (isMainThread()) {
runnable.run();
} else {
post(runnable);
}
}
public static <T> T callOnMainThread(Callable<T> callable) throws ExecutionException, InterruptedException {
if (isMainThread()) {
try {
return callable.call();
} catch (Exception e) {
throw new ExecutionException(e);
}
} else {
FutureTask<T> task = new FutureTask<>(callable);
post(task);
return task.get();
}
}
/**
* 异步在主线程执行并通过回调返回结果(不会阻塞调用线程)
*/
public static <T> void callOnMainThreadAsync(final Callable<T> callable, final Callback<T> callback) {
post(() -> {
try {
T result = callable.call();
if (callback != null) {
callback.onSuccess(result);
}
} catch (Exception e) {
if (callback != null) {
callback.onError(e);
}
}
});
}
public static Handler getHandler() {
return MAIN_HANDLER;
}
/**
* 回调接口
*/
public interface Callback<T> {
void onSuccess(T result);
void onError(Exception e);
}
}
Kotlin 版本 MainHandlerUtils.kt
package com.example.utils
import android.os.Handler
import android.os.Looper
import java.util.concurrent.Callable
import java.util.concurrent.ExecutionException
import java.util.concurrent.FutureTask
/**
* MainHandlerUtils 工具类
* 用于在主线程(UI线程)执行任务
*/
object MainHandlerUtils {
private val mainHandler = Handler(Looper.getMainLooper())
@JvmStatic
fun post(runnable: Runnable) {
mainHandler.post(runnable)
}
@JvmStatic
fun postDelayed(runnable: Runnable, delayMillis: Long) {
mainHandler.postDelayed(runnable, delayMillis)
}
@JvmStatic
fun remove(runnable: Runnable) {
mainHandler.removeCallbacks(runnable)
}
@JvmStatic
fun isMainThread(): Boolean {
return Looper.myLooper() == Looper.getMainLooper()
}
@JvmStatic
fun runOnMainThread(runnable: Runnable) {
if (isMainThread()) {
runnable.run()
} else {
post(runnable)
}
}
@JvmStatic
@Throws(ExecutionException::class, InterruptedException::class)
fun <T> callOnMainThread(callable: Callable<T>): T {
return if (isMainThread()) {
try {
callable.call()
} catch (e: Exception) {
throw ExecutionException(e)
}
} else {
val task = FutureTask(callable)
post(task)
task.get()
}
}
/**
* 异步在主线程执行并通过回调返回结果(不会阻塞调用线程)
*/
@JvmStatic
fun <T> callOnMainThreadAsync(callable: Callable<T>, callback: Callback<T>?) {
post(Runnable {
try {
val result = callable.call()
callback?.onSuccess(result)
} catch (e: Exception) {
callback?.onError(e)
}
})
}
@JvmStatic
fun getHandler(): Handler = mainHandler
/**
* 回调接口
*/
interface Callback<T> {
fun onSuccess(result: T)
fun onError(e: Exception)
}
}
使用示例
// 子线程调用
new Thread(() -> {
MainHandlerUtils.callOnMainThreadAsync(() -> {
// 主线程执行逻辑
return "主线程执行完成";
}, new MainHandlerUtils.Callback<String>() {
@Override
public void onSuccess(String result) {
Log.d("Test", "异步回调结果: " + result);
}
@Override
public void onError(Exception e) {
e.printStackTrace();
}
});
}).start();
这样,工具类就有了 完整的主线程任务处理能力:
-
post / postDelayed / remove
→ 基础调度 -
runOnMainThread
→ 自动判断线程 -
callOnMainThread
→ 阻塞并返回结果 -
callOnMainThreadAsync
→ 非阻塞异步回调
常见使用场景 总结成一个对照表(比如 UI 更新、同步任务、异步回调)
把 MainHandlerUtils
的常见方法使用场景整理成一个对照表,方便你在不同业务场景下选择合适的方法。
📌 MainHandlerUtils
方法使用场景对照表
方法 | 功能描述 | 使用场景 | 示例 |
---|---|---|---|
post(Runnable) | 把任务投递到主线程执行 | 在子线程里需要更新 UI |
|
postDelayed(Runnable, long) | 延迟在主线程执行任务 | 延时执行某些 UI 动画、Toast 提示 |
|
remove(Runnable) | 移除已提交的任务 | 取消定时任务、避免内存泄漏 |
|
isMainThread() | 判断当前线程是否为主线程 | 在执行前做安全检查 |
|
runOnMainThread(Runnable) | 如果在主线程直接执行,否则切回主线程 | 写 UI 更新逻辑时避免多余切换 |
|
callOnMainThread(Callable<T>) | 在主线程执行并返回结果(阻塞调用线程) | 子线程需要同步获取主线程执行的结果 |
|
callOnMainThreadAsync(Callable<T>, Callback<T>) | 在主线程执行并通过回调返回结果(非阻塞) | 子线程发起请求 → 主线程执行逻辑并异步返回 |
|
🌟 总结推荐
-
更新 UI →
runOnMainThread()
-
延时任务 →
postDelayed()
-
取消任务 →
remove()
-
同步获取结果(会阻塞) →
callOnMainThread()
-
异步获取结果(推荐) →
callOnMainThreadAsync()