Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Communication between UI thread and other threads using handler

How to do inter thread communication between UI thread and background thread? I want use common handler concept here to update my UI. I have the concept as below

new Thread(new Runnable() {
         public void run() {
             while (mProgressStatus < 100) {
                 mProgressStatus = doWork();

                 // Update the progress bar
                 mHandler.post(new Runnable() {
                     public void run() {
                         mProgress.setProgress(mProgressStatus);
                     }
                 });
             }
         }
     }).start();

I want to use two classes, one class contains main thread, another class contains background thread and they use the same handler. How do I implement this? I know it is very common but I am finding it difficult to exactly implement.

like image 436
gd1 Avatar asked Feb 27 '17 00:02

gd1


1 Answers

You can pass anything from the parameters if you don't want to use static concepts. In the below codes, I have implemented two classes. As you asked, I used the common handler in both thread classes. I pass handler h1 as the parameters of Runnable object and start() method there to trigger the run() method of another thread class. The thread which contains run() method is the UI (Main) thread. We must use UI thread to update UI. Worker (Background) threads can't do UI update. The communication between worker with UI is done via handler. So, I define handler h2 in UI thread class. When UI thread class constructor is called from background thread class, I get my h2 values from h1 that come from the constructor. And I use h2 for my the communication. In fact, h2 and h1 belong to the same memory space in the system.

I made below two classes and did thread communication for your reference.

First class

 public class MainActivity extends AppCompatActivity {
    Handler h1;
    Thread t;
    EditText editText;
    private Bundle bb = new Bundle();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText) findViewById(R.id.editText);

        h1 = new Handler(Looper.getMainLooper()) {

            @Override
            public void handleMessage(Message msg) {
                bb = msg.getData();
                String str = bb.getString("udd");
                editText.setText(str);
                System.out.println(str);
            }
        };
        t = new Thread(new MyRunnable(h1)); //I pass Runnable object in thread so that the code inside the run() method
        //of Runnable object gets executed when I start my thread here. But the code executes in new thread
        t.start(); //thread started

        try {
            t.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

}

Second class

public class MyRunnable implements Runnable {
    private Handler h2;
    public MyRunnable(Handler h) {
        this.h2 = h;
    }

    @Override
    public void run() {

        //everything inside rum method executes in new thread
        for(int i=0;i<10;i++) {
            Message m = Message.obtain(); //get null message
            Bundle b = new Bundle();
            b.putString("udd", "daju");
            m.setData(b);
            //use the handler to send message
            h2.sendMessage(m);

        }
    }
}

Note: when thread.start() happens, it triggers the run of the Runnable class, it creates a separate thread. So every time, you call start(), there is a new thread with the same priority of callee thread.

Hope, this helped you.

like image 85
Uddhav P. Gautam Avatar answered Oct 13 '22 06:10

Uddhav P. Gautam