使用volley库,在onResponse方法中,ArrayList有一些数据,但在OnResponse方法之外,arraylist是空的 [英] Using volley library, inside the onResponse Method the ArrayList have some data but outside the OnResponse method the arraylist is empty

查看:147
本文介绍了使用volley库,在onResponse方法中,ArrayList有一些数据,但在OnResponse方法之外,arraylist是空的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在模型中进行网络操作,然后返回结果,但是当我返回时,arraylist大小为零但是在 onResponse 方法中,arraylist大小为不是零。如何解决这个问题?

I am doing the network operation in a model and then return the result, but the arraylist size is zero when I return it but inside the onResponse method the arraylist size is not zero. How to resolve this?

      public class doInBackground {

           //i have initialized the arraylist here 
            ArrayList<Contact> arrayList=new ArrayList<>();
            String url="http://192.168.10.3/volley/allUser.php"; 
            private Context context;
            public doInBackground(Context context){
                this.context=context;
            }

            public ArrayList<Contact> getArrayList(){
                JsonArrayRequest jsonArrayRequest=new JsonArrayRequest(Request.Method.POST, url, null, new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {

                        for(int i=0;i<response.length();i++){
                            try {
                                JSONObject jsonObject=response.getJSONObject(i);
                                Contact contact=new Contact();
                                contact.setName(jsonObject.getString("name"));
                                contact.setUserName(jsonObject.getString("username"));
                                arrayList.add(contact);
                            } catch (JSONException e) {
                                e.printStackTrace();
                                Toast.makeText(context,e.toString(),Toast.LENGTH_LONG).show();
                            }
                        }

//outside the for loop the arraylist have data( i.e fetch from Mysql database)
                    }

                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(context,error.toString(),Toast.LENGTH_LONG).show();
                    }
                });
                Toast.makeText(context,arrayList.size()+"",Toast.LENGTH_LONG).show();

           //using singleton design pattern to add the request to the queue                    MySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);
           // here the arraylist is empty

                    return arrayList;
                }


        }


推荐答案

理解不了异步操作,你给Volley的Listener正在等待响应,并且当响应返回时,不会调用你的 return 语句服务器端,但立即被调用。这意味着你的 arrayList 只是空的(填充它的代码在响应返回后运行)。它必须是异步操作,因为如果不是用户的所有UI线程都会停止而你的应用程序不会响应任何用户操作。

It is tipical not understanding async operations, Listener which You have given to Volley is waiting for response and Your return statement is called not when response returns from server side, but is called instantly. It means Your arrayList is just empty ( code which fills it is running after response come back ). It must be async operations because if not all UI thread for user would just stop and Your application would not respond for any user action.

所以要解决这个问题你需要等到响应返回后再填充数组调用下一个想要的流程。好的是添加一些加载器视图,在开始请求之前显示它并在请求结束后隐藏。

So to fix this problem You need to wait until response will return and then after filling array call next wanted flow. Good is to add some loader view, show it before starting of request and hide after end of request.

可能有一些流量比较。

当前流程:


  • 凌空请求开始

  • 返回arrayList(空列表)

  • 排球响应正在填充arrayList

通缉流程:


  • show loader

  • 凌空请求开始

  • 凌空响应正在填充arrayList

  • 隐藏加载程序

  • 在准备好使用arrayList的响应后调用想要的操作

  • show loader
  • start of volley request
  • volley response is filling arrayList
  • hide loader
  • call wanted action after response with ready to use arrayList

编辑(关于装载机)

对于装载可以使用任何使用 VISIBILITY 等视图属性查看(例如带图像的简单视图),因此当加载程序视图应该可见时,只需调用 loaderView.setVisibility(View.VISIBLE)以及何时应隐藏 - loaderView.setVisibility(Vie w.GONE)

For loading can be used any view ( for example simple view with image ) by using view properties like VISIBILITY, so when loader view should be visible just call loaderView.setVisibility(View.VISIBLE) and when should be hidden - loaderView.setVisibility(View.GONE).

为了这个目的,也可以使用一个随时可用的Android库,如 ContentLoadingProgressBar

To this purpose also can be used one of ready to use android libraries like ContentLoadingProgressBar.

ContentLoadingProgressBar 的示例用法。

首先将其添加到布局:

<android.support.v4.widget.ContentLoadingProgressBar
    android:id="@+id/loader"
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:visibility="gone" />

下一个在Activity中找到它:

Next in Activity find it by:

ContentLoadingProgressBar loader = (ContentLoadingProgressBar)findViewById(R.id.loader);

最后只是用它来显示 loader.show(),用于隐藏 loader.hide()。所以回到主要观点 - 在请求之前显示,隐藏在响应侦听器中。

And last just use it, for showing loader.show(), for hidding loader.hide(). So back to main point - show before request, hide inside in response listener.

这篇关于使用volley库,在onResponse方法中,ArrayList有一些数据,但在OnResponse方法之外,arraylist是空的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆