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

t98cgbkg  于 2022-11-14  发布在  Android
关注(0)|答案(1)|浏览(177)

我的片段有这样的代码:

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;
}

我第一次导航到此片段时,应用程序运行正常,但如果我返回主页并再次导航到此片段,应用程序有30%的机会崩溃,并为线程的setText行引发java.lang.NullPointerException: Attempt to invoke virtual method 'int android.text.Layout.getWidth()' on a null object reference。我尝试使用Thread.interrupt()停止线程,但没有成功。
那么,是什么导致了崩溃,我该如何解决呢?

mwecs4sa

mwecs4sa1#

你应该注意两件事:
1.在两个线程之间共享变量
1.在渲染线程/主线程之外更新UI
您应该做的事情:
使用线程安全变量,如AtomicBoolean或threadRunning变量的volatile布尔值...以及用于验证变量值的双重检查锁定或Lock
如果没有这一点,则无法保证在更改threadRunning var值时,更新的线程循环不在setText方法之前...
此外,您最好在onDestroyView方法的末尾调用super.onDestroyView()。
您可以执行的操作:
使用以下可能性之一(并非穷举)将TextView更新从更新线程分派到主线程

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

相关问题