Android send data from main UI thread to another thread

后端 未结 3 1560
忘了有多久
忘了有多久 2021-02-10 02:44

I need to send some data from the main thread to another thread. I\'ve already read a lot of materials on threads, asynctasks and handlers but maybe they created some confusion

3条回答
  •  不思量自难忘°
    2021-02-10 03:09

    You can't do it this way. You've created your second Thread by using HandlerThread. A HandlerThread is a Thread that has a Looper. So that is what is going on in the run() method of HandlerThread. It is running the looper loop. That means that the run() method in the HandlerThread will only complete when the Looper exits.

    In your initThread() method you wrote:

        @Override
        public void run() {
            super.run(); // <-- This call runs the Looper loop and doesn't complete!!
            try{
                handler = new WorkerHandler(getLooper());
            }catch(Exception e){
                e.printStackTrace();
            }               
        }
    

    You can see that your overridden run() method first calls super.run(). This runs the looper loop and doesn't complete. So the rest of your code in initThread() never executes.

    If you want to use a HandlerThread() then you can't mess with its run() method. If you want it to do stuff for you then you'll need to post messages (or Runnables) to it, and do your work there. Here's an example:

        HandlerThread handlerThread = new HandlerThread("myHandlerThread");
        handlerThread.start();
        // Now get the Looper from the HandlerThread so that we can create a Handler that is attached to
        // the HandlerThread
        // NOTE: This call will block until the HandlerThread gets control and initializes its Looper
        Looper looper = handlerThread.getLooper();
        // Create a handler attached to the background message processing thread
        handler = new Handler(looper, this);
    

    Now you can post messages and Runnables to the "handler". In this example, the messages will be processed by an overridden handleMessage() method of the creating class.

    EDIT: Provide code example for the Handler callback

    You can use your WorkerHandler class to handle the callbacks if you modify it like this (I've changed the name to Worker because it isn't really a Handler, it just implements the Handler.Callback interface):

    public class Worker implements Handler.Callback {
    
        protected Socket socket;
        protected BufferedWriter writer;
    
        public Worker() throws Exception{    
            this.socket = new Socket("192.168.1.7", 5069);
            this.writer = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream(), "utf-8"));
        }
    
        public BufferedWriter getWriter(){
            return this.writer;
        }
    
        public Socket getSocket(){
            return this.socket;
        }
    
        @Override
        public void handleMessage(Message msg) {
            Draw draw = (Draw) msg.obj;
            if (draw != null){          
                if (getWriter() != null){
                    try{
                        getWriter().write(DrawUtil.toJson(draw)+"\n");
                        getWriter().flush();
                    }catch(IOException e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    Now you need to create an instance of this Worker class and pass it as the callback argument when you create the Handler. In your activity do:

        HandlerThread handlerThread = new HandlerThread("myHandlerThread");
        handlerThread.start();
        Looper looper = handlerThread.getLooper();
        // Create an instance of the class that will handle the messages that are posted
        //  to the Handler
        Worker worker = new Worker();
        // Create a Handler and give it the worker instance to handle the messages
        handler = new Handler(looper, worker);
    

提交回复
热议问题