领透酷医云安卓客户端

WeakHandler.java 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. package com.linkdialy.mobile.kuyicloud.utils;
  2. import android.os.Handler;
  3. import android.os.Looper;
  4. import android.os.Message;
  5. import android.support.annotation.NonNull;
  6. import android.support.annotation.Nullable;
  7. import java.lang.ref.WeakReference;
  8. /**
  9. * time: 15/7/1
  10. * description: 对原生handler进行封装
  11. *
  12. * @author sunjianfei
  13. */
  14. public class WeakHandler {
  15. private final Handler.Callback mCallback;
  16. private final ExecHandler mExec;
  17. private final ChainedRef mRunnables = new ChainedRef((Runnable) null);
  18. public WeakHandler() {
  19. this.mCallback = null;
  20. this.mExec = new ExecHandler();
  21. }
  22. public WeakHandler(@Nullable Handler.Callback callback) {
  23. this.mCallback = callback;
  24. this.mExec = new ExecHandler(new WeakReference(callback));
  25. }
  26. public WeakHandler(@NonNull Looper looper) {
  27. this.mCallback = null;
  28. this.mExec = new ExecHandler(looper);
  29. }
  30. public WeakHandler(@NonNull Looper looper, @NonNull Handler.Callback callback) {
  31. this.mCallback = callback;
  32. this.mExec = new ExecHandler(looper, new WeakReference(callback));
  33. }
  34. public final boolean post(@NonNull Runnable r) {
  35. return this.mExec.post(this.wrapRunnable(r));
  36. }
  37. public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
  38. return this.mExec.postAtTime(this.wrapRunnable(r), uptimeMillis);
  39. }
  40. public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) {
  41. return this.mExec.postAtTime(this.wrapRunnable(r), token, uptimeMillis);
  42. }
  43. public final boolean postDelayed(Runnable r, long delayMillis) {
  44. return this.mExec.postDelayed(this.wrapRunnable(r), delayMillis);
  45. }
  46. public final boolean postAtFrontOfQueue(Runnable r) {
  47. return this.mExec.postAtFrontOfQueue(this.wrapRunnable(r));
  48. }
  49. public final void removeCallbacks(Runnable r) {
  50. ChainedRef runnableRef = this.mRunnables.findForward(r);
  51. if (runnableRef != null) {
  52. this.mExec.removeCallbacks(runnableRef.wrapper);
  53. }
  54. }
  55. public final void removeCallbacks(Runnable r, Object token) {
  56. ChainedRef runnableRef = this.mRunnables.findForward(r);
  57. if (runnableRef != null) {
  58. this.mExec.removeCallbacks(runnableRef.wrapper, token);
  59. }
  60. }
  61. public final boolean sendMessage(Message msg) {
  62. return this.mExec.sendMessage(msg);
  63. }
  64. public final boolean sendEmptyMessage(int what) {
  65. return this.mExec.sendEmptyMessage(what);
  66. }
  67. public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
  68. return this.mExec.sendEmptyMessageDelayed(what, delayMillis);
  69. }
  70. public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
  71. return this.mExec.sendEmptyMessageAtTime(what, uptimeMillis);
  72. }
  73. public final boolean sendMessageDelayed(Message msg, long delayMillis) {
  74. return this.mExec.sendMessageDelayed(msg, delayMillis);
  75. }
  76. public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
  77. return this.mExec.sendMessageAtTime(msg, uptimeMillis);
  78. }
  79. public final boolean sendMessageAtFrontOfQueue(Message msg) {
  80. return this.mExec.sendMessageAtFrontOfQueue(msg);
  81. }
  82. public final void removeMessages(int what) {
  83. this.mExec.removeMessages(what);
  84. }
  85. public final void removeMessages(int what, Object object) {
  86. this.mExec.removeMessages(what, object);
  87. }
  88. public final void removeCallbacksAndMessages(Object token) {
  89. this.mExec.removeCallbacksAndMessages(token);
  90. }
  91. public final boolean hasMessages(int what) {
  92. return this.mExec.hasMessages(what);
  93. }
  94. public final boolean hasMessages(int what, Object object) {
  95. return this.mExec.hasMessages(what, object);
  96. }
  97. public final Looper getLooper() {
  98. return this.mExec.getLooper();
  99. }
  100. private WeakRunnable wrapRunnable(Runnable r) {
  101. ChainedRef hardRef = ChainedRef.obtain(r);
  102. this.mRunnables.insertAbove(hardRef);
  103. return hardRef.wrapper = new WeakRunnable(new WeakReference(r), new WeakReference(hardRef));
  104. }
  105. static class ChainedRef {
  106. @Nullable
  107. ChainedRef next;
  108. @Nullable
  109. ChainedRef prev;
  110. @Nullable
  111. Runnable runnable;
  112. @Nullable
  113. WeakRunnable wrapper;
  114. @Nullable
  115. static ChainedRef sPool;
  116. static int sPoolSize;
  117. static final int MAX_POOL_SIZE = 15;
  118. public ChainedRef(Runnable r) {
  119. this.runnable = r;
  120. }
  121. public void remove() {
  122. if (this.prev != null) {
  123. this.prev.next = this.next;
  124. }
  125. if (this.next != null) {
  126. this.next.prev = this.prev;
  127. }
  128. this.prev = null;
  129. this.runnable = null;
  130. this.wrapper = null;
  131. Class var1 = ChainedRef.class;
  132. synchronized (ChainedRef.class) {
  133. if (sPoolSize <= 15) {
  134. this.next = sPool;
  135. sPool = this;
  136. ++sPoolSize;
  137. }
  138. }
  139. }
  140. public void insertAbove(@NonNull ChainedRef candidate) {
  141. if (this.next != null) {
  142. this.next.prev = candidate;
  143. }
  144. candidate.next = this.next;
  145. this.next = candidate;
  146. candidate.prev = this;
  147. }
  148. @Nullable
  149. public ChainedRef findForward(Runnable obj) {
  150. for (ChainedRef curr = this; curr != null; curr = curr.next) {
  151. if (curr.runnable != null) {
  152. if (curr.runnable.equals(obj)) {
  153. return curr;
  154. }
  155. } else if (obj == null) {
  156. return curr;
  157. }
  158. }
  159. return null;
  160. }
  161. public static ChainedRef obtain(Runnable r) {
  162. ChainedRef result = null;
  163. Class var2 = ChainedRef.class;
  164. synchronized (ChainedRef.class) {
  165. if (sPool != null) {
  166. result = sPool;
  167. sPool = sPool.next;
  168. --sPoolSize;
  169. }
  170. }
  171. if (result != null) {
  172. result.runnable = r;
  173. return result;
  174. } else {
  175. return new ChainedRef(r);
  176. }
  177. }
  178. }
  179. static class WeakRunnable implements Runnable {
  180. private final WeakReference<Runnable> mDelegate;
  181. private final WeakReference<ChainedRef> mReference;
  182. WeakRunnable(WeakReference<Runnable> delegate, WeakReference<ChainedRef> reference) {
  183. this.mDelegate = delegate;
  184. this.mReference = reference;
  185. }
  186. public void run() {
  187. Runnable delegate = (Runnable) this.mDelegate.get();
  188. ChainedRef reference = (ChainedRef) this.mReference.get();
  189. if (reference != null) {
  190. reference.remove();
  191. }
  192. if (delegate != null) {
  193. delegate.run();
  194. }
  195. }
  196. }
  197. private static class ExecHandler extends Handler {
  198. private final WeakReference<Callback> mCallback;
  199. ExecHandler() {
  200. this.mCallback = null;
  201. }
  202. ExecHandler(WeakReference<Callback> callback) {
  203. this.mCallback = callback;
  204. }
  205. ExecHandler(Looper looper) {
  206. super(looper);
  207. this.mCallback = null;
  208. }
  209. ExecHandler(Looper looper, WeakReference<Callback> callback) {
  210. super(looper);
  211. this.mCallback = callback;
  212. }
  213. public void handleMessage(Message msg) {
  214. if (this.mCallback != null) {
  215. Callback callback = (Callback) this.mCallback.get();
  216. if (callback != null) {
  217. callback.handleMessage(msg);
  218. }
  219. }
  220. }
  221. }
  222. }