package com.hdl.sdk.sourceos.utils.thread; import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.MessageQueue; import androidx.annotation.NonNull; import java.lang.reflect.Method; import java.util.LinkedList; import java.util.concurrent.Executor; /** * Created by Tong on 2023/01/03. */ public class MainThreadExecutor implements Executor { private final LinkedList mQueue = new LinkedList<>(); private final IdleHandlerImpl mHandler = new IdleHandlerImpl(Looper.getMainLooper()); private final Handler mainHandler = new Handler(Looper.getMainLooper()); private MessageQueue mMessageQueue; private MainThreadExecutor() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { mMessageQueue = Looper.getMainLooper().getQueue(); } else { try { Method getQueue = Looper.class.getDeclaredMethod("getQueue"); mMessageQueue = (MessageQueue) getQueue.invoke(Looper.getMainLooper()); } catch (Exception e) { e.printStackTrace(); } } } private static class SingletonInstance { private static final MainThreadExecutor INSTANCE = new MainThreadExecutor(); } public static MainThreadExecutor getInstance() { return SingletonInstance.INSTANCE; } private class IdleHandlerImpl extends Handler implements MessageQueue.IdleHandler { public IdleHandlerImpl(@NonNull Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { Runnable r; synchronized (mQueue) { if (mQueue.size() == 0) { return; } r = mQueue.removeFirst(); } r.run(); synchronized (mQueue) { scheduleNextLocked(); } } @Override public boolean queueIdle() { handleMessage(null); //ture执行多次,false执行一次 return false; } } private static class IdleRunnable implements Runnable { Runnable mRunnable; IdleRunnable(Runnable r) { mRunnable = r; } public void run() { mRunnable.run(); } } @Override public void execute(Runnable command) { if (Looper.getMainLooper() == Looper.myLooper()) { command.run(); } else { mainHandler.post(command); } } public void post(Runnable runnable) { synchronized (mQueue) { mQueue.add(runnable); if (mQueue.size() == 1) { scheduleNextLocked(); } } } public void postIdle(final Runnable runnable) { post(new IdleRunnable(runnable)); } public void postIdle(final Runnable runnable, long delayMillis) { mHandler.postDelayed(runnable, delayMillis); } public void cancelAll() { synchronized (mQueue) { mQueue.clear(); } } public void flush() { LinkedList queue; synchronized (mQueue) { queue = new LinkedList<>(mQueue); mQueue.clear(); } for (Runnable r : queue) { r.run(); } } private void scheduleNextLocked() { if (mQueue.size() > 0) { Runnable peek = mQueue.getFirst(); if (peek instanceof IdleRunnable) { if (mMessageQueue != null) { mMessageQueue.addIdleHandler(mHandler); } } else { mHandler.sendEmptyMessage(1); } } } }