【Android】Android中MainHandlerUtils工具类

王者杯·14天创作挑战营·第5期 10w+人浏览 892人参与

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
MainHandlerUtils.post(() -> textView.setText("更新UI"));

postDelayed(Runnable, long)延迟在主线程执行任务延时执行某些 UI 动画、Toast 提示
MainHandlerUtils.postDelayed(() -> 
    Toast.makeText(context, "延迟2秒", Toast.LENGTH_SHORT).show(), 
2000);

remove(Runnable)移除已提交的任务取消定时任务、避免内存泄漏
MainHandlerUtils.remove(myRunnable);

isMainThread()判断当前线程是否为主线程在执行前做安全检查
if (MainHandlerUtils.isMainThread()) { 
    textView.setText("安全更新"); 
}

runOnMainThread(Runnable)如果在主线程直接执行,否则切回主线程写 UI 更新逻辑时避免多余切换
MainHandlerUtils.runOnMainThread(() -> textView.setText("安全UI更新"));

callOnMainThread(Callable<T>)在主线程执行并返回结果(阻塞调用线程)子线程需要同步获取主线程执行的结果
String result = MainHandlerUtils.callOnMainThread(() -> "主线程返回值");

callOnMainThreadAsync(Callable<T>, Callback<T>)在主线程执行并通过回调返回结果(非阻塞)子线程发起请求 → 主线程执行逻辑并异步返回 
MainHandlerUtils.callOnMainThreadAsync(() -> "主线程任务", new MainHandlerUtils.Callback<String>() { 
   public void onSuccess(String r) { 
      Log.d("Test", "结果:" + r); 
   } 
   public void onError(Exception e) { 
     e.printStackTrace(); 
   } 
});


🌟 总结推荐

  • 更新 UIrunOnMainThread()

  • 延时任务postDelayed()

  • 取消任务remove()

  • 同步获取结果(会阻塞) → callOnMainThread()

  • 异步获取结果(推荐) → callOnMainThreadAsync()


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值