package com.linkdialy.mobile.kuyicloud.utils; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import java.lang.ref.WeakReference; /** * time: 15/7/1 * description: 对原生handler进行封装 * * @author sunjianfei */ public class WeakHandler { private final Handler.Callback mCallback; private final ExecHandler mExec; private final ChainedRef mRunnables = new ChainedRef((Runnable) null); public WeakHandler() { this.mCallback = null; this.mExec = new ExecHandler(); } public WeakHandler(@Nullable Handler.Callback callback) { this.mCallback = callback; this.mExec = new ExecHandler(new WeakReference(callback)); } public WeakHandler(@NonNull Looper looper) { this.mCallback = null; this.mExec = new ExecHandler(looper); } public WeakHandler(@NonNull Looper looper, @NonNull Handler.Callback callback) { this.mCallback = callback; this.mExec = new ExecHandler(looper, new WeakReference(callback)); } public final boolean post(@NonNull Runnable r) { return this.mExec.post(this.wrapRunnable(r)); } public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) { return this.mExec.postAtTime(this.wrapRunnable(r), uptimeMillis); } public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) { return this.mExec.postAtTime(this.wrapRunnable(r), token, uptimeMillis); } public final boolean postDelayed(Runnable r, long delayMillis) { return this.mExec.postDelayed(this.wrapRunnable(r), delayMillis); } public final boolean postAtFrontOfQueue(Runnable r) { return this.mExec.postAtFrontOfQueue(this.wrapRunnable(r)); } public final void removeCallbacks(Runnable r) { ChainedRef runnableRef = this.mRunnables.findForward(r); if (runnableRef != null) { this.mExec.removeCallbacks(runnableRef.wrapper); } } public final void removeCallbacks(Runnable r, Object token) { ChainedRef runnableRef = this.mRunnables.findForward(r); if (runnableRef != null) { this.mExec.removeCallbacks(runnableRef.wrapper, token); } } public final boolean sendMessage(Message msg) { return this.mExec.sendMessage(msg); } public final boolean sendEmptyMessage(int what) { return this.mExec.sendEmptyMessage(what); } public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { return this.mExec.sendEmptyMessageDelayed(what, delayMillis); } public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { return this.mExec.sendEmptyMessageAtTime(what, uptimeMillis); } public final boolean sendMessageDelayed(Message msg, long delayMillis) { return this.mExec.sendMessageDelayed(msg, delayMillis); } public boolean sendMessageAtTime(Message msg, long uptimeMillis) { return this.mExec.sendMessageAtTime(msg, uptimeMillis); } public final boolean sendMessageAtFrontOfQueue(Message msg) { return this.mExec.sendMessageAtFrontOfQueue(msg); } public final void removeMessages(int what) { this.mExec.removeMessages(what); } public final void removeMessages(int what, Object object) { this.mExec.removeMessages(what, object); } public final void removeCallbacksAndMessages(Object token) { this.mExec.removeCallbacksAndMessages(token); } public final boolean hasMessages(int what) { return this.mExec.hasMessages(what); } public final boolean hasMessages(int what, Object object) { return this.mExec.hasMessages(what, object); } public final Looper getLooper() { return this.mExec.getLooper(); } private WeakRunnable wrapRunnable(Runnable r) { ChainedRef hardRef = ChainedRef.obtain(r); this.mRunnables.insertAbove(hardRef); return hardRef.wrapper = new WeakRunnable(new WeakReference(r), new WeakReference(hardRef)); } static class ChainedRef { @Nullable ChainedRef next; @Nullable ChainedRef prev; @Nullable Runnable runnable; @Nullable WeakRunnable wrapper; @Nullable static ChainedRef sPool; static int sPoolSize; static final int MAX_POOL_SIZE = 15; public ChainedRef(Runnable r) { this.runnable = r; } public void remove() { if (this.prev != null) { this.prev.next = this.next; } if (this.next != null) { this.next.prev = this.prev; } this.prev = null; this.runnable = null; this.wrapper = null; Class var1 = ChainedRef.class; synchronized (ChainedRef.class) { if (sPoolSize <= 15) { this.next = sPool; sPool = this; ++sPoolSize; } } } public void insertAbove(@NonNull ChainedRef candidate) { if (this.next != null) { this.next.prev = candidate; } candidate.next = this.next; this.next = candidate; candidate.prev = this; } @Nullable public ChainedRef findForward(Runnable obj) { for (ChainedRef curr = this; curr != null; curr = curr.next) { if (curr.runnable != null) { if (curr.runnable.equals(obj)) { return curr; } } else if (obj == null) { return curr; } } return null; } public static ChainedRef obtain(Runnable r) { ChainedRef result = null; Class var2 = ChainedRef.class; synchronized (ChainedRef.class) { if (sPool != null) { result = sPool; sPool = sPool.next; --sPoolSize; } } if (result != null) { result.runnable = r; return result; } else { return new ChainedRef(r); } } } static class WeakRunnable implements Runnable { private final WeakReference mDelegate; private final WeakReference mReference; WeakRunnable(WeakReference delegate, WeakReference reference) { this.mDelegate = delegate; this.mReference = reference; } public void run() { Runnable delegate = (Runnable) this.mDelegate.get(); ChainedRef reference = (ChainedRef) this.mReference.get(); if (reference != null) { reference.remove(); } if (delegate != null) { delegate.run(); } } } private static class ExecHandler extends Handler { private final WeakReference mCallback; ExecHandler() { this.mCallback = null; } ExecHandler(WeakReference callback) { this.mCallback = callback; } ExecHandler(Looper looper) { super(looper); this.mCallback = null; } ExecHandler(Looper looper, WeakReference callback) { super(looper); this.mCallback = callback; } public void handleMessage(Message msg) { if (this.mCallback != null) { Callback callback = (Callback) this.mCallback.get(); if (callback != null) { callback.handleMessage(msg); } } } } }