"只有创建视图层次结构的原始线程才能触及其视图。"使用TimerTask时出错

时间:2016-09-16 22:48:47

标签: java android timer timertask

我创建了一个由单个活动组成的应用程序,其中包含一个TextView。这是我的活动的XML:

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="0dp"
    android:paddingLeft="0dp"
    android:paddingRight="0dp"
    android:paddingTop="0dp"
    tools:context="zeratops.myApp.MainActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:background="#000000"
        android:layout_alignParentTop="true">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14dp"
            android:text=""
            android:textColor="#FF0000"
            android:id="@+id/text_1"
            android:paddingTop="200dp"
            android:layout_gravity="center" />
    </FrameLayout>
</RelativeLayout>

我的java代码是每秒设置此textView的文本。这是我用来执行此任务的代码:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final TextView text = (TextView) findViewById(R.id.text_1);
        Timer timer = new Timer();
        TimerTask timertask = new TimerTask() {
            @Override
            public void run() {
                text.setText("test");
            }
        };

        timer.schedule(timertask, 0, 1000);
    }
}

问题

当我启动加载我的应用并在LG G2上启动它时,我面临以下问题:

  

android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图。

我确定了这些行:

timer.schedule(timertask, 0, 1000);

导致错误,因为我删除它时没有异常。我在检查一下吗?

2 个答案:

答案 0 :(得分:0)

您需要执行

text.setText("test");

UI线程中的

。您可以使用处理程序执行此操作。

final Handler myHandler = new Handler();
myHandler.post(myRunnable);



   final Runnable myRunnable = new Runnable() {
      public void run() {
        text.setText("test");
      }
   };

答案 1 :(得分:0)

您的run()方法将在后台线程上调用,因此无法操纵UI。

较轻的解决方案是:

public class MainActivity extends AppCompatActivity {
    private TextView text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        text = (TextView) findViewById(R.id.text_1);

        onEverySecond.run();
    }

    private Runnable onEverySecond=new Runnable() {
        @Override
        public void run() {
            text.setText("test");
            text.postDelayed(this, 1000);
        }
    }
}
在指定的延迟期后,

postDelayed()在主应用程序线程上调用您的run()方法。在这里,我们使用它来使Runnable计划本身在1000ms后再次运行。

要停止postDelayed()&#34;循环&#34;,请致电removeCallbacks(onEverySecond)上的MainActivity

这比在runOnUiThread()中使用TimerTask的优势在于它更便宜,因为您没有创建单独的线程(Timer / TimerTask线程)。

相关问题