Bo_ Bo_ - 1 month ago 6
Java Question

How to make a runnable where the run code is able to access a variable provided in the trigger

I have a class listening to a websocket and when a message is received, it should execute some code depending on the message type.
Throughout my application I want to be able to register more listeners.

I created the following MessageListener class:

static class MessageListener {
private String triggerMessage;
private Runnable runnable;

MessageListener(String message, Runnable runnable) {
this.triggerMessage = message;
this.runnable = runnable;
}

private void trigger(String message) {
if (message.equals(triggerMessage)) {
runnable.run();
}
}
}


I add a listener like this:

ws.setListener(new IPDWebSocket.MessageListener("disconnect", new Runnable() {
@Override
public void run() {
Log.e("xx", "Received message: ");
}
}
)
);


When a message is received it will trigger the listeners like this:

for (int nr=0; nr < listeners.size(); nr++) {
listeners.get(nr).trigger(msg);
}


Now my problem is that in the Runnable I would like to be able to use the message variable. Something like this:

ws.setListener(new IPDWebSocket.MessageListener("disconnect", new Runnable() {
@Override
public void run() {
Log.e("xx", "Received message: " + message);
}
}
)
);


But obviously the variable "message" isn't defined anywhere.
Any idea's on how to get this implemented? Thanks heaps!

Answer Source

Instead of using Runnable you can use your own interface to achieve this scenario,

Ex Create one interface inside your MessageListener

static class MessageListener {
    private String triggerMessage;
    private MessageTriggerListener runnable;

    public interface MessageTriggerListener {
        public void onMessageReceived(String message);
    }

    MessageListener(String message, MessageTriggerListener runnable) {
        this.triggerMessage = message;
        this.runnable = runnable;
    }

    private void trigger(String message) {
        if (message.equals(triggerMessage)) {
            runnable.onMessageReceived(message);
        }
    }
}

And you can implement the listener like this,

ws.setListener(new IPDWebSocket.MessageListener("disconnect", new MessageListener.MessageTriggerListener() {
            @Override
            public void onMessageReceived(String message) {
                Log.e("xx", "Received message: " + message);
            }
        }
        )
);