Как остановить вызов в очереди после первого выполнения? - PullRequest
0 голосов
/ 02 апреля 2019

Я очень новичок в разработке Android. Попытка подключить какой-то сайт и получить с него данные. У меня эта функция вызывается только из onCreate в основной деятельности. Каждый раз, когда я поворачиваю виртуальный телефон Android влево или вправо, я вижу новые строки «run ()» в EditText и запросы в Wireshark. Как правильно это остановить?

Пробовал call.cancel () и mClient.dispatcher (). CancelAll () внутри OnResponse

protected void Load(String url) {
    Request request = new Request.Builder()
            .url(url)
            .build();

    mClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, final Response response) throws IOException {
            if (response.isSuccessful()) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mEdit.setText(mEdit.getText() + "run()\n");
                    }
                });
            }
        }

    });
}

Ответы [ 2 ]

0 голосов
/ 02 апреля 2019

onCreate вызывается каждый раз при изменении конфигурации (например, вы поворачиваете свой телефон / эмулятор). Для получения дополнительной информации: https://developer.android.com/guide/components/activities/activity-lifecycle

Вы можете сохранить свой ответ, чтобы запретить новый запрос для каждого onCreate. Примерно так:

MainActivity {
  private Response savedResponse;

  onCreate() {
    if (savedResponse == null) {
      Load(url)
    }
  }
}

и в вашем onResponse сохраните ответ:

 @Override
    public void onResponse(Call call, final Response response) throws IOException {
        if (response.isSuccessful()) {
            savedResponse = response;    // <----
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mEdit.setText(mEdit.getText() + "run()\n");
                }
            });
        }
    }

Однако правильным способом было бы отделить сетевые вызовы / запросы от жизненного цикла активности и загрузить данные в другое место (Service, WorkManager, ...)

0 голосов
/ 02 апреля 2019

дооснащение поддерживает отмену очереди, и это прекрасно работает. И я думаю, что если вы попытаетесь запустить этот код - ваша клиентская очередь будет остановлена ​​

protected void Load(String url) {
    Request request = new Request.Builder()
            .url(url)
            .build();

    Call<Response> mCall = mClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
                if (call.isCanceled()) {
                    Log.e(TAG, "request was cancelled");
                }
                else {
                    Log.e(TAG, "other larger issue, i.e. no network connection?");
                }
        }

        @Override
        public void onResponse(Call call, final Response response) throws IOException {
            if (response.isSuccessful()) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mEdit.setText(mEdit.getText() + "run()\n");
                    }
                });
            }
        }

    });

    mCall.cancel();
}

Я не знаю, как вы проектируете структуру и какие шаблоны вы используете (MVP, MVVM или другие), но в простом случае этот код можно улучшить, возвращая Call

protected void Load(String url): Call<Response>

И тогда вы можете изменить свой статус запроса, например, если он дольше 5 секунд, вы звоните call.cancel() и запрос останавливается.

...