Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.74
St@nton
3 / 3 / 0
Регистрация: 04.01.2013
Сообщений: 72
#1

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

22.06.2014, 07:19. Просмотров 3691. Ответов 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 и выполнять код дальше - Программирование Android
Помогите, пожалуйста. Мне нужно дождаться завершения работы AsyncTask и только потом выполнять код дальше. Я уже понял, что для этого нужно...

Как остановить AsyncTask? - Программирование Android
Не ругайтесь на код:) с Asynctask работаю только несколько дней class MyTask extends AsyncTask<Void, Void, Void> { @Override...

Как обновить TextView с AsyncTask? - Программирование Android
private class DownloadFilesTask extends AsyncTask<String, Integer, Long> { protected Long doInBackground(String... urls) { ...

Как приостановить doInBackground() из AsyncTask - Программирование Android
Здравствуйте. Есть экземпляр AsyncTask и активити с WebView. AsyncTasd выполняет действия с сетью, передает некий url WebView....

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

Как дождаться завершения RequestTask? - Программирование Android
при создании активити в new RequestTask().execute делаю веб запрос, по результатам которого достраивается интерфейс... т.к. в потоке его...

11
RaiaNKnight
96 / 70 / 7
Регистрация: 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,071
22.06.2014, 13:09 #3
RaiaNKnight, а если просто в onPostExecute() обратиться к методу класса TravelsMap? Оъясните пожалуйста, что дает реализация интерфейса?
У меня такая же задача, обращение идет к статическому методу, что неудобно, если приходится из этого метода обращаться к другим методам класса.
0
RaiaNKnight
96 / 70 / 7
Регистрация: 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,071
22.06.2014, 15:53 #5
Цитата Сообщение от RaiaNKnight Посмотреть сообщение
Реализация интерфейса избавляет вас от необходимости иметь статический метод в TravelsMap
Так я и знал, что что-то должно быть). Спасибо за подсказку.
0
YuraAAA
1576 / 1317 / 271
Регистрация: 25.10.2009
Сообщений: 3,438
Записей в блоге: 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,071
22.06.2014, 17:47 #7
YuraAAA, ух шайтан...
0
St@nton
3 / 3 / 0
Регистрация: 04.01.2013
Сообщений: 72
22.06.2014, 20:26  [ТС] #8
Цитата Сообщение от Rube Посмотреть сообщение
YuraAAA, ух шайтан...
Поддерживаю

Всем большое спасибо. Теперь всё работает) Не ожидал столь доходчивых ответов)
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,071
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
1576 / 1317 / 271
Регистрация: 25.10.2009
Сообщений: 3,438
Записей в блоге: 2
24.06.2014, 13:32 #10
Rube, да, всё верно
0
yura91
1 / 25 / 2
Регистрация: 23.10.2013
Сообщений: 2,305
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,071
08.08.2015, 09:07 #12
Цитата Сообщение от yura91 Посмотреть сообщение
В этом коде не совсем понятно что такое V?
Можно V вообще не писать.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.08.2015, 09:07
Привет! Вот еще темы с ответами:

Как получить значение String из UI потока в потоке AsyncTask? - Программирование Android
Есть 4 шт. EditText. Нужно получить их значения в потоке AsyncTask. Вот весь мой код package com.examplemy.activity2; ...

Как написать простейший запрос на сервер без использование AsyncTask - Программирование Android
как написать простейший запрос на сервер? без использование AsyncTask. у меня есть локальный сервер который возвращает JSON адрес...

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

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


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

Или воспользуйтесь поиском по форуму:
12
Yandex
Объявления
08.08.2015, 09:07
Ответ Создать тему
Опции темы

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