为啥 RequireView() 不返回视图 onResume()?

Posted

技术标签:

【中文标题】为啥 RequireView() 不返回视图 onResume()?【英文标题】:Why doesn't RequireView() not return a view onResume()?为什么 RequireView() 不返回视图 onResume()? 【发布时间】:2020-03-14 10:07:17 【问题描述】:

我正在使用片段的 onResume() 方法上的 Volley 请求解析数据,用解析的数据填充布局,我需要获取片段的视图,这就是我调用 requireView() onResume 的原因() 成功解析后。 现在我的应用程序第一次在一行上崩溃了,我将用 * 表示:

java.lang.IllegalStateException:片段 DataMain1a53f20 (4f68cb4d-c05f-4416-932e-26e455fbf106) 没有返回视图 onCreateView() 或在 onCreateView() 之前调用。

这是代码:

class DataMain : Fragment(), CoroutineScope by MainScope() 

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? 
        val view = inflater.inflate(R.layout.fragment_Data, container, false)
        DataBalance = view.findViewById(R.id.Data_balance)
        // Firebase User Auth
        getUID.requestUidToken()?.addOnSuccessListener  

                    ?.addOnFailureListener 

                    val unregisteredView = inflater.inflate(R.layout.fragment_unregistred, container, false)
                    val registerNow = unregisteredView.findViewById<TextView>(R.id.textview_registernow)
                    registerNow.setOnClickListener 
                        val mIntent = Intent(activity, LoginMain::class.java)
                        requireActivity().startActivity(mIntent)
                    
                
            view
         else 
            val unregisteredView = inflater.inflate(R.layout.fragment_unregistred, container, false)
            val registerNow = unregisteredView.findViewById<TextView>(R.id.textview_registernow)
            registerNow.setOnClickListener 
                val mIntent = Intent(activity, LoginMain::class.java)
                requireActivity().startActivity(mIntent)
            
            unregisteredView
        
    

        private fun populateDataLayout(res: JSONObject, view: View) 
        val response = Gson().fromJson(res.toString(), ServerResponse::class.java)
        //here I need the view
        val lVDataMenu: ListView = view.findViewById(R.id.lV_DataMenu)
        lVDataMenu.adapter = lVadapter

        else if (response.code == 403) 

        



    override fun onResume() 
        getUID.requestUidToken()?.addOnSuccessListener  getTokenResult ->
            Volley(config.DATA_LOADDATA,  res ->
                **CRASH**populateDataLayout(res,requireView())
            , 
                tv_unverified.visibility = View.VISIBLE
            )
        
        super.onResume()
    

我可以在填充例程中摆脱“view.findViewById(R.id.lV_DataMenu)”的使用,但是我不明白这里的问题。 我无法重新创建错误,所以这就是我要问的原因。那么为什么 requireView() 可能不返回视图呢?是因为用户切换到下一个片段,而 Volley 还没有完成解析吗?我该如何解决这个问题?

【问题讨论】:

【参考方案1】:
override fun onResume() 
    getUID.requestUidToken()?.addOnSuccessListener  getTokenResult ->
        Volley(config.DATA_LOADDATA,  res ->
            **CRASH**populateDataLayout(res,requireView())
        , 
            tv_unverified.visibility = View.VISIBLE
        )
    

你没有在onResume()这里打电话给requireView()

您有两个异步调用,并且将函数( 中的那些 lambda 表达式)作为参数传递给它们。这些函数稍后会被调用,例如当异步操作完成时。那时你的片段可能已经完成了它的生命周期。

两种常见的处理策略:

    在片段完成时取消挂起的异步调用。您似乎在onCreateView()onResume() 中拨打电话。这些对应的生命周期是onDestroyView()onPause()。具体如何执行此操作取决于您使用的异步 API。

    带有过期检查的即发即弃:当异步完成时,检查片段是否还活着,否则什么也不做。例如,改变

    populateDataLayout(res,requireView())
    

    类似

    view?.let  populateataLayout(res, it) 
    

    其中view 是可空的getView() 对应于非空requireView()

【讨论】:

这对理解问题很有帮助,谢谢先生。请问:有没有什么我可以阅读以更深入地了解这个特定主题并使用您称之为“即发即弃”的方法来解决问题? view?.let = "let" 基本上是说:if view !=null then do this here? 是的。神奇的是 ?. 安全调用运算符,它仅在操作数为非空时调用 let 范围函数。

以上是关于为啥 RequireView() 不返回视图 onResume()?的主要内容,如果未能解决你的问题,请参考以下文章

为啥jQuery将单选按钮的值返回为“ON”?如何纠正它?

为啥 viewbag 值不传递回视图?

为啥导航返回后表格视图单元格背景视图工作良好?

Python 3.0 - dict 方法返回视图 - 为啥?

为啥这个 NIB 视图在返回之前没有发布?

为啥离子 v1 事件“beforeLeave”在离开视图后返回数据