Android – Threads Tutorial – Part 2

Today we’ll focus on Threads creation and analyze an example of a local Thread instantiated in a method.

First of all I want to make sure that we understand why and how we deal with Threads. We use Threads objects to start parallel execution lines. For this we need to “load” the Thread object with the behavior we want, meaning to provide a run() method for it, which contains that behavior. We can do this in three ways:

  1. providing a class implementing Runnable in the Threads constructor (and that class needs to implement the run() method) – as we did in our first example
  2. implementing (in fact overriding) the run() method of a Thread object we declare and initialize – and we’ll show this in today’s example
  3. creating a class that inherits Thread and in that class overriding the run() method; in our code we just need to initialize an object of that class – as we’ll see in part 3 of this tutorial

When we want to start the parallel execution we simply call the Thread’s start() method.

Why using one method over another? When our Thread’s behavior is simple (thus the run() method short and simple) and there are little chances of change in future releases, the second method tends to be used. When changes in the Thread behavior may occur, the first or last method is preferred.

Let’s get to the practical example for today.

Example – Class with an Inner Thread

Things are getting better now – this little application shows a countdown from 10 to 0, at 0 the application closes. If the user touches the screen before the countdown finish, the application also closes.

Application view

Application view

We will use a Thread declared and initialized locally in the onCreate() method. Also we’ll learn about Thread loops, we’ll see a way to interrupt and finish the Thread and also try changing some instance variables from the Thread. Remember, you can’t modify other UI objects from the Thread, you really need to use for that the Handler, sending it messages and letting it do the job.

Let’s see the basic form of the code to be understood:

public class SomeClass [extends Activity]{

    public void someMethod(…){
        // ...
        // initializing and starting a new local Thread object
        Thread myTread = new Thread() {
            // setting the behavior we want from the Thread
            @Override
            public void run() {
                try {
                    // a Thread loop
                    while([someCondition]) {
                        // do things
                    }
                } catch(InterruptedException e) {
                    // don't forget to deal with exceptions....
                } finally {
                    // this block always executes so take care here of
                    // unfinished business
                }
            }
        };
        myThread.start();
        // ...
    }

    // manages Threads messages
    private Handler threadHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            // handling messages and acting for the Thread goes here
        }
    };

    // ...
    // other methods

}

A short note – if we don’t need later in the code myThread object we can in fact declare the Thread as an anonymous inner class like this:

(new Thread() {
    public void run() {
        // ...
    }
}).start();

And now the whole thing:

package com.indy.testing;

import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.widget.TextView;

public class TestMain extends Activity {

    // text view influenced by the Thread
    private TextView threadModifiedText;
    private int threadModifiedInt = 4;
    private Point threadModifiedPoint = new Point(20,10);

    // boolean that controls if the Thread will run or not.
    private boolean activeThread = true;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        threadModifiedText = (TextView) findViewById(R.id.thread_modified_text);

        // the local Thread used for count-down
        Thread myTread = new Thread() {
            @Override
            public void run() {
                try {
                    // test modifying objects
                    threadModifiedInt = 20;
                    threadModifiedPoint.set(30, 40);

                    int timeCounter = 100;
                    // main loop. the thread just checks at each 100ms
                    // passed if it should still be running and then waits.
                    // timeCounter decrements by 1 each loop
                    while(activeThread && (timeCounter > 0)) {
                        sleep(100);
                        // once per second notifies the Handler to
                        // update the displayed count-down
                        if(timeCounter % 10 == 0){
                            threadHandler.sendEmptyMessage(
                                (int)timeCounter/10);
                        }
                        timeCounter--;
                    }
                } catch(InterruptedException e) {
                    // don't forget to deal with exceptions....
                } finally {
                    // this forces the activity to end
                    // (also the application in our case)
                    finish();
                }
            }
        };

        // starting thread
        myTread.start();
    }

    // manages user touching the screen
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // we set the activeThread boolean to false,
            // forcing the loop from the Thread to end
            activeThread = false;
        }
        return super.onTouchEvent(event);
    }

    // Receives Thread's messages, interprets them and acts
    // on the current Activity as needed
    private Handler threadHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            threadModifiedText.setText("test int is " + threadModifiedInt +
            "\ntest Point is " + threadModifiedPoint.toString() +
            "\ncounter is " + Integer.toString(msg.what));
        }
    };
}
  • This time our Activity class doesn’t implement Runnable, it can focus on other things than implementing run() method and being used by a Thread.
  • The Thread we use is declared and instantiated inside onCreate() method. Also there we override its run() method imprinting the behavior we want.
  • We test the Thread’s ability to access instance variables – a primitive (by changing the threadModifiedInt) and also an object (threadModifiedPoint). We didn’t pay attention here to synchronization issues as this was not the target of the exercise.
  • We can try changing the UI object (threadModifiedText) from the Thread also, but we’ll get the CalledFromWrongThreadException. So indeed we must use the Handler for modifying this object.
  • This time the Handler uses the message sent by the Thread – it converts and displays the number (msg.what) sent with the message.
  • Our Thread has a main loop (the while statement) that runs once every 100ms while some constraints are satisfied. Meanwhile it sends messages to the Handler to determine user interface changes (the countdown display).
  • We control the moment when the Thread should finish by using a boolean flag. As long as activeThread boolean is true the Thread executes, when changed to false it stops.
  • This time our try-catch block has “grown up” – it gained a finally statement. This block is executed no matter what happened inside the try-catch block.
  • Notice the forcing of the Activity to end by calling finish() in the finally block.
  • Notice the use of onTouchEvent() method to manage user screen touching.
  • Remember the comments in the code are for learning purpose, do not to comment code the same way in real life (I’ll probably have a post about Commenting Code anytime soon).

You can access the source code for this example here.

In Threads Tutorial – Part 3 we will use a special independent class that inherits Thread and we’ll learn more about Handler usages.

10 comments

  1. Maulik Khare

    This is really good information regarding threads.

  2. Very clear and concise tutorial. Help me a lot!

    Thanks!

Trackbacks/Pingbacks

  1. Android – Threads Tutorial | IndyVision.Net - [...] hope this helped. In the Threads Tutorial – Part 2 we’ll deal with a Thread inside a method and ...

Leave a Reply

You must be logged in to post a comment.