我知道这种奇怪的问题,但是我试图在for循环中使用我的Retrofit调用。我正在做的是在通话中使用insertdata(seperated2[0], seperated2[1], email, tag);
但是当他们跳过对call.enqueue(......onResponse(...) onfailure(.....))
的匿名调用时,循环表现得很奇怪。
与其使用循环控件进行调用,不如先完成循环,然后进入call.enqueue并始终执行循环中的最后一个元素。这就是循环的样子....
separated = currentString.split("\n");
for (int i=1; i<separated.length; i++) {
seperated2 = separated[i].split(":");
for (String aSeperated2 : seperated2) {
Call<ServerResponse2> call = requestInterface.insertQrdata(seperated2[0], seperated2[1], email, tag);
call.enqueue(new Callback<ServerResponse2>() {
@Override
public void onResponse(Call<ServerResponse2> call, Response<ServerResponse2> response) {
ServerResponse2 serverResponse2 = response.body();
Toast.makeText(getActivity(), serverResponse2 != null ? serverResponse2.getMessage() : null, Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<ServerResponse2> call, Throwable t) {
Toast.makeText(getActivity(), t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
这是seperated []和seperated2 []的ex
0 1
2 3
4 5
6 7
7 8
9 10
seperated []按行将其拆分,seperated2按列将其拆分。
问题 当我在on Response方法中为每次迭代检查我的septerated2 [0]和septerated2 [1]值时,它应该是
sep2[0]= 0 sep2[1] = 1
2 3
and so on... for each iteration
但是在每次迭代中,onResponse中的值始终是最后一个值,即
sep2[0] = 9 sep2[1] = 10
untill the length (say 6) same value at each iteration.
我不知道是否做错了什么,但是当我在onResponse()之外使用它们时,值显示正确。
我知道使用翻新这样的做法不是很好的做法,但是我很好奇它在这种情况下会如何反应。任何人都可以提供帮助或提出建议吗?
谢谢!!
答案 0 :(得分:0)
除了使用for循环,您还可以使用递归。 仅在获得上一个索引的响应之后,才会一次又一次调用API。 在onResponse()方法中,您可以通过增加索引值来调用该方法。 因为在for循环中,该迭代不会等待API响应的执行完成,所以它将跳转到下一个迭代。
如果您仍然想使用循环,请进行while循环
递归示例:
int i=1;
separated = currentString.split("\n");
void callMethod(){
seperated2 = separated[i].split(":");
Call<ServerResponse2> call = requestInterface.insertQrdata(seperated2[0], seperated2[1], email, tag);
call.enqueue(new Callback<ServerResponse2>() {
@Override
public void onResponse(Call<ServerResponse2> call, Response<ServerResponse2> response) {
ServerResponse2 serverResponse2 = response.body();
Toast.makeText(getActivity(), serverResponse2 != null ? serverResponse2.getMessage() : null, Toast.LENGTH_SHORT).show();
i++;
callMethod();
}
@Override
public void onFailure(Call<ServerResponse2> call, Throwable t) {
Toast.makeText(getActivity(), t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
答案 1 :(得分:0)
根据我的建议,请勿对此类操作使用循环。这是个坏主意,如果您可以明智地看到性能。
您可以通过以下方式执行此操作:
改造只是调用服务器URL,并将您的数据传递到服务器。 因此,无论在服务器端执行任何处理,您都可以更改为仅执行一次,而不是每次执行。
您可以一次将json格式的整个循环数据传递到服务器,并在服务器端执行所有循环过程。会最适合您的。
希望您能阐明我的观点。
如果您有任何问题,请告诉我。
答案 2 :(得分:0)
这是使用改造库进行循环的示例。如果我们使用for循环,则调用不会立即被所有迭代调用。因此请使用此模型。
private void UploadImagesTask(final String image, final int position) {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
File file = new File(image);
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part photoArray = MultipartBody.Part.createFormData("photo", file.getName(), reqFile);
HashMap<String, RequestBody> params = new HashMap<>();
params.put("token", Utils.createPartFromString(pref.getToken()));
params.put("app_id", Utils.createPartFromString(pref.getAppId()));
Call<ImageUploadResponse> imageUploadResponseCall = apiService.uploadImage(photoArray, params);
imageUploadResponseCall.enqueue(new Callback<ImageUploadResponse>() {
@Override
public void onResponse(@NonNull Call<ImageUploadResponse> call, @NonNull Response<ImageUploadResponse> response) {
if (response.isSuccessful()) {
urlList.add(Objects.requireNonNull(response.body()).getUrl());
completeData.remove(position);
completeData.add(position, getString(R.string.uploaded));
uploadAdapter.notifyDataSetChanged();
pref.setTempData(Constants.IMAGE_UPLOADED, gson.toJson(urlList));
if (position != uriData.size() - 1) {
int posi = position + 1;
CompressImages(posi);
} else {
uploadDone.setActivated(true);
uploadDone.setEnabled(true);
}
} else {
Utils.showSnackView(getString(R.string.error_occurred), snackView);
uploadDone.setActivated(true);
uploadDone.setEnabled(true);
}
}
@Override
public void onFailure(@NonNull Call<ImageUploadResponse> call, @NonNull Throwable t) {
Utils.showSnackView(getString(R.string.error_occurred), snackView);
uploadDone.setActivated(true);
uploadDone.setEnabled(true);
}
});
}
答案 3 :(得分:0)
嘿,如果您还没有找到答案,我有个建议。在对数据进行应用循环之后,将整个响应分为几部分,并使用Asynctask将数据发送到服务器并创建一个接口,以便您可以对响应执行任何操作。
public interface GetResponse{
public void onSuccess(ResponseModel model);
publich void onFail();
}
In your async task
public class AsyncTaskForApiSync extends AsyncTask<Void, Void, Void> {
GetResponse mcallback;
public AsyncTaskForApiSync(GetResponse mcallBack){
this.mcallback=mcallBack;
}
@Override
protected Void doInBackground(Void... voids) {
//retrofit api call in on success
mcallback.onSuccess(response);
}
}
对不起,我的英语。另外,如果您发现任何问题,请告诉我。谢谢。