-
-
Save markus2610/3786330 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Add WeakReference that refer equals() and hashCode() methods to reference object. | |
* | |
* @author Tomáš Procházka <<a href="mailto:[email protected]">[email protected]</a>> | |
* @version $Revision: 0$ ($Date: 30.11.2011 14:53:06$) | |
*/ | |
public class BetterWeakReference<T> extends WeakReference<T> { | |
/** | |
* Constructs a new weak reference to the given referent. The newly created | |
* reference is not registered with any reference queue. | |
* | |
* @param r the referent to track | |
*/ | |
public BetterWeakReference(T r) { | |
super(r); | |
} | |
/** | |
* Constructs a new weak reference to the given referent. The newly created | |
* reference is registered with the given reference queue. | |
* | |
* @param r the referent to track | |
* @param q the queue to register to the reference object with. A null value | |
* results in a weak reference that is not associated with any | |
* queue. | |
*/ | |
public BetterWeakReference(T r, ReferenceQueue<? super T> q) { | |
super(r, q); | |
} | |
@Override | |
public boolean equals(Object o) { | |
if (o instanceof WeakReference<?> && get() != null) { | |
return get().equals(((WeakReference<?>) o).get()); | |
} | |
return false; | |
} | |
@Override | |
public int hashCode() { | |
if (get() != null) { | |
return get().hashCode(); | |
} | |
return super.hashCode(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Global one way asynchronous notification mechanism between parts of application based on Handler class. | |
* For example from service to activities. | |
* | |
* <p> | |
* Notification are always delivered to the UI thread. | |
* </p> | |
* | |
* <p> | |
* This class keep all listeners as weak reference so it is save to add whole activities as listeners, but do not use | |
* anonymous listeners. | |
* </p> | |
* | |
* <p> | |
* Reference to this class should be obtained via <code>SL.get(getActivity(), GlobalObserverService.class)</code> | |
* </p> | |
* | |
* <p> | |
* <b>Usage:</b> | |
* </p> | |
* | |
* <p> | |
* Register listener: | |
* <code>SL.get(getActivity(), GlobalObserverService.class).addListener(R.id.message_update_completed, this);</code> | |
* </p> | |
* <p> | |
* Call listener: | |
* <code>SL.get(getActivity(), GlobalObserverService.class).addListener(R.id.message_update_completed, this);</code> | |
* </p> | |
* | |
* @author Tomáš Procházka <<a href="mailto:[email protected]">[email protected]</a>> | |
* @version $Revision: 0$ ($Date: 30.11.2011 11:55:53$) | |
*/ | |
public class GlobalHandlerService implements Callback { | |
Context mContext; | |
private Handler mhandler; | |
private SparseArray<List<BetterWeakReference<Callback>>> mListenersSpecific = new SparseArray<List<BetterWeakReference<Callback>>>(); | |
private List<BetterWeakReference<Callback>> mListenersUniversal = new ArrayList<BetterWeakReference<Callback>>(); | |
public GlobalHandlerService(Context context) { | |
super(); | |
this.mContext = context; | |
mhandler = new Handler(Looper.getMainLooper(), this); | |
} | |
/** | |
* @see android.os.Handler#sendMessage(android.os.Message) | |
*/ | |
public final boolean sendMessage(Message msg) { | |
return mhandler.sendMessage(msg); | |
} | |
/** | |
* @see android.os.Handler#sendEmptyMessage(int) | |
*/ | |
public final boolean sendEmptyMessage(int what) { | |
return mhandler.sendEmptyMessage(what); | |
} | |
/** | |
* @see android.os.Handler#sendEmptyMessageDelayed(int, long) | |
*/ | |
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { | |
return mhandler.sendEmptyMessageDelayed(what, delayMillis); | |
} | |
/** | |
* @see android.os.Handler#sendEmptyMessageAtTime(int, long) | |
*/ | |
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { | |
return mhandler.sendEmptyMessageAtTime(what, uptimeMillis); | |
} | |
/** | |
* @see android.os.Handler#sendMessageDelayed(android.os.Message, long) | |
*/ | |
public final boolean sendMessageDelayed(Message msg, long delayMillis) { | |
return mhandler.sendMessageDelayed(msg, delayMillis); | |
} | |
/** | |
* @see android.os.Handler#sendMessageAtTime(android.os.Message, long) | |
*/ | |
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { | |
return mhandler.sendMessageAtTime(msg, uptimeMillis); | |
} | |
/** | |
* @see android.os.Handler#sendMessageAtFrontOfQueue(android.os.Message) | |
*/ | |
public final boolean sendMessageAtFrontOfQueue(Message msg) { | |
return mhandler.sendMessageAtFrontOfQueue(msg); | |
} | |
/** | |
* @see android.os.Handler#removeMessages(int) | |
*/ | |
public final void removeMessages(int what) { | |
mhandler.removeMessages(what); | |
} | |
/** | |
* @see android.os.Handler#removeMessages(int, java.lang.Object) | |
*/ | |
public final void removeMessages(int what, Object object) { | |
mhandler.removeMessages(what, object); | |
} | |
public Handler getHandler() { | |
return mhandler; | |
} | |
/** | |
* Add listener for specific type of message by its {@link Message#what}. | |
* | |
* @param what ID of message that will be only notified to listener | |
* @param listener | |
*/ | |
public synchronized void addListener(int what, Callback listener) { | |
List<BetterWeakReference<Callback>> whatListofListeners = mListenersSpecific.get(what); | |
if (whatListofListeners == null) { | |
whatListofListeners = new ArrayList<BetterWeakReference<Callback>>(); | |
mListenersSpecific.put(what, whatListofListeners); | |
} | |
BetterWeakReference<Callback> r = new BetterWeakReference<Handler.Callback>(listener); | |
if (!whatListofListeners.contains(r)) { | |
whatListofListeners.add(r); | |
} | |
} | |
/** | |
* Add listener for all messages. | |
* | |
* @param listener | |
*/ | |
public synchronized void addListener(Callback listener) { | |
BetterWeakReference<Callback> r = new BetterWeakReference<Handler.Callback>(listener); | |
if (!mListenersUniversal.contains(r)) { | |
mListenersUniversal.add(r); | |
} | |
} | |
/** | |
* Remove listener for specific type of message by its {@link Message#what}. | |
* | |
* @param what The id of the message to stop listening to. | |
* @param listener The listener to remove. | |
*/ | |
public synchronized void removeListener(int what, Callback listener) { | |
List<BetterWeakReference<Callback>> whatListofListeners = mListenersSpecific.get(what); | |
if (whatListofListeners == null) { | |
return; | |
} | |
BetterWeakReference<Callback> r = new BetterWeakReference<Handler.Callback>(listener); | |
if (whatListofListeners.contains(r)) { | |
whatListofListeners.remove(r); | |
} | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see android.os.Handler.Callback#handleMessage(android.os.Message) | |
*/ | |
@Override | |
public boolean handleMessage(Message msg) { | |
// proces listeners for specified type of message what | |
synchronized (mListenersSpecific) { | |
List<BetterWeakReference<Callback>> whatListofListeners = mListenersSpecific.get(msg.what); | |
if (whatListofListeners != null) { | |
handleListeners(whatListofListeners, msg); | |
if (whatListofListeners.size() == 0) { | |
mListenersSpecific.remove(msg.what); | |
} | |
} | |
} | |
// process universal listeners | |
handleListeners(mListenersUniversal, msg); | |
return true; | |
} | |
private void handleListeners(List<BetterWeakReference<Callback>> whatListofListeners, Message msg) { | |
synchronized (whatListofListeners) { | |
for (BetterWeakReference<Callback> ComparableWeakReference : whatListofListeners) { | |
if (ComparableWeakReference.get() != null) { | |
ComparableWeakReference.get().handleMessage(msg); | |
} else { | |
whatListofListeners.remove(ComparableWeakReference); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment