Подождите, синхронный обратный вызов?

Предположим, у меня есть следующий код:

private void getResource(String mac, String resource) {
int threadID = android.os.Process.myTid();

Log.e( "", "Marker 1" );
Mds.builder().build(mContext).get(SCHEME_PREFIX + mac + resource, null, new MdsResponseListener() {
    @Override
    public void onSuccess(String data, MdsHeader header) {
        Log.e( "", "Marker 2" );
        
        int callbackTID = android.os.Process.myTid();
        if ( callbackTID == threadID) {
            Log.e("", "Same Thread");
        }

        else{
            Log.e("", "Different Thread");
        }
      }
  });

Log.e( "", "Marker 3" );
}

Похоже, что обратный вызов, который я указал в new MdsResponseListener, выполняется в потоке одно и тоже, который сделал общий вызов функции для get(...), потому что threadID и callbackTID идентичны.

Однако журнал ясно показывает, что "Marker 3" напечатан перед"Marker 2", который, насколько я понимаю, говорит мне, что это все-таки асинхронный обратный вызов. Как это может быть? Я новичок в Java (и Android), поэтому, возможно, мне не хватает важных базовых знаний здесь.

Как можно реализовать метод ожидания обратного вызова? Я пробовал это с CoundDownLatch, который просто ведет обратный отсчет в методе onSuccess и ожидает до печати журнала "Marker 3"log, но, как я и ожидал, я застрял, потому что, по-видимому, обратный вызов выполняется в том же потоке, что и ожидающий.

проверьте, есть ли не асинхронная функция get .. поместите все в новый поток, и он обновит поток пользовательского интерфейса ..

Itzik Samara 01.07.2018 18:37

К сожалению, синхронизированной функции get нет. Я пробовал использовать асинхронное получение в потоке, однако обратный вызов все еще выполняется в основном потоке.

Hafnernuss 01.07.2018 18:38

Ну, это немного грязно, но вы можете запустить таймер с таймером обратного отсчета в начале get, который при 0 будет делать маркер 3 ... не рекомендуется, но его решение ..

Itzik Samara 01.07.2018 18:43

Это не решит проблему. Мне нужно будет дождаться обратного вызова, прежде чем вернуться из моей функции. Я не совсем понимаю, как этого добиться с помощью таймера?

Hafnernuss 01.07.2018 18:49
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
173
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Пример 1:

       Log.e( "", "Marker 1" );
    Mds.builder().build(mContext).get(SCHEME_PREFIX + mac + resource, null, new MdsResponseListener() {
        @Override
        public void onSuccess(String data, MdsHeader header) {
            Log.e( "", "Marker 2" );
            doSomething() // Your method call when response is ready

      });

    private void doSomething() {
     Log.e( "", "Marker 3" );
   }

    }

Пример 2 (RxJava)

Obserable.create( source -> 
Mds.builder().build(mContext).get(SCHEME_PREFIX + mac + resource, null, new MdsResponseListener() {
    @Override
    public void onSuccess(String data, MdsHeader header) {
     source.onNext(data)
     source.onComplete()
  });
)

Затем подпишитесь на этот наблюдаемый объект, и вы сможете управлять subscribeOn / ObservOn.

NOTE: This is only pseudo code and shows how it can be done.

Я знаю, что уже поздно, но ты был прав. В то время я даже не понимал основ Rx;)

Hafnernuss 15.10.2020 16:23

Другие вопросы по теме