POMATu
POMATu

Reputation: 3472

How to textView.setText from Thread?

I need to set text to textView from thread. All code is created in oncreate()

something like

public TextView pc;

    oncreate(..) {
        setContentView(R.layout.main);
        pc = new TextView(context);
        Thread t =new Thread() {
            public void run() {
                pc.setText("test");
        }};
        t.start();

This crashes my app. How can I set text from thread?

Upvotes: 14

Views: 26935

Answers (4)

Ganesh MB
Ganesh MB

Reputation: 1179

I know Its too late but this is easy to implement for future developers

Just call this startCounter() method.

private void startCounter() {
    Thread thread = new Thread(new Runnable() {
        int startTime = 1;
        int endTime = 100;
        @Override
        public void run() {
            while (startTime <= endTime){
                runOnUiThread(new Runnable() {
                @Override
                public void run() {
                text.setText(startTime+"");    // text-> TextView
                startTime++;
                }
            });
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
            }
        }
    });
    thread.start();
}

Upvotes: 0

yoAlex5
yoAlex5

Reputation: 34451

Using Android Data Binding Library you can do this easy

Background Thread

You can change your data model in a background thread as long as it is not a collection. Data binding will localize each variable / field while evaluating to avoid any concurrency issues.

For example

ViewModel.java

package somepackage;

public class ViewModel {
    public final ObservableField<String> mTextViewField = new ObservableField<>();

    public void setText(String text) {
        mTextViewField.set(text)
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="viewModel"
            type="somepackage.ViewModel" />

    </data>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{viewModel.mTextViewField}" />

    </FrameLayout>
</layout>

MainActivity.java

public class MainActivity {

    private ViewModel mViewModel;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        MainBinding binding = DataBindingUtil.setContentView(this, R.layout.main);

        mViewModel = new ViewModel();
        binding.setViewModel(viewModel);
    }

}

Now you can address to the mViewModel from any Thread and change text value safely

Upvotes: 1

Ted Hopp
Ted Hopp

Reputation: 234857

Use a Handler:

public TextView pc;
Handler handler = new Handler();
oncreate(..) {
    setContentView(R.layout.main);
    pc = new TextView(context);
    Thread t =new Thread(){
        public void run() {
            handler.post(new Runnable() {
                public void run() {
                    pc.setText("test");
                }
            });
        }
    }};
    t.start();
}

But you have another problem. pc points to a view that is not part of your hierarchy. You probably want to use findViewById with the id of the TextView in your layout.

Upvotes: 10

bigstones
bigstones

Reputation: 15267

Try Activity.runOnUiThread().

Thread t = new Thread() {
    public void run() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                pc.setText("test");
            }
        });
    }
};

Upvotes: 11

Related Questions