首页 > 解决方案 > 如何在 Handler 类中发送时间戳?

问题描述

我创建了一个处理程序,其中我已经解析了时间戳,但我收到一个错误

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

我认为这是因为我在 xml 中定义的 textview 我不知道如何放置 textview 然后可以。任何人都可以帮助我为什么会收到这个错误,因为我只在 run() 中放置了 textview

主要活动

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(this);
    }
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                notificationDialog();
                break;
        }
    }
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void notificationDialog() {
        mHandler=new Handler();

        new Thread(new Runnable() {
            @Override
            public void run() {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss");
                    String format = simpleDateFormat.format(new Date());

                    TextView textView = findViewById(R.id.date);
                    textView.setText(format);

            }
        }).start();
    }
}

XML 文件

LinearLayout 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="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Date!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id = "@+id/button"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:text = "Click"
        app:layout_constraintBottom_toBottomOf = "parent"
        app:layout_constraintLeft_toLeftOf = "parent"
        app:layout_constraintRight_toRightOf = "parent"
        app:layout_constraintTop_toTopOf = "parent" />


</LinearLayout>

标签: android

解决方案


您不能从不同的线程更改 UI。Android 提供了几种方法来将更改传达给 UI 线程:

来自https://developer.android.com/guide/components/processes-and-threads.html#WorkerThreads

为了解决这个问题,Android 提供了几种从其他线程访问 UI 线程的方法。以下是可以提供帮助的方法列表:

Activity.runOnUiThread(可运行)

View.post(可运行)

View.postDelayed(可运行,长)

完成您正在尝试的事情的一种快速方法是使用 Activity.runOnUiThread(Runnable)。

private void notificationDialog() {
        Handler mHandler=new Handler();

        new Thread(new Runnable() {
            @Override
            public void run() {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss");
                final String format = simpleDateFormat.format(new Date());

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        TextView textView = findViewById(R.id.date);
                        textView.setText(format);     
                    }
                });

            }
        }).start();
    }

该变量format需要声明为 final 才能在内部 Runnable 中使用。我们创建一个新的 runnable 并告诉 Activity 在 UiThread 中运行它。

对于更复杂的场景,您可以使用AsyncTask类。


推荐阅读