我需要根据数组列表大小得到8次响应(动态)。所以我用过loop.inside for for循环,我正在使用volley get response。
每次点击api时,我都需要获得onResponse。
下面我发布了logcat及相关代码:
Logcat:(已编辑)
E/getAvaArrStr:
E/urlAva:
E/getAvaArrStr:
E/urlAva:
E/getAvaArrStr:
E/urlAva:
E/getAvaArrStr:
E/urlAva:
E/getAvaArrStr:
E/urlAva:
/* Response */
E/ResponseAvatar:
E/url:
E/CheckArrBit:
E/ResponseAvatar:
E/url:
E/CheckArrBit:
E/ResponseAvatar:
E/url:
E/CheckArrBit:
E/ResponseAvatar:
E/url:
E/CheckArrBit:
CardsFragment.java:(已编辑)
RequestQueue queue = Volley.newRequestQueue(getActivity());
for (int i = 0; i < alAvaArr.size(); i++) {
getAvaArrStr = alAvaArr.get(i);
Log.e("getAvaArrStr", "" + getAvaArrStr);
urlAva = BurblrUtils.BR_AVATAR_IMAGE + getAvaArrStr + "&android=1";
Log.e("urlAva", urlAva);
requestAva = new StringRequest(Request.Method.GET, urlAva, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response != null && !response.startsWith("<HTML>")) {
Log.e("ResponseAvatar", response);
dialog.dismiss();
try {
Toast.makeText(getActivity(), "Running ", Toast.LENGTH_SHORT).show();
String url = response.replace("\\", "");
url = url.replace("\"", "");
Log.e("url", url);
arrBitMap.add(url);
Log.e("CheckArrBit", "" + arrBitMap);
// Glide.with(getActivity()).load(url).placeholder(R.drawable.ic_launcher).error(R.drawable.ic_launcher).into(img);
getSwipeImage();
myAppAdapter.notifyDataSetChanged();
} catch (Exception e) {
e.printStackTrace();
dialog.dismiss();
}
} else {
dialog.dismiss();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error != null) {
Log.e("error", error.toString());
dialog.dismiss();
}
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("file", getAvaArrStr);
Log.e("paramsImg", "" + params);
Log.e("RunningParams", "Testing");
return params;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
};
queue.add(requestAva);
queue.getCache().remove(urlAva);
}
预期的日志响应顺序:
E/getAvaArrStr: -> E/urlAva: -> E/ResponseAvatar: -> E/url: -> E/CheckArrBit:
每次运行循环时我都需要得到响应。这意味着将近8次,基于arrayList的大小,我必须得到响应消息,是否可能在凌空中?任何克服这个问题的建议。
答案 0 :(得分:2)
您正在for循环中创建RequestQueue
...
所以没有呼叫队列......将其移出for循环
RequestQueue queue = Volley.newRequestQueue(getActivity());
for(..){
...
queue.add(requestAva);
}
答案 1 :(得分:2)
因为Volley是异步的,所以IMO,你不应该像你问题中的代码一样将请求放在for循环中。请参阅以下示例代码,然后将其逻辑应用于您的应用程序。希望它有所帮助!
public class MainActivity extends AppCompatActivity {
private int num = 0;
private JsonArrayRequest jsonArrayRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RequestQueue requestQueue = Volley.newRequestQueue(this);
String url = "http://...";
jsonArrayRequest = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.i("Num", String.valueOf(num));
Log.i("Response", response.toString());
if (num < 8) {
num++;
requestQueue.add(jsonArrayRequest);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Error", error.toString());
}
});
num++;
requestQueue.add(jsonArrayRequest);
}
}
Logcat输出如下:
03-28 13:14:29.885 13262-13262/com.example.googlevolley I/Num: 1
03-28 13:14:29.885 13262-13262/com.example.googlevolley I/Response: [{"id":"1","name":"Information Technology"},{"id":"2","name":"Human Resources"},{"id":"3","name":"Marketing and PR"},{"id":"4","name":"Research and Developement"}]
03-28 13:14:29.935 13262-13262/com.example.googlevolley I/Num: 2
03-28 13:14:29.955 13262-13262/com.example.googlevolley I/Response: [{"id":"1","name":"Information Technology"},{"id":"2","name":"Human Resources"},{"id":"3","name":"Marketing and PR"},{"id":"4","name":"Research and Developement"}]
03-28 13:14:30.085 13262-13262/com.example.googlevolley I/Num: 3
03-28 13:14:30.085 13262-13262/com.example.googlevolley I/Response: [{"id":"1","name":"Information Technology"},{"id":"2","name":"Human Resources"},{"id":"3","name":"Marketing and PR"},{"id":"4","name":"Research and Developement"}]
03-28 13:14:30.245 13262-13262/com.example.googlevolley I/Num: 4
03-28 13:14:30.245 13262-13262/com.example.googlevolley I/Response: [{"id":"1","name":"Information Technology"},{"id":"2","name":"Human Resources"},{"id":"3","name":"Marketing and PR"},{"id":"4","name":"Research and Developement"}]
03-28 13:14:30.266 13262-13262/com.example.googlevolley I/Num: 5
03-28 13:14:30.266 13262-13262/com.example.googlevolley I/Response: [{"id":"1","name":"Information Technology"},{"id":"2","name":"Human Resources"},{"id":"3","name":"Marketing and PR"},{"id":"4","name":"Research and Developement"}]
03-28 13:14:30.296 13262-13262/com.example.googlevolley I/Num: 6
03-28 13:14:30.296 13262-13262/com.example.googlevolley I/Response: [{"id":"1","name":"Information Technology"},{"id":"2","name":"Human Resources"},{"id":"3","name":"Marketing and PR"},{"id":"4","name":"Research and Developement"}]
03-28 13:14:30.306 13262-13262/com.example.googlevolley I/Num: 7
03-28 13:14:30.306 13262-13262/com.example.googlevolley I/Response: [{"id":"1","name":"Information Technology"},{"id":"2","name":"Human Resources"},{"id":"3","name":"Marketing and PR"},{"id":"4","name":"Research and Developement"}]
03-28 13:14:30.316 13262-13262/com.example.googlevolley I/Num: 8
03-28 13:14:30.316 13262-13262/com.example.googlevolley I/Response: [{"id":"1","name":"Information Technology"},{"id":"2","name":"Human Resources"},{"id":"3","name":"Marketing and PR"},{"id":"4","name":"Research and Developement"}]
答案 2 :(得分:1)
您必须创建一个功能。函数makeRequest
处理您的下一个Api调用
public class MainActivity extends AppCompatActivity {
RequestQueue queue;
int mIndex = 0 ;
ArrayList<String> alAvaArr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mQueue = Volley.newRequestQueue(getActivity());
alAvaArr = ///////// initialize here
mIndex = 0;
makeRequest(alAvaArr.get(mIndex));
}
public void makeRequest( String arg){
getAvaArrStr = arg;
Log.e("getAvaArrStr", "" + getAvaArrStr);
urlAva = BurblrUtils.BR_AVATAR_IMAGE + getAvaArrStr + "&android=1";
Log.e("urlAva", urlAva);
requestAva = new StringRequest(Request.Method.GET, urlAva, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response != null && !response.startsWith("<HTML>")) {
Log.e("ResponseAvatar", response);
dialog.dismiss();
try {
Toast.makeText(getActivity(), "Running ", Toast.LENGTH_SHORT).show();
String url = response.replace("\\", "");
url = url.replace("\"", "");
Log.e("url", url);
arrBitMap.add(url);
Log.e("CheckArrBit", "" + arrBitMap);
// Glide.with(getActivity()).load(url).placeholder(R.drawable.ic_launcher).error(R.drawable.ic_launcher).into(img);
getSwipeImage();
myAppAdapter.notifyDataSetChanged();
mIndex++;
if(mIndex < alAvaArr.size()){
makeRequest(alAvaArr.get(mIndex));
}
} catch (Exception e) {
e.printStackTrace();
dialog.dismiss();
}
} else {
dialog.dismiss();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error != null) {
Log.e("error", error.toString());
dialog.dismiss();
}
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("file", getAvaArrStr);
Log.e("paramsImg", "" + params);
Log.e("RunningParams", "Testing");
return params;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
};
mQueue.add(requestAva);
}
答案 3 :(得分:1)
我将添加由BNK
字样触发的另一个选项因为Volley是异步的......
这里我们有两种解决方案,主要是同步你的请求。
1)通过在前一个响应回调中触发它们来解决同步请求(请求链接)
2)我的解决方案使用Futures来同步调用,从而在阻塞调用中转换它们(一个等待前一个调用完成)。
他们都工作,并且几乎以相同的速度执行。
然而,他们都反对Volley的多线程优势。如果您的唯一目标是将您首先提供的网址与回复相关联,那么您只需拥有MAP并在收到回复时将其放在正确的位置。
在这个例子中我将使用Map(urlAndResponses)来组合你的2个集合
alAvaArr和arrBitMap
所以基本上不是这样的:
for (int i = 0; i < alAvaArr.size(); i++) {
getAvaArrStr = alAvaArr.get(i);
你放了:
final Map<String, String> urlAndResponses = Collections.synchronizedMap(new HashMap<String, String>());
for (Map.Entry<String, String> entry:urlAndResponses.entrySet()) {
final String getAvaArrStr = entry.getKey();
然后在你的回调而不是:
arrBitMap.add(url);
你放了:
urlAndResponses.put(getAvaArrStr, url);
这样您就不会拥有所需的日志,但您可以随时在正确的位置获得响应,并且所有请求仍将异步运行。
答案 4 :(得分:0)
要多次运行齐射请求(例如在for循环中),并且您的日志输出严格遵循您定义的顺序,您可以执行此操作 -
1)将您拥有的代码放入&#39; for循环&#39;在可运行的内部
Runnable runnable=new Runnable(){
//your code here
};
2)使用
在上述代码之前的任何位置创建一个处理程序Handler handler=new Handler();
现在将此行作为onResponse
中的最后一行handler.post(runnable);
3)现在您的代码将在无限循环中运行,因此您需要创建退出条件。你可以创建一个计数器变量并在onResponse中增加它。然后将handler.post()放在if条件中,检查计数器是否为&lt; 8或类似的东西。
使用处理程序,您可以再次发出截击请求,而无需从onErrorResponse递增计数器,并且可以比使用for循环更好地处理请求失败。
此外,您的退出条件可以是您作为响应得到的一些布尔值,因此您可以让服务器告诉您要生成多少请求而不是硬编码的固定数字。
第三(正如我之前提到的),在你提出截击请求之前你在runnable中拥有的代码将始终在前一个请求完成后执行,所以如果你愿意,你可以使用这个严格的顺序。 / p>
如果您有任何疑问或某些代码无法正常评论,那么我可以进行必要的修改。
答案 5 :(得分:0)
根据您的要求,我想您需要同步执行。如此不好建议使用期货。 同样重要的是要注意,为了不阻塞主线程,您已经在单独的线程上执行整个循环。 例如:
new Thread(new Runnable() {
@Override
public void run() {
..your loop...
}
}).start();
创建请求时:
requestAva = new StringRequest(Request.Method.GET, urlAva, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response != null && !response.startsWith("<HTML>")) {
Log.e("ResponseAvatar", response);
dialog.dismiss();
try {
Toast.makeText(getActivity(), "Running ", Toast.LENGTH_SHORT).show();
String url = response.replace("\\", "");
url = url.replace("\"", "");
Log.e("url", url);
arrBitMap.add(url);
Log.e("CheckArrBit", "" + arrBitMap);
// Glide.with(getActivity()).load(url).placeholder(R.drawable.ic_launcher).error(R.drawable.ic_launcher).into(img);
getSwipeImage();
myAppAdapter.notifyDataSetChanged();
} catch (Exception e) {
e.printStackTrace();
dialog.dismiss();
}
} else {
dialog.dismiss();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error != null) {
Log.e("error", error.toString());
dialog.dismiss();
}
}
})
改为:
RequestFuture<String> future = RequestFuture.newFuture() {
@Override
public synchronized void onResponse(String response) {
if (response != null && !response.startsWith("<HTML>")) {
Log.e("ResponseAvatar", response);
dialog.dismiss();
try {
Toast.makeText(getActivity(), "Running ", Toast.LENGTH_SHORT).show();
String url = response.replace("\\", "");
url = url.replace("\"", "");
Log.e("url", url);
arrBitMap.add(url);
Log.e("CheckArrBit", "" + arrBitMap);
// Glide.with(getActivity()).load(url).placeholder(R.drawable.ic_launcher).error(R.drawable.ic_launcher).into(img);
getSwipeImage();
myAppAdapter.notifyDataSetChanged();
} catch (Exception e) {
e.printStackTrace();
dialog.dismiss();
}
} else {
dialog.dismiss();
}
super.onResponse(response);
}
@Override
public synchronized void onErrorResponse(VolleyError error) {
if (error != null) {
Log.e("error", error.toString());
dialog.dismiss();
}
super.onErrorResponse(error);
}
};
requestAva = new StringRequest(Request.Method.GET, urlAva, future, future) {...
请注意这样,您将听众视为未来,而您以前的听众并未在您的未来实施。 然后当你添加请求
queue.add(requestAva);
更改为:
queue.add(requestAva);
try {
future.get();
// the response is handled by your Future synchroniously
} catch (InterruptedException e) {
// handle the error
} catch (ExecutionException e) {
// handle the error
}