Как отменить все запросы в очереди на отказ?(Retrofit2) - PullRequest
0 голосов
/ 14 декабря 2018

На самом деле я использую Retrofit2 в своем приложении для отправки некоторого текста на мой сервер.

Проблема в том, когда я использую радиочастотное устройство, когда сеть прерывается, поэтому я получаювызов должен быть отменен, но как только устройство снова подключается к сети, кажется, что оно повторно отправляет текст или что-то подобное, этот текст остается в очереди, и я бы обработал его.

Вот мой метод, в котором я отправляютекст (я еще пытался использовать call.cancel () в onFailure, но это не имеет никакого эффекта)

  @SuppressLint("DefaultLocale")
    public void sendPost() {
        @SuppressLint({"SdCardPath", "DefaultLocale"}) final File file = new File("/data/data/app/files/"+String.format("%03d", Integer.valueOf(nTerminalino))+"_"+nTavoli.getText().toString()+".txt");

        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);

        RequestBody fbody = RequestBody.create(MediaType.parse("text/*"), file);
        builder.addFormDataPart(String.format("%03d", Integer.valueOf(nTerminalino))+"_"+nTavoli.getText().toString(), file.getName(),fbody);

        MultipartBody requestBody = builder.build();

        final APIService apiService = ApiUtils.getAPIService(ipCASSA);

        final Call<Void> calls = apiService.savePost(requestBody);

        calls.enqueue(new Callback<Void>() {
            @Override
            public void onResponse(@NonNull Call<Void> call, @NonNull Response<Void> response) {
                if (response.isSuccessful()) {
                    Log.i("RESPONSE: ", response.toString());
                    Print();
                    file.delete();
                    dialogLoading.dismiss();
                    Runtime.getRuntime().gc();
                }else {
                    calls.cancel();
                }
            }

            @Override
            public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
                    Log.e("TAG", t.toString());
                    MediaPlayer mpFound = MediaPlayer.create(pterm.this, R.raw.errorsound);
                    mpFound.start();
                    Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                    if (v.hasVibrator()) {
                        v.vibrate(6000);
                    }
                    new GlideToast.makeToast(pterm.this, "CONNESSIONE FALLITA!", GlideToast.LENGTHLONG, GlideToast.FAILTOAST).show();
                    dialogLoading.dismiss();

            }
        });
    }

В моем классе, где я создаю OkHttpClient, я установил retryOnConnectionFailure (false), но все ещене может решить проблему, что даже при сбое я получаю запрос POST.

ОБНОВЛЕНИЕ:

После некоторых исследований я обнаружил, что OkHttp делает тихую повторную попытку POST при сбое соединения.

Так, как я могу предотвратить клиентуповторить попытку?

НЕКОТОРАЯ ИНФОРМАЦИЯ:

Мое приложение - приложение для официанта, поэтому, когда я получаю сообщение onFailure, я уведомляю официанта о том, что квитанция не поступила.не был получен POS и не был распечатан, но, поскольку OkHttpClient все еще повторяет попытку отправки файла, и я заставляю официанта повторно отправить квитанцию ​​после onFailure, это вызывает печать дублированных квитанций.

Вот мой класс ApiUtils, интерфейс APIService и класс RetrofitClient

class ApiUtils {

    private ApiUtils() {}



    static APIService getAPIService(String ipCASSA) {

        String BASE_URL = "http://"+ipCASSA+"/web/";

        final OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(10000, TimeUnit.MILLISECONDS)
                .writeTimeout(10000, TimeUnit.MILLISECONDS)
                .readTimeout(10000, TimeUnit.MILLISECONDS)
                .retryOnConnectionFailure(false)
                .build();


        return RetrofitClient.getClient(BASE_URL,okHttpClient).create(APIService.class);
    }
}

public interface APIService {

    @POST("CART=PTERM")
    Call<Void> savePost(@Body RequestBody text);

}

class RetrofitClient {

    private static Retrofit retrofit = null;


    static Retrofit getClient(String baseUrl, OkHttpClient okHttpClient) {
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Вы можете попробовать отменить звонок напрямую.Поэтому при сбое вызова в обратном вызове onFailure вы можете сделать что-то вроде

@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
    if (!call.isCanceled()) {
        // Do receipt logic
        call.cancel();
    }
}
0 голосов
/ 17 декабря 2018

Поскольку retryOnConnectionFailure(false) не помогло, проблема не вызвана повторной попыткой OKHttp.

Я подозреваю, что вы дублируете запрос.Проверьте, вызывается ли sendPost() несколько раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...