【问题标题】:Android http callback and fragment handlingAndroid http回调和片段处理
【发布时间】:2020-04-02 13:47:01
【问题描述】:

我有以下代码(它的骨架):

PostRequester(..., Fragment caller, final PostRequesterResponse callback  ) {
        StringRequest stringRequest = new StringRequest(Request.Method.POST, baseUrl,
                response -> {
                    if (callback != null && caller != null) {
                        callback.onResponse(response);
                    }
                })...

从片段中调用上述示例:

...(this, result -> {
            try {
                if (result.contains("error")) {
                    throw new Exception(new JSONObject(result).getString("error"));
                }
                JSONObject jo = new JSONObject(result).getJSONObject("result");
                tvIncome.setText(getString(R.string.income));
            } catch (Exception e) {
                ...showPopup(getString(...));
            }

我确实检查了回调和调用者不为空,但我得到以下信息:

Fatal Exception: java.lang.IllegalStateException: Fragment x2{8dc73ab (83fe8dc9-f7d2-4324-abf2-c4aae15c37ef)} not attached to a context.

第一个getString() 失败,然后异常的失败。也许调用者不是空的,但它是分离的。我可以添加caller.isDetached() 条件,但用户可能随时“返回”并分离片段。在每行代码之后检查 isDetached 并不是一个好主意。

在这种情况下可以做什么?谢谢

【问题讨论】:

    标签: android android-fragments callback httprequest


    【解决方案1】:

    正如我所见,您应该像这样调用 getActivity().getString() :

    tvIncome.setText(getActivity().getString(R.string.income))

    但也必须在 getActivity() 不为空之前检查!!!

    【讨论】:

      【解决方案2】:

      您可以在回调条件中添加caller.isDetached()。 正如您所提到的,but the user might "go back" and detach the fragment at any time. 在这种情况下,您无论如何都不希望片段接收回调。 如果您想处理响应而不考虑片段,则不应从片段中调用它,而是从其他更可持续的地方调用它。 在这种情况下,我建议不要将片段包含在请求逻辑中,而只涉及任何调用者都可以注册的回调。

      关于您的后续问题:

      片段或者需要得到响应的人,应该实现回调接口。例如:

      1. 声明一个名为INetworkListener 的接口,方法为onResponse(Response response)

      2. FragmentX 实现 INetworkListener

      3. 在 FragmentX 中覆盖 onResponse(Response response) 并在那里处理响应

      4.当你进行网络调用时,而不是片段和回调作为参数,使用类型为INetworkListener 的参数callback(在我们的例子中是片段的实现者。所以如果从片段调用,参数将成为this

      5. 在你的调用函数中,当响应准备好时调用callback.onResponse(response),就像你现在正在做的那样,片段将在其覆盖的 onResponse() 方法中接收它。

      它与你现在拥有的有什么不同?好吧,从技术上讲,它不是。
      基本上将片段作为参数传递可能会导致内存泄漏,这不是一个很好的做法。

      当您拨打电话时,这一点很重要。例如,如果您在片段的 onCreate 中调用它,则响应可能会在附加片段之前返回。
      您的代码的问题在于它在访问其 ui 之前没有考虑片段的状态。
      如果您想在片段恢复后对其进行更新,您可以在更新片段的 ui 作为响应之前使用带有检查的回调,例如 if (!fragment.isAdded) return,以防片段被分离。
      但是,如果您想用数据加载片段 ,我建议您提前准备网络数据,用数据初始化片段,而不是为此目的在片段上使用回调。

      【讨论】:

      • 为简单起见,我有片段 x 需要显示“收入”。它调用请求,回调代码是函数的一部分(如您在我的示例中所见)。你说不要为此使用片段,我还能在哪里调用它,片段如何知道现在应该执行回调?请记住,我有几个片段,每个片段都检索/显示自己的数据。谢谢。
      • 后续跟进:如果我在同一个片段中有 2-3-4 个 http 请求,则相同的“onresponse”将处理所有这些请求,但这很容易解决。我的主要问题是:它与我现在拥有的有什么不同?为什么这样做会防止“分离”问题?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多