A
A
amimamoya2021-04-15 18:22:50
Java
amimamoya, 2021-04-15 18:22:50

The application crashes on the line that says to change the text in the TextView. What is the problem?

Hello, here's the thing, I want to display the current time to the nearest second in the application after pressing the button, I do this by means of a stream in which the current time is obtained every second and put in the TextView. Everything seems to be fine, but after the first installation, when the time is updated a second time, the application crashes with the error android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Here is the xml code:

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat 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"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_marginLeft="150dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/label2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/but"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="125dp"
        android:text="Погнали!"
        android:onClick="butpress"/>

</androidx.appcompat.widget.LinearLayoutCompat>

And here is MainActivity:
public class MainActivity extends AppCompatActivity {
    TextView label;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        label = (TextView) findViewById(R.id.label2);
    }

    public void butpress(View view){
        ButPres nm = new ButPres();
        nm.actionPerformed();
    }

    class ButPres extends Thread{
        public void actionPerformed() {
            start();
        }

        boolean prov = true;

        @Override
        public void run() {
            while (prov) {
                String time = new SimpleDateFormat("kk:mm:ss").format(Calendar.getInstance().getTime());
                label.setText(time);
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        }

    }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Denis Zagaevsky, 2021-04-15
@amimamoya

Well, in general, it writes to you

Only the original thread that created a view hierarchy can touch its views.

Original thread is Main(UI) thread. Your thread cannot access the UI. You can use runOnUiThread.
But in general, for this task, the new thread is redundant and even harmful. You can use Handler + postDelayed to achieve this effect.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question