使用volley库,在onResponse方法中,ArrayList有一些数据,但在OnResponse方法之外,arraylist是空的
我在模型中进行网络操作,然后返回结果,但是当我返回时,arraylist大小为零,但在onResponse
方法中,arraylist大小不为零。 怎么解决这个?
public class doInBackground { //i have initialized the arraylist here ArrayList 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 getArrayList(){ JsonArrayRequest jsonArrayRequest=new JsonArrayRequest(Request.Method.POST, url, null, new Response.Listener() { @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( ie 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线程都会停止,并且您的应用程序不会响应任何用户操作。
所以要解决这个问题你需要等到响应将返回,然后填充数组调用下一个想要的流量。 好的是添加一些加载器视图,在请求开始之前显示它并在请求结束后隐藏。
也许有些流量比较。
当前流程:
- 凌空请求的开始
- return arrayList(空列表)
- 凌空响应正在填充arrayList
通缉流程:
- 显示装载机
- 凌空请求的开始
- 凌空响应正在填充arrayList
- 隐藏装载机
- 在准备好使用arrayList的响应之后调用想要的操作
编辑(关于装载机)
对于加载,可以使用任何视图(例如带图像的简单视图),使用VISIBILITY等视图属性,因此当加载器视图应该可见时,只需调用loaderView.setVisibility(View.VISIBLE)
,何时应隐藏 – loaderView.setVisibility(View.GONE)
。
为此目的,也可以使用一个随时可用的Android库,如ContentLoadingProgressBar 。
ContentLoadingProgressBar的示例用法。
首先将其添加到布局:
在Activity中的下一步找到它:
ContentLoadingProgressBar loader = (ContentLoadingProgressBar)findViewById(R.id.loader);
最后只是使用它,用于显示loader.show()
,用于隐藏loader.hide()
。 所以回到主要观点 – 在请求之前显示,隐藏在响应监听器内部。