TextView.setText()崩溃了应用程序

时间:2013-08-02 23:29:55

标签: android

我有一个textView(称为tvCurrentBeat),每当我尝试使用setText()时,我的应用程序在启动时崩溃。如果我删除这行代码,应用程序就可以正常工作。

XML代码:

<TextView
      android:id="@+id/tvCurrentBeat"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignLeft="@+id/ivDividerMiddle"
      android:layout_below="@+id/ivDividerMiddle"
      android:layout_marginTop="10dp"
      android:text="Current Beat:"
      android:textColor="#ffffff"
      android:textAppearance="?android:attr/textAppearanceLarge" />

变量初始化:

tvCurrentBeat = (TextView) findViewById(R.id.tvCurrentBeat);

其他代码:

new Thread() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            super.run();

            while (true) {
                if (metronomeOn) {
                    metronome = new Metronome(10000);
                    metronome.play();
                    metronomeOn = false;
                }
                tvCurrentBeat.setText("Current Beat: ");
            }
        }

    }.start();

这是影响此textview的所有代码。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

您正在尝试更新后台UI上的Thread。那不是不。您需要使用runOnUiThread()AsyncTaskHandler

这样的东西
 runOnUiThread(new Runnable() {
        public void run()
        {
           tvCurrentBeat.setText("Current Beat: ");
        }
    });
}

您可能还想阅读Painless Threading

答案 1 :(得分:2)

  

这是影响此textview的所有代码。有什么想法吗?

在Android中有限制告诉您,您只能从其原始线程操纵UI元素(正如@Delyan在评论中指出的那样)。

您创建了与主(UI)线程不同步的工作者(后台)线程,并且不允许更新UI(出于安全性和平稳运行的原因)

您可以选择如何实现目标:

  • runOnUiThread()
  • 的用法
  • 处理程序
  • 的AsyncTask

所有提到的结构都是同步的,或者提供与UI线程同步的方法,并允许使用UI进行操作。

答案 2 :(得分:1)

您无法从后台线程更新UI元素。您需要创建一个Runnable并通过它更新它们。虽然还有其他选择,但这是我最常使用的选项。

以下是一个例子:

private Handler threadHandler = new Handler();

// ...

while (true) {
    if (metronomeOn) {
        metronome = new Metronome(10000);
        metronome.play();
        metronomeOn = false;
    }
    threadHandler.post(updateRunnable);
}

// ...

final Runnable updateRunnable = new Runnable() {
    public void run() {
        tvCurrentBeat.setText("Current Beat: ");
    }
}; 

另一种方法是使用runOnUiThread()只在主线程上运行你的东西。

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();

        while (true) {
            if (metronomeOn) {
                metronome = new Metronome(10000);
                metronome.play();
                metronomeOn = false;
            }
            tvCurrentBeat.setText("Current Beat: ");
        }
    }
}.start();