java - 如何使用 Volley 进行并发 GET 调用?

标签 java android asynchronous android-volley

我有 3 个 API GET 调用。我的方法面临的问题是,该应用程序能够从两个 API 成功获取数据,并且我也能够在 UI 上显示它。但是,对于第三个 API 调用,由于以下错误,之前显示的数据消失了,这是不好的。

D/Volley: [380] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] http://example.com/api/search/getTwitterData?limit=10&tag=JavaScript 0x865f5dc2 NORMAL 3> [lifetime=6683], [size=10543], [rc=200], [retryCount=0]

如何使用 Volley 进行并发 API GET 调用而不丢失 UI 上的数据。有人可以指导我吗?

以下是我的代码的摘录。
public class StaggeredSearchActivity extends AppCompatActivity {

    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_staggered_search);

        requestQueue = Volley.newRequestQueue(this);

        Intent intent = getIntent();
        String searchText = intent.getStringExtra("searchText");

        // Three concurrent API GET Calls  
        getMediumData(searchText);
        getExampleData(searchText);
        getGoogleData(searchText);

        recyclerView = findViewById(R.id.staggered_recycler_view);
        staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(staggeredGridLayoutManager);
    }

    ArrayList<StaggeredCustomCard> dataset = new ArrayList<>();

    private void getMediumData(String searchText) {
        progressBar = findViewById(R.id.progressBar);
        progressBar.setVisibility(View.VISIBLE);

        String url = UrlConstants.getUrl() + searchText;

        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
                (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            progressBar.setVisibility(View.INVISIBLE);
                            JSONArray array = response.getJSONArray("mediumposts");

                            ...

                            dataset.add(new StaggeredCustomCard(user, userpost, postdate));
                            }
                            staggeredGridAdapter = new StaggeredGridAdapter(StaggeredSearchActivity.this, dataset);
                            recyclerView.setAdapter(staggeredGridAdapter);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }

                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // TODO: Handle error
                        progressBar.setVisibility(View.INVISIBLE);
                    }
                });

        jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
                DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 15,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        requestQueue.add(jsonObjectRequest);
    }

    private void getExampleData(String searchText) {

        ...

        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
                (Request.Method.GET, url, null, new Response.Listener<JSONArray>() {

                    @Override
                    public void onResponse(JSONArray response) {
                        try {
                            ...
                            dataset.add(new StaggeredCustomCard(user, userpost, postdate));
                                staggeredGridAdapter = new StaggeredGridAdapter(StaggeredSearchActivity.this, dataset);
                                recyclerView.setAdapter(staggeredGridAdapter);
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        ...
                    }
                });

        jsonArrayRequest.setRetryPolicy(new DefaultRetryPolicy(
                DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 15,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        requestQueue.add(jsonArrayRequest);
    }

    private void getGoogleData(String searchText) {
        ...

        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
                (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        ...

                        dataset.add(new StaggeredCustomCard(user, userpost, postdate));

                            }
                            staggeredGridAdapter = new StaggeredGridAdapter(StaggeredSearchActivity.this, dataset);
                            recyclerView.setAdapter(staggeredGridAdapter);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }

                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        ...
                    }
                });

        jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
                DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 15,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        requestQueue.add(jsonObjectRequest);
    }
}

最佳答案

问题是您每次都在初始化适配器,这就是为什么一旦新的 API 调用您的数据就会丢失。我更喜欢下面的方法,这样可以帮助你,
在 ArrayList 中添加数据并通知适配器,

在 onCreate 中添加这一行,

staggeredGridAdapter = new StaggeredGridAdapter(StaggeredSearchActivity.this, dataset);
recyclerView.setAdapter(staggeredGridAdapter);

API回调响应的变化:
                             ...

dataset.add(new StaggeredCustomCard(user, userpost, postdate));

循环后添加以下行
staggeredGridAdapter.notifyDataSetChanged();

适配器的变化
 private ArrayList<StaggeredCustomCard> dataSet;
        private Context context;

        public MyAdapter(ArrayList<StaggeredCustomCard> dataSet, Context context) {
            this.data = data;
            this.context = context;
        }

注意:不要在适配器上创建新对象。

关于java - 如何使用 Volley 进行并发 GET 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57961172/

相关文章:

C#:BackgroundWorker 线程优先级

java - Spring roo实体依赖

java - Jax-WS 和注释

android - AdMob: "activity has leaked ServiceConnection"和 "AdvertisingIdClient unbindService failed."

java - 如何从android studio连接到cloud SQL?

asp.net-mvc-3 - 通过 ASP.NET 同步上下文安全地执行任务,无需 AsyncManager.Sync

java - spring boot CrudRepository查询传递对象mysql

java - akka 是否提供对远程参与者之间网络连接的监控?

java - setListener 时发生内存泄漏

php - 如何从另一个 PHP 脚本异步运行一个 PHP 脚本?