启动片段的后台线程时,应用程序随机崩溃

App randomly crashes when starting background thread of a fragment

我的片段有以下代码:

public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    txtAngle = view.findViewById(R.id.textView_angle);

    updateTextThread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (threadRunning) {
                txtAngle.setText("1");
            }
        }
    });

    threadRunning = true;
    updateTextThread.start();
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
    threadRunning = false;
}

应用程序在我第一次导航到这个片段时工作正常,但如果我 return 到主页并再次导航到这个片段,应用程序有 30% 的机会崩溃,抛出 java.lang.NullPointerException: Attempt to invoke virtual method 'int android.text.Layout.getWidth()' on a null object reference 用于线程的 setText 行。我尝试使用 Thread.interrupt() 来停止线程,但它没有用。

那么是什么导致了崩溃,我该如何解决?

你应该注意两件事:

  1. 在两个线程之间共享一个变量
  2. 更新 UI 渲染线程/主线程

你应该做什么:

使用线程安全变量,如 AtomicBoolean 或 volatile boolean 作为 threadRunning var...,并使用双重检查锁定或 Lock 来验证 var

的值

如果没有这个,你无法保证在更改 threadRunning var 值时更新线程循环不在 setText 方法之前...

另外,你最好在 onDestroyView 方法的最后调用 super.onDestroyView()。

你能做什么:

使用以下可能性之一(并非详尽无遗)将 TextView 更新从更新线程分派到主线程

  • 使用与主 Looper 关联的 Handler
  • 使用协程或 rxJava 将工作分派到正确的线程