iuiz
iuiz

Reputation: 3

Android thread problem

I just want to continously update text in an android app. However my App crashes every time.

This is my code:

package org.pgvw.main;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class InertialView extends Activity {
    TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tv = new TextView(this);
        tv.setText("Time: ");
        new Thread(new Runnable() {
            public void run() {
                while(true) {
                    try {
                        Thread.currentThread().sleep(100);
                        tv.setText("Time: " + System.currentTimeMillis());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        setContentView(tv);
    }
}

Can anyone spot the mistake?

Greetings and thx!

Upvotes: 0

Views: 1807

Answers (3)

JAL
JAL

Reputation: 3319

Consider that you do not need to launch any additional threads to update the UI every x milliseconds. The additional overhead of an added thread is justified IF you have a time intensive task. In the following example the timer is launched on a button click. Note that this code does not create a new thread.

private Handler myHandler= new Handler(){
    @Override
    public void  handleMessage(Message msg){         
        switch(msg.what){
            case 0:
                if (!isDoneThinking){
                    editTextConfusedText.setText("Still Thinking "+new Integer(thinkSeconds).toString());
                    thinkSeconds++;
                    this.removeMessages(0);
                    sendMessageDelayed(obtainMessage(0),1000); // <== Loop on delayed messages every second
                }
                else {
                    thinkSeconds= 0; // reset timer
                }
                break;
            default:
                super.handleMessage(msg);
                break;
        }
    }
};

We launch the timer in onClick. We simply send an empty message with a what value of "0".

    buttonConfuseText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

               isDoneThinking= false;
               myHandler.sendEmptyMessage(0); <== starts timer with what value of "0"
        }
    };

The timer is unconstrained and will continue to count until the flag isDoneThinking is set to true.

Upvotes: 2

MByD
MByD

Reputation: 137282

You cannot update GUI from another thread. You can use runOnUiThread or handler to update the GUI.

for example:

new Thread(new Runnable() {
            public void run() {
                while(true) {
                    try {
                        Thread.currentThread().sleep(100);
                        runOnUiThread(new Runnable() {
                            public void run() {
                                tv.setText("Time: " + System.currentTimeMillis());
                            }

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

BTW - The use of Thread.currentThread().sleep(100); can be shorted to Thread.sleep(100) since it's a static method. see Jon Skeet's answer regarding that

Upvotes: 2

Christian Garbin
Christian Garbin

Reputation: 2532

Or use AsyncTask. It was designed to do background tasks and properly update the UI. Your design will be more scalable this way.

Upvotes: 0

Related Questions