9

The Handler in Android is used to send messages between classes. For example:

public class Foo
{

    private Handler handler;

    public Foo(Handler handler)
    {
        this.handler = handler;

        // ...
    }

    public void fooMethod()
    {
        // ...
        handler.obtainMessage("blah blah").sendToTarget();
    }

}

Main:

public class Main
{
    private Handler handler;

    public Main()
    {
        handler = new Handler()
        {
            @Override
            public void handleMessage(Message msg)
            {
                // handle the message that is sent from Foo
            }
        };

        Foo f = new Foo(handler);

        // ...
    }
}

So, I am looking for a similar technique in Java, or should I implement my own handler?

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • 3
    `Handler` is designed primarily to allow background threads to arrange for work to be accomplished on the main application thread (e.g., UI updates). Or, to quote [the documentation](http://developer.android.com/reference/android/os/Handler.html), "There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own." Using a `Handler` for other purposes is poor practice. – CommonsWare Mar 04 '12 at 21:07
  • @CommonsWare Thanks for the advice. I just want to use the mechanism that is used in Handler (i.e I want to redirect a socket message comes across the internet via `Foo` class, and use it in `Main` class). – Eng.Fouad Mar 04 '12 at 21:17
  • Most OO developers would simply call a method on `Main` from an instance of `Foo`. – CommonsWare Mar 04 '12 at 21:25
  • @CommonsWare I didn't think about that. I will pass an instance of Main in the Foo constructor then call a method of Main inside Foo. Thanks again :) – Eng.Fouad Mar 04 '12 at 21:30
  • @Eng.Fouad You have written: `I will pass an instance of Main in the Foo constructor then call a method of Main inside Foo` I've tried your suggestion and it haven't worked! I loaded images from URL in background thread. So I had rubbish instead of correct pictures. – Nolesh Mar 20 '13 at 04:34
  • Related: http://stackoverflow.com/questions/30074890/how-to-remove-postdelayed-runnables-in-java – AlikElzin-kilaka May 07 '15 at 17:43

2 Answers2

3

I believe that you are looking for something like Observer Pattern, that makes easy the communication of an object to another.

See >>> http://www.javaworld.com/javaqa/2001-05/04-qa-0525-observer.html

Also >>> http://www.oodesign.com/observer-pattern.html

I hope I've helped...

3

There isn't one by default. But you can make your own custom class that does a similar thing. I made one like this:

import java.util.ArrayList;

public class Handler extends Object{

ArrayList<Message> messages;

public Handler(){
    messages = new ArrayList<>();
}

public final Message obtainMessage(int what, Object obj){
    Message message = new Message(what, obj, this);
    messages.add(message);
    return message;
}

public final Message obtainMessage(int what){
    Message message = new Message(what, this);
    messages.add(message);
    return message;
}

public void handleMessage(Message msg){
    messages.remove(msg);
}

public final boolean hasMessages(){
    return !messages.isEmpty();
}
}

you would then also need a custom Message class like this:

public class Message extends Object{

int mWhat;
Object mObj;
Handler mTarget;

public Message(int what, Object obj){
    mWhat = what;
    mObj = obj;
}

public Message(int what, Object obj, Handler target){
    mWhat = what;
    mObj = obj;
    mTarget = target;
}

public Message(int what, Handler target){
    mWhat = what;
    mTarget = target;
}

public Message(int what){
    mWhat = what;
}

public void sendToTarget(){
    mTarget.handleMessage(this);
}
}

You can use this Handler to communicate from a background thread to the UI thread, without disturbing the UI thread too much.

You can use this class in completely the same way as you would in Android: First you create an instance in your UI class:

final int MESSAGE_RECEIVED = 0;
Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.mWhat){
            case MESSAGE_RECEIVED:
                System.out.println("Message received.");
                updateStatus("Message received.");
                break;
        }
    }
};

Then you supply this Handler instance to your background thread:

Thread thread = new T1(handler);
thread.start();

And last, you send messages by the means of:

mHandler.obtainMessage(0).sendToTarget();

I tested this method on a sample applet program i did, and it seems to work perfectly. Although I'm not an expert java programmer, so there might be some downsides to this, that I'm not really aware of. If so, I would love to hear an educated explanation of why this isn't ok.

Hope this helps someone.

NOTE: The above Handler and Message classes (my code) do not provide the full functionality of Android.Handler and Android.Message.

ak93
  • 1,135
  • 16
  • 27
  • 2
    This is not actually the expected behavior. In android handleMessage will be executed on the thread were the Handler was created (because Handler is bounded to the thread where it was created. Even if looks like the usage is similar, the example you proposed it will run different than the Handler from Android. More explicit, the part of code from handleMessage will run on the thread (T1) not on the thread where the handler was created! – cmg_george Jun 15 '17 at 12:07
  • Thanks . As least, For quick migrate from Android to pure Java, it is enough . Next I should think the equivient..Maybe it is rxJava? – Yeung Apr 16 '18 at 04:23