我在模型中进行网络操作然后返回结果,但是当我返回时,arraylist大小为零,但在onResponse
方法中,arraylist大小不为零。如何解决这个问题?
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;
}
}
答案 0 :(得分:2)
理解并不理解异步操作,您给Volley的Listener正在等待响应,并且当响应从服务器端返回时,不会调用您的return
语句,而是立即调用。这意味着您的arrayList
只是空的(填充它的代码在响应返回后运行)。它必须是异步操作,因为如果不是用户的所有UI线程都会停止,并且您的应用程序不会响应任何用户操作。
所以要解决这个问题你需要等到响应返回后再填充数组调用下一个想要的流程。好的是添加一些加载器视图,在开始请求之前显示它并在请求结束后隐藏。
也许有些流量比较。
当前流程:
通缉流程:
编辑(关于装载机)
对于加载,可以使用任何视图(例如带图像的简单视图),使用 VISIBILITY 等视图属性,因此当加载程序视图可见时,只需调用loaderView.setVisibility(View.VISIBLE)
,何时应该是隐藏 - loaderView.setVisibility(View.GONE)
。
为此目的,也可以使用一个随时可用的Android库,如 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中找到它:
ContentLoadingProgressBar loader = (ContentLoadingProgressBar)findViewById(R.id.loader);
最后只是使用它来显示loader.show()
,以隐藏loader.hide()
。所以回到主要观点 - 在请求之前显示,隐藏在响应监听器中。