Метод join () не ждет завершения потока

У меня есть AsyncTask, и в его методе doInBackground я вызываю метод другого класса:

@Override
protected ArrayList<CustomClass> doInBackground(ArrayList<CustomClass>...  array) {
    ArrayList<CustomClass> retorno= DataNetwork.GetCustomClassArrayList(array[0],(...more parameters...));
    return retorno;
}

В DataNetwork у меня есть этот метод, который выполняет вызов REST и возвращает результат. Я вынужден использовать библиотеку, которая выполняет вызов REST (я думаю, что она использует Volley, но я не уверен. Чтобы вызвать эту библиотеку, мне нужно сделать Intent, который передается методу makeRESTCall):

public static ArrayList<CustomClass> GetCustomClassArrayList(various params goes here){
ArrayList<CustomClass> toReturn;
    //some parameters processing
    library.makeRESTCall(Intent intent){
        //processing the answer
        toReturn=processAnswerJSONResponse();
    }
return toReturn;
}

Таким образом, я перехожу к строке возврата к возврату до того, как будет обработан ответ от REST. Итак, я попытался создать поток и использовать оператор соединения. Метод GetCustomClassArrayList (ну, большая его часть, до t.start ()) теперь находится внутри потока. Конец метода теперь:

(...)
 t.start();
    try {
        t.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return toReturn;

Выполнение вызывает t.join () сразу после t.start (); и toReturn имеет значение null.

Возможно, это вопрос новичка, но использование метода join () всегда помогало мне, и я ждал завершения потока, прежде чем вводить оператор return. Без исключения, без ошибок. Он просто не ждет завершения потока.

Почему сейчас не работает? Что я могу сделать, чтобы дождаться выполнения переменной toReturn, прежде чем вводить оператор возврата?

Спасибо.

Re: «Выполнение вызывает t.join() сразу после t.start()». Это почти никогда не имеет смысла. Зачем начинать новый поток, если у уже существующего потока нет работы до завершения нового потока? Вы могли бы просто вместо этого вызвать t.run().

Solomon Slow 15.10.2018 17:18
0
1
22
1

Ответы 1

Проблема, вероятно, связана с использованием библиотеки, которая уже возвращает ответ асинхронно, поэтому ваш AsyncTask не блокируется. Проверьте документацию библиотеки.

AsyncTask не похож на нормальную нить. Он специализируется на однократном выполнении, блокируя, если необходимо, в методе doInBackground, а затем возвращает результаты для обработки в основном потоке. Если ваша сторонняя библиотека REST имеет синхронную версию своих вызовов, вы можете использовать ее в своем AsyncTask, но она, вероятно, будет менее эффективной, чем встроенные функции библиотеки.

«Проверьте документацию библиотеки» ... это рассмешило меня. Это внутренняя библиотека, и документации нет ... В любом случае спасибо за ваш ответ.

Fustigador 15.10.2018 13:41

Если это внутренняя библиотека, я бы рекомендовал подробнее изучить ее код, чтобы узнать, что она делает с обратным вызовом / закрытием, которое вы предоставляете. Если он сохраняет его, а затем отправляет его на Handler или использует какой-либо другой механизм для обратного вызова в определенном потоке (например, с помощью планировщиков RxJava / RxAndroid), вы, скорее всего, можете полностью избавиться от использования AsyncTask. Просто убедитесь, что ваш код настроен на асинхронную обработку.

Larry Schiefer 15.10.2018 14:07

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