Java &引用;只有创建视图层次结构的原始线程才能接触其视图。”;使用TimerTask时出错

Java &引用;只有创建视图层次结构的原始线程才能接触其视图。”;使用TimerTask时出错,java,android,timer,timertask,Java,Android,Timer,Timertask,我已经创建了一个由一个活动组成的应用程序,其中包括一个TextView。以下是我的活动的XML: 活动\u 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:l

我已经创建了一个由一个活动组成的应用程序,其中包括一个
TextView
。以下是我的活动的XML:

活动\u 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>
问题

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

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

我确定了以下几行:

timer.schedule(timertask, 0, 1000);
导致错误的原因是,当我删除它时没有异常。我是不是误会了一些检查?

您需要执行以下操作

text.setText(“测试”)

在UI线程中。您可以使用处理程序执行此操作

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



   final Runnable myRunnable = new Runnable() {
      public void run() {
        text.setText("test");
      }
   };
您的
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
计划本身在1000毫秒后再次运行

要停止
postDelayed()
循环,请在
main活动上调用
removeCallbacks(onEverySecond)


与在
TimerTask
中使用
runOnUiThread()
相比,这种方法的优点是成本更低,因为您不需要创建单独的线程(
Timer
/
TimerTask
线程)Platform.runLater(){}
,android应该有类似的.Perfect。只需提及,我必须将
final TextView text=(TextView)findviewbyd(R.id.text_1)public void run(){
函数中进行代码>实例化,以避免范围错误。但是如果没有它,它可以很好地节省时间!@Zeratops:或者,将其设置为一个字段--我刚刚更新了我的答案以显示这一点。它可以避免您进行
findViewById()
不必要的每秒钟打一次电话。我检查它是否正常工作。感谢您的更新。
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);
        }
    }
}