首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程错误NullPointerException中的Android绑定

线程错误NullPointerException中的Android绑定
EN

Stack Overflow用户
提问于 2021-12-30 02:29:36
回答 1查看 1.6K关注 0票数 1

我已经将代码切换到查看绑定,但现在我在线程中更新UI时遇到了问题。该代码在合成语法方面运行良好。我搞错了:

代码语言:javascript
复制
java.lang.NullPointerException
    at HomeFragment.getBind(HomeFragment.kt:25)
    at HomeFragment.updateHomeUI$lambda-6(HomeFragment.kt:190)
    at HomeFragment.$r8$lambda$7K03ZbIZrY_5ngvcMBPsw15TPbw(Unknown Source:0)
    at HomeFragment$$ExternalSyntheticLambda10.run(Unknown Source:2)
    at java.lang.Thread.run(Thread.java:919)

我的代码:

代码语言:javascript
复制
class HomeFragment : Fragment(R.layout.fragment_home) {
    private var _binding: FragmentHomeBinding? = null
    private val bind get() = _binding!!  // <-- line 25

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        _binding = FragmentHomeBinding.inflate(inflater, container, false)
        return bind.root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        ...
        updateHomeUI()
    }

    private fun updateHomeUI() {
        Thread {
            while (bind.tvName != null) {  // Stop the loop after changing the fragment
                ...
                // Lots of UI update like this:
                if (activity != null) (activity as MainActivity).runOnUiThread { bind.tvName?.text = str }
                ...
                Thread.sleep(1000)
            }
        }.start()
    }

当我切换到另一个片段时,会出现错误。如果我是对的,则线程运行在onDestroyView ()之后,绑定变为空。我想出了暂停onDestroyView直到线程完成的想法,但我认为这不是最好的解决方案,因为它可能会停止整个应用程序。

代码语言:javascript
复制
override fun onDestroyView() {
    super.onDestroyView()
    threadStop = true
    while (threadRunning) {
        Thread.sleep(1)
    }
    _binding = null
}
private fun updateHomeUI() {
    Thread {
        threadRunning = true
        threadStop = false
        while (!threadStop) {
            ...
        }
        threadRunning = false
    }
}

如何正确地避免这个问题?

诚挚的问候!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-30 03:11:24

如果您放弃!! getter,只在需要时使用本地非空变量的可空类型,您可能会发现这更容易。如果在循环中有很多地方可以使用绑定,则可以在循环开始时获取该绑定的非空值。

代码语言:javascript
复制
private fun updateHomeUI() {
    Thread {
        // this could also be while(true) since the calls just
        // inside will break out when it goes null
        while (_binding != null) {  // Stop the loop after onDestroyView sets this to null
            val binding = _binding ?: break
            val a = activity as? MainActivity ?: break
            
            
            // Lots of UI update like this:
            a.runOnUiThread { binding.tvName.text = str }
            
            ...
            Thread.sleep(1000)
        }
    }.start()
}

我不确定您现有的bind.tvName != null循环条件如何在没有首先失败!!检查的情况下返回false。默认情况下,绑定类中的视图是非空的(除非它们并不存在于所有布局排列中),所以如果bind getter中的_binding为null,则这要么为真,要么将在_bindinggetter中失败。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70526892

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档