HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Singleton holding and notifying registered listeners

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
registeredlistenersnotifyingsingletonandholding

Problem

Suppose I am listening for network changes with the following listener:

interface NetListener {

    void onNetworkAvailable(boolean isWifi);

    void onNetworkUnavailable();
}


I want to have an object, accessible from anywhere within the app, holding the registered NetListeners, that can trigger the appropriate methods when necessary. The solution I came up with is this "singleton":

class NetListenerManager {

    private static List _listeners = new CopyOnWriteArrayList();

    static void addListener(final NetListener listener) {
        if (null != listener) { _listeners.add(listener); }
    }

    static void removeListener(final NetListener listener) {
        if (null != listener) { _listeners.remove(listener); }
    }

    /**
     * Called when a network connection is available.
     */
    static void notifyOnNetworkAvailable(boolean isWifi) {
        for (NetListener listener : _listeners) { listener.onNetworkAvailable(isWifi); }
    }

    /**
     * Called when a network connection becomes unavailable.
     */
    static void notifyOnNetworkUnavailable() {
        for (NetListener listener : _listeners) { listener.onNetworkUnavailable(); }
    }

    private NetListenerManager() { /* Instantiation disabled. */ }

}


So whenever e.g. a network change broadcast is received, I call NetListenerManager.notifyOnNetworkAvailable or NetListenerManager.notifyOnNetworkUnavailable,
depending on the network state.

I’m wondering if this is a good solution or if there are better ways to implement this.
Thanks!

UPDATE no.2

This is the modified listener:

interface NetListener {

    static enum NetworkType {NO_NETWORK, WIFI, MOBILE}

    void onNetworkChange(NetworkType type);

}


And the manager:

```
public final class NetListenerManager {

private static final List NET_LISTENERS = new CopyOnWriteArrayList();
private static final BlockingQueue QUEUE = new LinkedBlockingQueue();

private static final Thread QUEUE_

Solution

(Disclaimer: I posted this as a comment first but feel like it should also be an answer)

You should consider to use enum as a singleton as proposed by Joshua Blochs in Effective Java. This will protect you from both serialization attacks and reflection attacks on your singleton instance.

Here is a post which discusses it a lot more in-depth.
https://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java/71399#71399

Context

StackExchange Code Review Q#36120, answer score: 4

Revisions (0)

No revisions yet.