Kasra
Kasra

Reputation: 3145

Starting/Calling the same thread multiple times Java Android

I need to call the same thread multiple times in my app. Using my original code, the first time is can be executed just fine. But the second time it crashes - I then learned that each thread shall only be executed not more than one time.

My original piece of code:

View.OnClickListener myClickListener = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        mythread.start();
    }
};


Thread mythread = new Thread(){

    @Override
    public void run() {

        runOnUiThread(new Runnable() {
            public void run() {
                demoBt.setText("Running...");
            }
        });

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

        runOnUiThread(new Runnable() {
            public void run() {
                demoBt.setText("Finished...");
            }
        });
    }
};

So as I said, it crashes if I try to run it for the second time. So I tried modifying it like:

View.OnClickListener myClickListener = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        test();
    }
};

private void test(){

    Thread mythread = new Thread(){

        @Override
        public void run() {

            runOnUiThread(new Runnable() {
                public void run() {
                    demoBt.setText("Running...");
                }
            });

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

            runOnUiThread(new Runnable() {
                public void run() {
                    demoBt.setText("Finished...");
                }
            });
        }
    };

    mythread.start();
}

It works very good; but my question is that whether this is the correct way to do this action or there is a more optimal way to do this?

Also, is it an acceptable thing to call a thread from insider of another thread? (like the way I put stuff on UI Thread inside the new thread of mine)

EDIT: This is just an example. For my actual code I have heavy math-based simulation to be done which takes 10sec to be done. Based on the results that will be shown to the user , they may want to change their input parameters and let the simulation run again. This will happen several times.

Upvotes: 1

Views: 8402

Answers (4)

Andres
Andres

Reputation: 6200

There is nothing bad with that but I think a better way would be using AsyncTask. It is exactly designed for this cases.

You can use AsyncTask multiple times just creating a new one like this new MyAsyncTask().execute(""); (source from here)

Upvotes: 2

Anirudh
Anirudh

Reputation: 389

From the provided code I assume that you want to perform an UI operation before and after your long mathematical computation. In such as @Andres suggested, AsyncTask is your best buy. It provides method onPreExecute, onPostExecute which runs on UI thread, and thus no need for explicitly calling runOnUiThread.

Key concepts :

  1. You can't start an already started thread. This will return in an IllegalStateException. If you need to perform same task again, you should create a new instance.

  2. If you find yourself creating several instances of a thread (even AsyncTask), since you need to run same task again and again, I would suggest you to use Thread Pool or simple Java Executor Service. Create a singleThread or may be pool and post your runnable onto executorService and it will take care of the rest.

  3. Inter-Thread or Inter-Process communication is quite common requirement.

Upvotes: 0

MikeHelland
MikeHelland

Reputation: 1159

In addition to the other good answers about using AsyncTask or runOnUiThread(), you could define a private member as a Runnable, like this:

private Runnable mytask = new Runnable() {
    @Override
    public void run() {

        runOnUiThread(new Runnable() {
            public void run() {
                demoBt.setText("Running...");
            }
        });

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

        runOnUiThread(new Runnable() {
            public void run() {
                demoBt.setText("Finished...");
            }
        });
    }
};

Then, whenever you want to run it, do

new Thread(mytask).start();

Upvotes: 5

zapl
zapl

Reputation: 63955

Also, is it an acceptable thing to call a thread from insider of another thread? (like the way I put stuff on UI Thread inside the new thread of mine)

runOnUiThread exists solely for that purpose. But there are usually much better ways (e.g. AsyncTask) so using this method is probably a bad idea.

my question is that whether this is the correct way to do this action or there is a more optimal way to do this?

You should not use a thread just to schedule future tasks. They are useful to execute something in parallel to the main thread but add lots of potential errors (try rotating the screen between it prints running..finished, could crash)

I would use a CountDownTimer in your case.

Or a Handler, examples e.g. here: Schedule task in android

Upvotes: 0

Related Questions