我们可以在Android Studio的循环内使用Retrofit吗?

时间:2019-02-07 06:42:17

标签: android android-studio for-loop retrofit retrofit2

我知道这种奇怪的问题,但是我试图在for循环中使用我的Retrofit调用。我正在做的是在通话中使用insertdata(seperated2[0], seperated2[1], email, tag);

之类的函数向我的String []元素一个接一个地发送

但是当他们跳过对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()之外使用它们时,值显示正确。

我知道使用翻新这样的做法不是很好的做法,但是我很好奇它在这种情况下会如何反应。任何人都可以提供帮助或提出建议吗?

谢谢!!

4 个答案:

答案 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);
    
        }
    
        }

对不起,我的英语。另外,如果您发现任何问题,请告诉我。谢谢。