使用 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

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

问题描述

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

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 的监听器正在等待响应并且你的 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(空列表)
  • volley 响应正在填充 arrayList

想要的流量:

  • 显示加载器
  • 开始截击请求
  • volley 响应正在填充 arrayList
  • 隐藏加载器
  • 在准备好使用 arrayList 的响应后调用想要的操作

编辑(关于加载器)

通过使用诸如 VISIBILITY 之类的视图属性,可以使用任何视图(例如带有图像的简单视图)加载,因此当加载器视图应该可见时,只需调用 loaderView.setVisibility(View.VISIBLE) 以及何时应该隐藏 - loaderView.setVisibility(View.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天全站免登陆