Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.74
St@nton
3 / 3 / 2
Регистрация: 04.01.2013
Сообщений: 72
#1

AsyncTask как дождаться окончания - Программирование Android

22.06.2014, 07:19. Просмотров 4439. Ответов 11
Метки нет (Все метки)

Всем привет. Ситуация следующая. Есть активити "MyTravelList" со списком, которое после нажатия на кнопку, запускает другое активити "TravelsMap". Оно, в свою очередь, сразу (в конце onCreate() ) создаёт экземпляр класса "TravelMaker", в конструкторе которого запускается AsyncTask. Мне нужно, чтобы активити "TravelsMap" совершала дальнейшие действия полсе того, как AsyncTask завершится. Написал следующее:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class TravelsMap extends Activity {
 
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 
    showTravel();
}
 
private void showTravel() {
    
    TravelMaker tm = new TravelMaker();
 
    while(tm.MyTask.getStatus() != AsyncTask.Status.FINISHED) wait();
 
    //дальнейшие действия
}
 
}
 
}
Написал и сначала всё работало. Ничего не менял, но потом перестало работать. Exception:

java.lang.IllegalMonitorStateException: object not locked by thread before wait()

В чём тут может быть дело?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.06.2014, 07:19
Я подобрал для вас темы с готовыми решениями и ответами на вопрос AsyncTask как дождаться окончания (Программирование Android):

Дождаться завершения работы AsyncTask и выполнять код дальше
Помогите, пожалуйста. Мне нужно дождаться завершения работы AsyncTask и только...

Как остановить AsyncTask?
Не ругайтесь на код:) с Asynctask работаю только несколько дней class MyTask...

Как обновить TextView с AsyncTask?
private class DownloadFilesTask extends AsyncTask<String, Integer, Long> { ...

Как приостановить doInBackground() из AsyncTask
Здравствуйте. Есть экземпляр AsyncTask и активити с WebView. AsyncTasd...

Как из AsyncTask Добавить элементы в ListView
В общем сабж. Используя адаптер как сделать?

Как дождаться завершения RequestTask?
при создании активити в new RequestTask().execute делаю веб запрос, по...

11
RaiaNKnight
96 / 70 / 12
Регистрация: 29.06.2011
Сообщений: 465
Записей в блоге: 1
22.06.2014, 12:32 #2
Это плохая идея ждать в цикле завершения AsyncTask'a. Чертовски плохая. Они ведь не для этого создавались!!
Сам AsyncTask должен вызывать нужный ему обработчик события.

Решение, которое подойдёт вам:
1) Создаёте интерфейс, какой-нибудь AsyncTaskListener;
2) Добавляете ему метод onAsyncTaskFinished();
3) Нужная активити пусть реализовывает этот интерфейс, т.е. TravelsMap implements AsyncTaskListener;
4) Добавляете реализацию метода onAsyncTaskFinished в TravelsMap;
5) В этом методе можно будет что угодно творить с нужной вам активити TravelsMap;
6) В AsyncTask вы передаетё свою активити (как параметр) и в методе onPostExecute() вызываете у своей активити нужный вам обработчик события завершения AsyncTask, т.е. onAsyncTaskFinished;
7) Тогда после завершения AsyncTask'а у вас выполняются нужные вам действия
4
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
22.06.2014, 13:09 #3
RaiaNKnight, а если просто в onPostExecute() обратиться к методу класса TravelsMap? Оъясните пожалуйста, что дает реализация интерфейса?
У меня такая же задача, обращение идет к статическому методу, что неудобно, если приходится из этого метода обращаться к другим методам класса.
0
RaiaNKnight
96 / 70 / 12
Регистрация: 29.06.2011
Сообщений: 465
Записей в блоге: 1
22.06.2014, 14:19 #4
Реализация интерфейса избавляет вас от необходимости иметь статический метод в TravelsMap, т.е. в Activity. По сути вы хотите из статического метода работать с инкапсулированными данными TravelsMap. Это плохо.

А интерфейс, вернее его реализация - это и будет сама Activity, TravelsMap. И она будет обращаться не из статических методов к своим полям.

Насколько я знаю, к методам TravelsMap вы можете обратиться либо через экземпляр этого класса, либо через статические методы.

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

Добавлено через 6 минут
P.S. Я думаю, ещё много причин и плюсов можно найти, почему так следует сделать, ООП же. Это решение я вычитал на stackoverflow, оно хорошо работает.
1
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
22.06.2014, 15:53 #5
Цитата Сообщение от RaiaNKnight Посмотреть сообщение
Реализация интерфейса избавляет вас от необходимости иметь статический метод в TravelsMap
Так я и знал, что что-то должно быть). Спасибо за подсказку.
0
YuraAAA
1578 / 1319 / 282
Регистрация: 25.10.2009
Сообщений: 3,436
Записей в блоге: 2
22.06.2014, 16:36 #6
Так это вообще easy. Добавим ещё generic type.

Интерфейс это такая структура, которая описывает лишь правила поведения. Она описывает что нужно делать, но не КАК это делать.

Java
1
2
3
4
5
6
7
8
9
10
11
public interface IWorkerCallback<V> {
 
    void onBegin(); //Асинхронная операция началась
 
    void onSuccess(V data); //Получили результат
 
    void onFailure(Throwable t); //Получили ошибку
 
    void onEnd(); //Операция закончилась
 
}
2. Опишем абстрактную универсальную асинк таску


Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public abstract class AbstractAsyncWorker<V> extends AsyncTask<Void, Void, V> {
    private IWorkerCallback<V> callback;
    private Throwable t;
 
    //В конструктор передаём интерфейс
    protected AbstractAsyncWorker(IWorkerCallback<V> callback) {
        this.callback = callback;
    }
 
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if (callback != null) {
            callback.onBegin(); //Сообщаем через интерфейс о начале
        }
    }
 
    protected abstract V doAction() throws Exception; //Этот метод будем переопределять
 
    @Override
    protected V doInBackground(Void... params) {
        try {
            return doAction(); //В параллельном потоке вызываем абстрактный метод.
        } catch (Exception e) {
            t = e;
            return null;
        }
    }
 
    @Override
    protected void onPostExecute(V v) {
        super.onPostExecute(v);
        if (callback != null) {
            callback.onEnd(); //Сообщаем об окончании
        }
        generateCallback(v);
    }
 
    private void generateCallback(V data) { //Генерируем ответ
        if (callback == null) return;
        if (data != null) { //Есть данные - всё хорошо
            callback.onSuccess(data);
        } else if (t != null) {
            callback.onFailure(t); //Есть ошибка - вызываем onFailure
        } else { //А такая ситуация вообще не должна появляться)
            callback.onFailure(new NullPointerException("Result is empty but error empty too"));
        }
    }
}

3. Вызов.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Test implements IWorkerCallback<Integer> {
 
    private void doSomethingAsyncOperaion() {
        new AbstractAsyncWorker<Integer>(this) {
            @Override
            protected Integer doAction() throws Exception {
                Thread.currentThread().wait(1000);
                return 1;
            }
        }.execute();
    }
 
    @Override
    public void onBegin() {
        Log.d("Async", "Begin");
    }
 
    @Override
    public void onSuccess(Integer data) {
        Log.d("Async", "Success:" + data);
    }
 
    @Override
    public void onFailure(Throwable t) {
        Log.d("Async", "Failure", t);
    }
 
    @Override
    public void onEnd() {
        Log.d("Async", "End");
    }
}
5
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
22.06.2014, 17:47 #7
YuraAAA, ух шайтан...
0
St@nton
3 / 3 / 2
Регистрация: 04.01.2013
Сообщений: 72
22.06.2014, 20:26  [ТС] #8
Цитата Сообщение от Rube Посмотреть сообщение
YuraAAA, ух шайтан...
Поддерживаю

Всем большое спасибо. Теперь всё работает) Не ожидал столь доходчивых ответов)
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
23.06.2014, 12:46 #9
YuraAAA,
Все работает, но вот что интересно: я раньше из активити передавал this в конструктор AsyncTask (чтобы ProgressDialog показать). А теперь надо еще и второй параметр this передавать, для присвоения интерфейса?
Java
1
2
3
4
5
6
7
8
// вызов из активити
new GetUpdate(this, this).execute(toUpdate)
 
// конструктор класса с AsyncTask 
public GetUpdate(Context context, IWorkerCallback callback) {
    this.context = context;
    this.callback = callback;
}
0
YuraAAA
1578 / 1319 / 282
Регистрация: 25.10.2009
Сообщений: 3,436
Записей в блоге: 2
24.06.2014, 13:32 #10
Rube, да, всё верно
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,317
08.08.2015, 01:13 #11
Java
1
2
3
4
5
6
7
8
9
10
11
public interface IWorkerCallback<V> {
 
    void onBegin(); //Асинхронная операция началась
 
    void onSuccess(V data); //Получили результат
 
    void onFailure(Throwable t); //Получили ошибку
 
    void onEnd(); //Операция закончилась
 
}
В этом коде не совсем понятно что такое V??
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
08.08.2015, 09:07 #12
Цитата Сообщение от yura91 Посмотреть сообщение
В этом коде не совсем понятно что такое V?
Можно V вообще не писать.
0
08.08.2015, 09:07
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.08.2015, 09:07
Привет! Вот еще темы с решениями:

Как получить значение String из UI потока в потоке AsyncTask?
Есть 4 шт. EditText. Нужно получить их значения в потоке AsyncTask. Вот весь...

Как написать простейший запрос на сервер без использование AsyncTask
как написать простейший запрос на сервер? без использование AsyncTask. у меня...

Как реализовать Синхронное выполнение двух функций при вызове AsyncTask
как сделать так чтобы при нажатии на BUTTON с начало выполнилась функция ...

Как отследить момент окончания аудио в SoundPool?
Нужно отключить анимацию рта по окончании, соответственно, речи=)


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru