为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

炎炎设计 2023-08-04 16:37:36
我有 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 上的数据。有人可以指导我吗?这是我的代码的摘录。
查看完整描述

4 回答

?
Helenr

TA贡献1780条经验 获得超3个赞

问题是您每次都会初始化适配器,这就是为什么一旦新的 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;

        }

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


查看完整回答
反对 回复 2023-08-04
?
MYYA

TA贡献1868条经验 获得超4个赞

这种方法没有多大意义。一旦您从三个端点之一收到响应,您似乎每次都会创建一个新的适配器并将其附加到回收器并使用随机的“notifyDataSetChanged”...

  1. 也许可以考虑使用具有处理业务登录的服务层和网络层的 ViewModel。

  2. 当网络方法之一的回调从端点响应时,ViewModel 更新/发布 MutableLiveData>...合并三部分数据。

  3. 该活动只是观察 ViewModel 的 MutableLiveData 并使用 DiffUtil 来更新回收器中的外观/卡片。

https://img1.sycdn.imooc.com//64ccb9320001d76708640432.jpg

查看完整回答
反对 回复 2023-08-04
?
缥缈止盈

TA贡献2041条经验 获得超4个赞

最好的方法是在 onCreate 方法的 StaggeredSearchActivity 中注册您的 LiveData 并像您一样监听数据库更改。在每个成功响应中,将其结果保存到没有 LiveData 的数据库中。onCreate方法中的LiveData会被触发。


   @Override



  protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main2);


  ViewModel viewModel = ViewModelProviders.of(this, factory).get(ViewModel.class);

            viewModel.getEntity().observe(this, entity -> {

                if (entity != null) {

                    adapter.notifyDataSetChanged(entity );


                }

            });


    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) {

                        StaggeredCustomCardDAO.insert();

                        // TODO just insert to dataBase

                    }


                }, 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 {


                            // TODO just insert to dataBase

                          StaggeredCustomCardDAO.insert();

                        } 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) {


                        // TODO just insert to dataBase

StaggeredCustomCardDAO.insert();

                    }

                }, 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);



    }



    class ViewModel extends androidx.lifecycle.ViewModel {



        private LiveData<StaggeredCustomCard> entity;



        public ViewModel(Repository repository) {

            entity = repository.getNetworkData();

        }



        public LiveData<StaggeredCustomCard> getEntity() {

            return entity;

        }

    }


    class Repository {


        LiveData<StaggeredCustomCard> getNetworkData() {


            LiveData<StaggeredCustomCard> localeData =  StaggeredCustomCardDAO .getLocaleData();//... todo Read from data base

            return localeData;

        }

    @Dao

    public interface StaggeredCustomCardDAO {

        @Query("Select * from tbl_staggeredCustomCard ")

        LiveData<StaggeredCustomCard> getLocaleData();


        @Insert(onConflict = OnConflictStrategy.REPLACE)

        void insert(List<StaggeredCustomCard> items);


    }

    }



查看完整回答
反对 回复 2023-08-04
?
达令说

TA贡献1821条经验 获得超6个赞

第一种方法:首先我建议您创建一个中央请求队列。


public class AppController extends Application {

    public static final String TAG = AppController.class

            .getSimpleName();

    private RequestQueue mRequestQueue;


    private static AppController mInstance;


    @Override

    public void onCreate() {

        super.onCreate();

        mInstance = this;

    }


    public static synchronized AppController getInstance() {

        return mInstance;

    }


    public RequestQueue getRequestQueue() {

        if (mRequestQueue == null) {

            mRequestQueue = Volley.newRequestQueue(getApplicationContext());

        }


        return mRequestQueue;

    }


    public <T> void addToRequestQueue(Request<T> req, String tag) {

        // set the default tag if tag is empty

        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);

        getRequestQueue().add(req);

    }


    public <T> void addToRequestQueue(Request<T> req) {

        req.setTag(TAG);

        getRequestQueue().add(req);

    }


    public void cancelPendingRequests(Object tag) {

        if (mRequestQueue != null) {

            mRequestQueue.cancelAll(tag);

        }

    }

}

然后将您想要的请求添加到队列中


// Adding request to request queue

AppController.getInstance().addToRequestQueue(jsonObjReq);

第二种方式:创建一个Generic Volley类和一个接口,使用接口来获取成功和失败响应。


步骤 1 创建一个单独的 Volley 类 步骤 2 创建一个用于访问 volley 类响应的接口 步骤 3 为该类创建新对象并发送所需参数 new PostVolleyJsonRequest(TestVolley.this, TestVolley.this(interfcae), "Submit", url ,参数);


类的上下文 用于发送成功和失败响应的接口 成功时识别的请求类型 url(强制) GET 的参数(可选) 不需要 通用 volley 类


public class PostVolleyJsonRequest {

private String  type;

private Activity act;

private VolleyJsonRespondsListener volleyJsonRespondsListener;

private String networkurl;

private JSONObject jsonObject = null;

private JSONObject params;



public PostVolleyJsonRequest(Activity act, VolleyJsonRespondsListener volleyJsonRespondsListener, String type, String netnetworkUrl,JSONObject params) {

    this.act = act;

    this.volleyJsonRespondsListener = volleyJsonRespondsListener;

    this.type = type;

    this.networkurl = netnetworkUrl;

    this.params = params;

    sendRequest();

}


private void sendRequest() {


    Log.d("url", "url" + networkurl);

    JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,networkurl,params,

            new Response.Listener<JSONObject>() {

                @Override

                public void onResponse(JSONObject response) {

                    Log.e("response", "response " + response);

                    volleyJsonRespondsListener.onSuccessJson(response, type);

                }

            },

            new Response.ErrorListener() {

                @Override

                public void onErrorResponse(VolleyError error) {

                    try {

                        NetworkResponse response = error.networkResponse;

                        Log.e("response", "response " + response);

                        if (response != null) {

                            int code = response.statusCode;


                            String errorMsg = new String(response.data);

                            Log.e("response", "response" + errorMsg);

                            try {

                                jsonObject = new JSONObject(errorMsg);

                            } catch (JSONException e) {

                                e.printStackTrace();

                            }

                            String msg = jsonObject.optString("message");

                            volleyJsonRespondsListener.onFailureJson(code, msg);

                        } else {

                            String errorMsg = error.getMessage();

                            volleyJsonRespondsListener.onFailureJson(0, errorMsg);

                        }

                    } catch (Exception e) {

                        e.printStackTrace();

                    }

                }

            });


    jsObjRequest.setRetryPolicy(new DefaultRetryPolicy(

            600000,

            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,

            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));


    RequestQueue requestqueue = Volley.newRequestQueue(act);

    requestqueue.add(jsObjRequest);


}

}


Use the interface to get responds message


public interface VolleyJsonRespondsListener {


public void onSuccessJson(JSONObject result, String type);

public void onFailureJson(int responseCode, String responseMessage);

}

在您想要包含多个请求的班级中


public class TestVolley extends AppCompatActivity implements VolleyJsonRespondsListener{


//Your class code goes here



//network request


try {

        //parameters 

        //Context,Interface,Type(to indentify your responds),URL,parameter for your request 


        //request 1

        new PostVolleyJsonRequest(TestVolley.this, TestVolley.this, "Submit", url, params);


        //request 2

        new PostVolleyJsonRequest(TestVolley.this, TestVolley.this, "AccessData", url_2, params_2);





 } catch (Exception e) {


 e.printStackTrace()

 }


 //Methods from Interface


  @Override

public void onSuccessJson(JSONObject result, String type) {


   //Based on the Type you send get the responds and parse it 

    switch (type) {

        case "Submit":

            try {

                parseSubmit(result);

            } catch (Exception e) {



查看完整回答
反对 回复 2023-08-04
  • 4 回答
  • 0 关注
  • 95 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信