首页 > 解决方案 > 删除Fragment时如何取消Volley JsonObjectRequest?

问题描述

语境

在我的 MainActivity 中,我使用一个函数来根据菜单选择替换不同的片段。

我正在使用 Kotlin Volley 库从服务器获取 JSON。在获取这些数据的同时,我向我的用户显示了一个加载微调器。

但是,如果任何用户不希望等待数据加载,则没有什么可以阻止他们打开导航抽屉并更改为不同的片段。

我的问题

Volley 请求似乎在后台继续,因为尽管使用以下代码作为 MainActivity 的一部分更改了片段,logcat 仍会产生以下响应:

java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.constraintlayout.widget.ConstraintLayout.setVisibility(int)' on a null object reference

这表明请求继续,并尝试找到我的元素以设置可见性,尽管片段已关闭因此崩溃,因为它找不到它。

关闭片段

我正在使用以下函数,当用户单击导航菜单项时调用。我此时也在清理任何其他片段的后台堆栈。

   private fun changeFragment(frag: Fragment){
        val fragment = supportFragmentManager.beginTransaction()
            .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)

        for (i in 0 until supportFragmentManager.getBackStackEntryCount()) {
            supportFragmentManager.popBackStack()
        }
        fragment.replace(R.id.fragmentContainer, frag).commit()
    }

JSON 请求

val request = JsonObjectRequest(Request.Method.GET, url, null, {
                response ->try {
                    serviceResultLayout.visibility = View.VISIBLE //LINE 88, as per logcat
                    loadingLayout.visibility = View.GONE
                    serviceList.clear()

                    val jsonArray = response.optJSONArray("services")
                    if(jsonArray != null) {
                        for (i in 0 until jsonArray.length()) {
                            val serviceRow = jsonArray.getJSONObject(i)

                            //variable assignments removed for ease of reading
   
                        }
                    }
                    recycleradapter.notifyDataSetChanged()
                } catch (e: JSONException) {
                    e.printStackTrace()
                    changeFragment(Location())
                    Toast.makeText(requireActivity(), "No Services Found", Toast.LENGTH_SHORT).show()
                }
            },
            {
                error ->
                    error.printStackTrace()
            })
        request.retryPolicy = DefaultRetryPolicy(
            60000,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
        )
        requestQueue?.add(request)

到目前为止我尝试过的

我使用了 onDestroy 和 onStop 覆盖函数requestQueue?.cancelAll(this)

onStop()继续导致同样的问题并且没有取消 JSON / 片段布局更新。 onDestroy()

override fun onDestroy() {
        super.onDestroy()
        requestQueue?.cancelAll(this)
    }

从这一点来看,我假设与其取消 requestQueue,不如将其重新分配val request给可能null,或者使用其他方式取消函数而不是取消 requestQueue?显然,在理解我对代码所做的事情方面,我已经咬得比我能咀嚼的还要多。谢谢

标签: kotlinandroid-volley

解决方案


推荐阅读