【问题标题】:Android Fragment + AsyncTaskAndroid Fragment + AsyncTask
【发布时间】:2015-06-02 19:31:08
【问题描述】:

在片段中,我使用“AsyncTask”从 URL 检索数据。我的代码的主要目的是访问数据(通过 AsyncTask)并将“JSONArray”传递给片段。 问题是,在片段方面,当我检查应该有结果的变量时,我得到一个错误,说变量为空。

代码如下:

    public class MyFragment extends ListFragment {
        //this is the variable that should have the result from the AsyncTask
        JSONArray myResult = null;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            (...)
            //execute the asyncTask
            new GetResult().execute(email, password);
            (...)
        }

        //The AsyncTask
        private class GetResult extends AsyncTask<String, Void, JSONArray> {
            @Override
            protected JSONArray doInBackground(String... params) {

                (...)

                JSONArray jsonArray = (JSONArray) json.get("customer");
                return jsonArray;
            }

            protected void onPostExecute(JSONArray result){
                (...)
                //this is where I try to pass the data to the fragment
                MyFragment.this.myResult = result;
            }

        }


    }

有人可以帮助我吗?提前谢谢你。

【问题讨论】:

  • 你看到 onPostexecute() 中“结果”的价值了吗?当您使用内部类时,您可以直接在 asynctask 中访问 myResult
  • 你应该接受对你帮助最大的答案。

标签: android android-fragments android-asynctask


【解决方案1】:

您是否使用 postExecute 方法后的值。你应该知道,在调用execute之后,你在主线程上的代码仍然在运行,只有在postExecute完成之后,你才会有值。

【讨论】:

  • 我在 'onPostExecute' 中放了一条 Toast 消息,只是为了检查 'myResult' 是否返回任何值而不是 'null' 并证明我得到了我想要的值(不是 'null') .但就像你说的,我试图在 AsyncTask 完成之前读取变量......如果是这样,我该如何解决这个问题?我的意思是,我如何在 AsyncTask 完成后获取值?
  • 无论你想对那个变量做什么,你都可以在 postExecute 方法中这样做,或者在它完成时产生另一个操作。
【解决方案2】:

尝试使用此代码,并确保您的 jsonstring 不为空,因为您不会发布完整的代码,而且我无法查看 myResult 变量是否已更改:

try {
                        JSONArray json = new JSONArray(jsonstring);

                        JSONObject json_customer = json.getJSONObject("customer");

                        return json_customer;
                        } catch (JSONException e) {
                        return null
                    }

【讨论】:

    【解决方案3】:

    对我来说,从字符串数据到 json 的反序列化似乎存在问题。我们缺乏您正在解析的确切数据的信息。考虑为此使用一些更高级的 json 处理库,如 Gson 或 Jackson。通常和他们在一起会更容易。

    【讨论】:

      【解决方案4】:

      听起来您正试图在AsyncTask 完成检索之前从myResult 变量中读取它。为确保它正确填充,请将其放入您的 onPostExecute 函数中,在此行 MyFragment.this.myResult = result; 之后:

      Log.i("my result value is: ", MyFragment.this.myResult.toString())

      如果您正确检索它,它应该在 LogCat 中打印出来,之后您应该能够访问该变量。

      另外,请考虑使用VolleyRetrofit 或其他网络插件来让您的生活更轻松。

      【讨论】:

      • 我在 'onPostExecute' 中放了一条 Toast 消息,只是为了检查 'myResult' 是否返回任何值而不是 'null' 并证明我得到了我想要的值(不是 'null') .但就像你说的,我试图在 AsyncTask 完成之前读取变量......如果是这样,我该如何解决这个问题?我的意思是,我如何在 AsyncTask 完成后获取值?
      • 惯例是在您启动请求时显示一个加载指示器,并在调用“onPostRequest”后使用返回的数据更新 UI,然后隐藏加载指示器。这是显示加载指示器的方法之一:stackoverflow.com/questions/12841803/…
      • 在我的 'onPreExecute' 方法中,我已经使用了这个加载指示器,在我的 'onPostExecute' 方法中我将其关闭,但仍然......同样的错误......它告诉我我的 JsonArray 为空(我的结果)
      • 您只能在 onPostExecute 函数运行后从 UI 线程访问该变量。在此之前推迟对该变量的任何使用 - 在执行 onPostExecute 之后对该变量中的数据执行任何您需要执行的操作。显示加载指示器只是为了让用户知道您的应用正在后台执行某些操作。这是一篇可以帮助您更好地理解 AsyncTasks 的好文章:androidresearch.wordpress.com/2012/03/17/…
      【解决方案5】:

      也许您可以使用一种清晰的方式将数据从任务传回片段。

      1) 定义一个接口作为AsyncTask中要调用的事件监听器,比如

          public interface TaskEventListener(){
      
              public void onTaskStarted(int messageId);
      
              public void onTaskStopped(int messageId, int resultCode);
      
              public void onDataReady(Object parameter);    
          }
      

      2)让fragment实现这个EventListener,把处理代码放在onDataReady()函数中。

      3) 将片段实例作为 EventListener 实例传递。

      4) 在从AsyncTask扩展的类中,调用onPreExecute()函数中的onTaskStarted(),调用onPostExecute()函数中的onDataReady()onTaskStopped(),只调用onTaskStopped() onCancelled() 函数。

      5) 请在后台任务类中使用弱引用,防止引用无效的UI组件崩溃。

      【讨论】:

        猜你喜欢
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多