如何从Thread中textView.setText?

时间:2011-05-18 19:16:23

标签: android multithreading

我需要从线程中将文本设置为textView。所有代码都在oncreate()

中创建

类似

public TextView pc;

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

这会导致我的应用崩溃。如何从线程设置文本?

4 个答案:

答案 0 :(得分:10)

尝试Activity.runOnUiThread()

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

答案 1 :(得分:8)

使用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();
}

但是你有另一个问题。 pc指向不属于您的层次结构的视图。您可能希望在布局中使用带有TextView标识的findViewById

答案 2 :(得分:0)

使用Android Data Binding Library即可轻松完成

  

后台主题

     

您可以在后台更改数据模型   线程,只要它不是一个集合。数据绑定将本地化   每个变量/字段在评估时避免任何并发   的问题。

例如

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);
    }

}

现在您可以从任何线程处理mViewModel并安全地更改文本值

答案 3 :(得分:0)

我知道为时已晚,但这对于未来的开发人员来说很容易实现

只需调用此 startCounter() 方法。

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();
}