【问题标题】:Is running a for loop in a Volley response listener okay?在 Volley 响应侦听器中运行 for 循环好吗?
【发布时间】:2014-10-29 01:53:45
【问题描述】:

我在我的 logcat 中得到了这个:skipped X frames! The application may be doing too much work on its main thread 其中 X 通常在 40 到 60 之间。

我是 android 开发的新手,我不确定 Volley 对 AsyncTasks 做了多少。在我的片段中,我向服务器发送 JSON 请求,如下所示:

{ "networks" : [ { "name" : "a name", "external_id" : "an external_id" }, ... ] }

... 只是与我在数组中显示的第一个具有相同形式的元素的占位符。

我基本上完成了 Fragment 中 onActivityCreated 函数中的所有工作。

这是代码,我不确定我是否做错了什么。此外,for 循环的重点是遍历 JSONArray 并将每个元素转换为自己的模型,然后我将其传递给 ArrayList,该 ArrayList 最终通过适配器适应 UI。

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    mSessionPreferences = this.getActivity().getSharedPreferences(
            getString(R.string.session_shared_preferences_key), Context.MODE_PRIVATE);

    networks = getListView();

    networkItems = new ArrayList<Network>();
    listAdapter = new NetworksListAdapter(getActivity(), networkItems);
    networks.setAdapter(listAdapter);

    JSONObject params = new JSONObject();
    params.put("user_id", mSessionPreferences.getString(getString(R.string.user_id_key), null))
          .put("auth_token", mSessionPreferences.getString(getString(R.string.user_auth_token_key), null));

    Response.Listener<JSONObject> listener = new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            JSONArray jsonNetworks = response.optJSONArray("networks");
            int len = jsonNetworks.length();
            for (int i = 0; i < len; i++) {
                JSONObject jsonNetwork = jsonNetworks.optJSONObject(i);
                Network network = new Network(jsonNetwork.optString("external_id"),
                            jsonNetwork.optString("name");

                networkItems.add(network);
            }

            listAdapter.notifyDataSetChanged();
        }
    };

    Response.ErrorListener errorListener = new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyErrorHandler volleyError = new VolleyErrorHandler(error);

            Log.v("Sigh", volleyError.getMessage(), "nope"));
        }
    };

    APIRequestManager.getInstance().doRequest().getNetworks(params, listener, errorListener);
}

最后一行负责让 Volley 发送请求。

有什么看起来可疑的地方吗?请注意,这不是在模拟器上,而是在我的实际设备上。我的印象是它处理异步的东西。我应该在后台明确地与我的听众做事吗?如果是这样,我该怎么做?

【问题讨论】:

  • Volley 实际上在后台处理其工作量。但是,侦听器或默认在 UI 线程上运行 - 这是您的责任。如果您正在跳帧,则它是在 UI 线程上执行的某种长操作。尝试放置信息丰富的日志打印以找出该操作的确切位置并将其移至后台线程。

标签: java android android-fragments android-asynctask android-volley


【解决方案1】:

如果 jsonNetworks 的长度很大,你应该在后台运行这个方法。 试试这个:

@Override
public void onResponse(JSONObject response) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            JSONArray jsonNetworks = response.optJSONArray("networks");
            int len = jsonNetworks.length();
            for (int i = 0; i < len; i++) {
                JSONObject jsonNetwork = jsonNetworks.optJSONObject(i);
                Network network = new Network(jsonNetwork.optString("external_id"),
                        jsonNetwork.optString("name");

                networkItems.add(network);
            }
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    listAdapter.notifyDataSetChanged();
                }
            });
        }
    }).start();
}

【讨论】:

  • 这个概念似乎是正确的,应该可行,但我认为您的代码不正确。
  • 好的,所以我解决了一个问题,即runOnUiThread需要成为getActivity().runOnUiThread,因为这是一个片段。唯一的另一个问题是我引用了response,它不是最终变量。
  • 已修复。在new Thread(new Runnable() { 的正上方,我刚刚写了final JSONObject jsonResponse = response; 并将响应替换为jsonResponse。
  • 嗯...如果有很多数据需要处理,显示进度对话框/栏会是个好主意吗?是否可以在 volley 的 onResponse 中做到这一点而不会冒漏窗户的风险?
猜你喜欢
  • 1970-01-01
  • 2014-06-09
  • 1970-01-01
  • 2020-12-01
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
相关资源
最近更新 更多