Подтвердить что ты не робот

Как определить, работает ли данный запрос?

Я смотрю на модернизацию своего сетевого уровня. Есть ли способ узнать, работает ли какой-либо конкретный асинхронный запрос в любой момент?

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

4b9b3361

Ответ 1

То, что я лично закончил, в этом случае состояло в том, что я использовал пример с Retrofit, Android Priority Jobqueue (от yigit fork) и Отто-eventbus.

public enum SingletonBus {
    INSTANCE;

    private Bus bus;

    private Handler handler = new Handler(Looper.getMainLooper());

    private SingletonBus() {
        this.bus = new Bus(ThreadEnforcer.ANY);
    }

    public <T> void postToSameThread(final T event) {
        bus.post(event);
    }

    public <T> void postToMainThread(final T event) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                bus.post(event);
            }
        });
    }

    public <T> void register(T subscriber) {
        bus.register(subscriber);
    }

    public <T> void unregister(T subscriber) {
        bus.unregister(subscriber);
    }
}

public interface Interactor {
    void injectWith(PresenterComponent presenterComponent);
}

public interface SendCertificateRequestInteractor
        extends Interactor {
    interface Listener {
        void onSuccessfulEvent(SuccessfulEvent e);

        void onFailureEvent(FailureEvent e);
    }

    class SuccessfulEvent
            extends EventResult<CertificateBO> {
        public SuccessfulEvent(CertificateBO certificateBO) {
            super(certificateBO);
        }
    }

    class FailureEvent
            extends EventResult<Throwable> {
        public FailureEvent(Throwable throwable) {
            super(throwable);
        }
    }

    void sendCertificateRequest(String username, String password);
}

Обратите внимание на Job здесь:

public class SendCertificateRequestInteractorImpl
        implements SendCertificateRequestInteractor {
    private Presenter presenter;

    private boolean isInjected = false;

    @Inject
    public JobManager jobManager;

    public SendCertificateRequestInteractorImpl(Presenter presenter) {
        this.presenter = presenter;
    }

    @Override
    public void sendCertificateRequest(String username, String password) {
        if(!isInjected) {
            injectWith(presenter.getPresenterComponent());
            isInjected = true;
        }
        InteractorJob interactorJob = new InteractorJob(presenter, username, password);
        long jobId = jobManager.addJob(interactorJob); //this is where you can get your jobId for querying the status of the task if you want
    }

    @Override
    public void injectWith(PresenterComponent presenterComponent) {
        presenterComponent.inject(this);
    }

    public static class InteractorJob
            extends Job {
        private final static int PRIORITY = 1;
        private final static String TAG = InteractorJob.class.getSimpleName();

        private String username;
        private String password;

        @Inject
        public MyService myService;

        public InteractorJob(Presenter presenter, String username, String password) {
            super(new Params(PRIORITY).requireNetwork());
            presenter.getPresenterComponent().inject(this);
            this.username = username;
            this.password = password;
        }

        @Override
        public void onAdded() {
            // Job has been saved to disk.
            // This is a good place to dispatch a UI event to indicate the job will eventually run.
            // In this example, it would be good to update the UI with the newly posted tweet.
        }

        @Override
        public void onRun()
                throws Throwable {
            String certificate = myService.getCertificate(username, password);
            SingletonBus.INSTANCE.postToMainThread(new SuccessfulEvent(certificate));
        }

        @Override
        protected void onCancel() {
            // Job has exceeded retry attempts or shouldReRunOnThrowable() has returned false.
            Log.e(TAG, "Cancelled job.");
        }

        @Override
        protected boolean shouldReRunOnThrowable(Throwable throwable) {
            // An error occurred in onRun.
            // Return value determines whether this job should retry running (true) or abort (false).
            Log.e(TAG, "Failed to execute job.", throwable);
            SingletonBus.INSTANCE.postToMainThread(new FailureEvent(throwable));
            return false;
        }
    }
}

И затем

@Subscribe
@Override
public void onSuccessfulEvent(SendCertificateRequestInteractor.SuccessfulEvent e) {
    String certificate = e.getResult();
    //do things
}

@Subscribe
@Override
public void onFailureEvent(SendCertificateRequestInteractor.FailureEvent e) {
    Throwable throwable = e.getResult(); 
    //handle error
}

Подробнее о android priority jobqueue здесь.

Таким образом, технически обработка async относится к очереди заданий, в то время как сама модификация использует синхронный интерфейс. Он работает хорошо, пока вам не нужно обращаться к заголовкам ответа. Хотя, честно говоря, я был, также отслеживая, выполнялось ли задание с булевым, а не с менеджером заданий и с идентификатором.

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

Вам, вероятно, придется настроить это решение на свой собственный сценарий и использовать только то, что вам действительно нужно.

Ответ 2

Вот что я обычно делал бы при необходимости отслеживать выполняемые запросы:

  • Сначала, используя модификацию, как только вы сделаете запрос, вы можете сделать следующее:
  • Используйте EventBus библиотеку, чтобы отправить событие в вашу деятельность или фрагмент. Теперь это можно сделать внутри метода onSuccess() вашего метода обратного вызова или onError().
  • В вашем мероприятии или фрагменте onEvent (событие EventClassName) вы можете просто проверить переменную типа [isRunning] из вашего события, чтобы убедиться, что если событие все еще запущено, вы обновляете пользовательский интерфейс соответственно, а если нет, сделайте то, что вам нужно сделать соответственно.
  • Когда запрос будет завершен, очевидно, что isRunning будет ложным, и вы сможете обновить пользовательский интерфейс, как ожидается от пользователя.
  • Я рекомендую EventBus здесь просто потому, что с ним гораздо проще отделить код приложения; вы можете отправлять различные события, которые уведомляют о действиях разных статусов ваших запросов, а затем обновляют ваш интерфейс таким образом.

Вы можете найти EventBus здесь

Надеюсь, это поможет!