package org.succlz123.blockanalyzer; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Process; import java.util.HashMap; import java.util.concurrent.FutureTask; /** * Created by succlz123 on 2016/12/16. */ public class HandlerThreads { public static final int THREAD_UI = 0; public static final int THREAD_REPORT = 1; public static final int THREAD_BACKGROUND = 2; public static final int THREAD_BACK_IO = 3; public static final int THREAD_SIZE = 4; /** 线程信息数组 */ private static final Handler[] INTERNAL_HANDLER_LIST = new Handler[THREAD_SIZE]; private static final String[] INTERNAL_THREAD_NAME_LIST = { "thread_ui", "thread_report", "thread_background", "thread_back_io", }; private static final Object LOCK = new Object(); private static final HashMap<String, Handler> HANDLER_MAP = new HashMap<>(4); // guardby LOCK /** * 派发任务 * * @param index 线程索引 * @param r Runnable */ public static void post(int index, Runnable r) { Handler handler = getHandler(index); handler.post(r); } public static void postDelayed(int index, Runnable r, long delayMillis) { Handler handler = getHandler(index); handler.postDelayed(r, delayMillis); } public static void postAtFront(int index, Runnable r) { Handler handler = getHandler(index); handler.postAtFrontOfQueue(r); } /** * 获取线程Handler * * @param index 线程索引 * @return 线程的Handler */ public static Handler getHandler(int index) { if (index < 0 || index >= THREAD_SIZE) { throw new IndexOutOfBoundsException(); } if (INTERNAL_HANDLER_LIST[index] == null) { synchronized (INTERNAL_HANDLER_LIST) { Handler handler; if (index == THREAD_UI) { handler = new Handler(Looper.getMainLooper()); } else { HandlerThread thread = new HandlerThread(INTERNAL_THREAD_NAME_LIST[index], Process.THREAD_PRIORITY_DEFAULT + Process.THREAD_PRIORITY_LESS_FAVORABLE); thread.start(); handler = new Handler(thread.getLooper()); } INTERNAL_HANDLER_LIST[index] = handler; } } return INTERNAL_HANDLER_LIST[index]; } /** * Gets or creates a handler instance with specified name * * @param tname unique handler thread name, null means to UI handler * @return the handler instance */ public static Handler getHandler(String tname) { if (tname == null) { return getHandler(THREAD_UI); } tname = tname.intern(); Handler handler = HANDLER_MAP.get(tname); if (handler == null) { synchronized (LOCK) { handler = HANDLER_MAP.get(tname); if (handler != null) { return handler; } // normal priority HandlerThread thread = new HandlerThread(tname); thread.start(); handler = new Handler(thread.getLooper()); HANDLER_MAP.put(tname, handler); } } return handler; } public static Looper getLooper(int index) { return getHandler(index).getLooper(); } /** * Gets or creates a Looper instance belong with specified name Handler thread * * @param tname unique handler thread name, null means to UI handler * @return the Looper instance */ public static Looper getLooper(String tname) { return getHandler(tname).getLooper(); } /** * @return true if the current thread is the specified handler thread. */ public static boolean runningOn(int index) { return getHandler(index).getLooper() == Looper.myLooper(); } /** * @return true if the current thread is the specified handler thread. */ public static boolean runningOn(String tname) { return getHandler(tname).getLooper() == Looper.myLooper(); } /** * Run the supplied Runnable on the thread. The method will block until the Runnable * completes. * * @param r The Runnable to run. */ public static void runOnBlocking(int index, final Runnable r) { if (runningOn(index)) { r.run(); } else { FutureTask<Void> task = new FutureTask<Void>(r, null); post(index, task); try { task.get(); } catch (Exception e) { throw new RuntimeException("Exception occured while waiting for runnable", e); } } } public static void runOn(int index, final Runnable r) { if (runningOn(index)) { r.run(); } else { post(index, r); } } /** * Removes callback in the specified handler thread */ public static void remove(int index, final Runnable r) { getHandler(index).removeCallbacks(r); } /** * Removes callback in the specified handler thread */ public static void remove(String tname, final Runnable r) { getHandler(tname).removeCallbacks(r); } }