Difference between Handler and Thread

10

I made a test app where I would like to see a ProgressBar being updated by simulating a long-running task. I initially tried to use Handler because after some research I saw that its use was recommended:

        final int tempoDeEspera = 500;
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                SystemClock.sleep(tempoDeEspera);
                progressBar.setProgress(1);
                SystemClock.sleep(tempoDeEspera);
                progressBar.setProgress(2);
                SystemClock.sleep(tempoDeEspera);
                progressBar.setProgress(3);
                SystemClock.sleep(tempoDeEspera);
                progressBar.setProgress(4);
                SystemClock.sleep(tempoDeEspera);
                progressBar.setProgress(5);
            }
        });

But I only got the expected result using Thread .

        final int tempoDeEspera = 500;
        new Thread(new Runnable() {
            @Override
            public void run() {
                SystemClock.sleep(tempoDeEspera);
                progressBar.setProgress(1);
                SystemClock.sleep(tempoDeEspera);
                progressBar.setProgress(2);
                SystemClock.sleep(tempoDeEspera);
                progressBar.setProgress(3);
                SystemClock.sleep(tempoDeEspera);
                progressBar.setProgress(4);
                SystemClock.sleep(tempoDeEspera);
                progressBar.setProgress(5);
            }
        }).start();

I would like to know the details of the two implementations and the situations in which each one should be used.

    
asked by anonymous 07.04.2014 / 19:27

1 answer

15

First, a basic concept (if you already know this part, you can skip to the last paragraph):

There is the main thread , also called the UI thread , whose central function is to perform UI operations is that they update the application screen, such as displaying texts, images, etc. This thread should not be overloaded with non-UI operations that are too heavy, otherwise it will cause the famous% s of% s, that is, screen refresh delay warnings that cause crashes in responsiveness application.

And there are secondary threads (any thread other than the main thread), these are suitable for heavier operations that are not UI but have no access directly to the main thread's thread queue and therefore can not call screen update operations directly through them; it is required ANR for this, which are objects that "post" a UI operation in the queue of operations to be performed by the main thread (this is called post a "message" or Handlers on the main thread). The difference between a message (class Runnable ) and a Runnable is minimal; both are excerpts of executable code, with Message storing a reference to an object that may be important for the code being executed (this is often not necessary, just pass Message to the thread using the Runnable method).

In your case, you have a secondary thread running non-UI operations (the calls to Handler.post(Runnable) ) and from time to time need to communicate to the main thread that the% % needs to be updated (this UI operation would be the sleep() call). As already mentioned, your secondary thread does not have direct access to the main thread execution queue and to post a "message" to the main thread run it should use a ProgressBar . The code would look like this:

final Handler handler = new Handler(Looper.getMainLooper());
final int tempoDeEspera = 500;
int i;

new Thread(new Runnable() {
    @Override
    public void run() {
        for (i = 0; i < 5; i++) {
            SystemClock.sleep(tempoDeEspera);
            handler.post(new Runnable() {
                @Override
                public void run() {
                    progressBar.setProgress(i);
                }
            });
        }
    }).start();

Note: I did not test to see if this code compiles, but it serves to illustrate the concept of ProgressBar.setProgress() and the difference between Handler and non Handler operations and the threads that execute them.

Examples of heavy operations that require processing and therefore must be performed on a separate thread : I / O operations, such as network access (HTTP requests in general, such as URL access) and SQLite database, heavy mathematical processing, etc.

A complement: In your case it worked without UI because the operation UI runs a post () internally ( Handler inherits this ProgressBar.setProgress() method), which puts the ProgressBar update in the main thread's thread queue. But not all UI components do this, so View remains useful in many cases.

    
07.04.2014 / 21:27