FjjF
FjjF

Reputation: 87

Aren't HANDLER supossed to have a Thread of their own?

I'm really frustrated now.

I'm trying to do a socket connection but I always get the NetworkOnMainThread Exception.

My goal is to create an object which has the thread, socket and Messenger model to comunicate using exclusively that object, like so:

WebBridge wb = new WebBridge(); 
wb.Send("My data to send", myLocalMessengerForAnswer);

I tried to use a Handler with the same result. Also I tried this, creating my own thread with a Handler of its own, but no success.

Aren't handler supossed to have their own Thread? Why am I getting the NetworkInMainThread Exception if I'm supposed to be in the Handler's thread?

Thanks in advance.

public class WebBridge {
    private class WebBridgeThread extends Thread {
    static final int STARTUP = 1;

    public Handler handler;
    Socket socket;

    public WebBridgeThread() {
        super("WebBridgeThread");
    }

    @Override
    public void run() {
        Looper.prepare();
        handler = new Handler() {
            @Override
            public void dispatchMessage(Message msg) {
                // TODO Auto-generated method stub
                super.dispatchMessage(msg);
                switch(msg.what) {
                    case STARTUP:
                    try {
                        socket = new Socket("192.168.100.99",1234);
                        int fer = 5;
                    } catch (UnknownHostException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    break;
                }
            }
        };
        Looper.loop();
    }


}


public WebBridge(Context paramContext) {
    WebBridgeThread wbt = new WebBridgeThread();
    wbt.start();
    Message msg = new Message();
    msg.what = WebBridgeThread.STARTUP;
    wbt.handler.dispatchMessage(msg);
}

Upvotes: 2

Views: 49

Answers (1)

Gil Vegliach
Gil Vegliach

Reputation: 3572

Why am I getting the NetworkInMainThread Exception if I'm supposed to be in the Handler's thread?

If you check the code for Handler, you will see that dispatchMessage() basically calls handleMessage(), which means it runs on the current thread, i.e. the UI thread in your case.

Instead, if you call sendMessage(), handler will enqueue the message and run the logic in handleMessage() on the thread with the looper, i.e. the background thread in your case. (Under the hood Looper.loop() calls directly dispatchMessage() after dequeueing a message from the queue; here the current thread is the thread with the looper)

So you need to:

  1. Use sendMessage() in WebBridge() instead of dispatchMessage()
  2. Override handleMessage() instead of dispatchMessage() in the Handler

Setting the thread priority to background would also be a good idea, so you won't race so much with the UI thread.

By the way, you could also use a HandlerThread which does the hard work for you, it creates a new thread and sets its priority. Then, after you start it, you can get its looper (getLooper()) and push it in the constructor of a handler. You still need to override handleMessage() in the handler for your network logic.

Upvotes: 3

Related Questions