У меня есть 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, прежде чем вводить оператор возврата?
Спасибо.
Проблема, вероятно, связана с использованием библиотеки, которая уже возвращает ответ асинхронно, поэтому ваш AsyncTask не блокируется. Проверьте документацию библиотеки.
AsyncTask не похож на нормальную нить. Он специализируется на однократном выполнении, блокируя, если необходимо, в методе doInBackground, а затем возвращает результаты для обработки в основном потоке. Если ваша сторонняя библиотека REST имеет синхронную версию своих вызовов, вы можете использовать ее в своем AsyncTask, но она, вероятно, будет менее эффективной, чем встроенные функции библиотеки.
«Проверьте документацию библиотеки» ... это рассмешило меня. Это внутренняя библиотека, и документации нет ... В любом случае спасибо за ваш ответ.
Если это внутренняя библиотека, я бы рекомендовал подробнее изучить ее код, чтобы узнать, что она делает с обратным вызовом / закрытием, которое вы предоставляете. Если он сохраняет его, а затем отправляет его на Handler или использует какой-либо другой механизм для обратного вызова в определенном потоке (например, с помощью планировщиков RxJava / RxAndroid), вы, скорее всего, можете полностью избавиться от использования AsyncTask. Просто убедитесь, что ваш код настроен на асинхронную обработку.
Re: «Выполнение вызывает
t.join()сразу послеt.start()». Это почти никогда не имеет смысла. Зачем начинать новый поток, если у уже существующего потока нет работы до завершения нового потока? Вы могли бы просто вместо этого вызватьt.run().