“只有创建视图层次结构的原始线程才能触摸其视图."使用TimerTask时出错 [英] "Only the original thread that created a view hierarchy can touch its views." error when using TimerTask

查看:106
本文介绍了“只有创建视图层次结构的原始线程才能触摸其视图."使用TimerTask时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个包含一个单独活动的应用程序,其中包括一个单独的 TextView .这是我活动的XML:

I have created an app composed of one single activity which include a single TextView. Here is the XML of my activity :

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 的文本.这是我用来执行此任务的代码:

My java code is to set the text of this textView every second. Here is the code I use to perform this task :

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上启动时,我面临以下问题:

I am facing the following issue when I launch load my app and launch it on my LG G2 :

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

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

我确定了以下几行:

timer.schedule(timertask, 0, 1000);

由于在删除错误时没有异常,因此导致该错误.我在误检查吗?

causing the error since I do not have exceptions when I remove it. Am I mising some checking ?

推荐答案

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

Your run() method will be called on a background thread, and it cannot manipulate the UI as a result.

一个重量更轻的解决方案是:

A lighter-weight solution would be:

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() calls your run() method on the main application thread, after the designated delay period. Here, we use that to have the Runnable schedule itself to run again after 1000ms.

要停止 postDelayed()循环",请在您的 MainActivity 上调用 removeCallbacks(onEverySecond).

To stop the postDelayed() "loop", call removeCallbacks(onEverySecond) on your MainActivity.

相对于在 TimerTask 中使用 runOnUiThread()/ TimerTask 线程).

The advantage of this over using runOnUiThread() inside the TimerTask is that it is less expensive, as you are not creating a separate thread (the Timer/TimerTask thread).

这篇关于“只有创建视图层次结构的原始线程才能触摸其视图."使用TimerTask时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆