Как получить доступ к результату void onComplete () Задачи - PullRequest
0 голосов
/ 18 мая 2018

Я работаю с библиотекой, странно спроектированной, этот код в основном имеет объект Task с onComplete() и onfail() методами, оба эти метода недействительны, поэтому я не могу использовать return внутри них.

Я пытался использовать внешнюю переменную, обновленную внутри задачи onComplete() и onfail(), используя

mytask.wait();
return value; 

с намерением дождаться завершения задачи и затем вернуть значение, но я получаю

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

если я попробую что-то вроде

while(!mytask.isComplete(){}

, чтобы заставить метод ждать завершения

приложение полностью зависнет

Как я могу получить значение призавершение задания правильно?

Ответы [ 2 ]

0 голосов
/ 19 мая 2018

java.lang.IllegalMonitorStateException: объект не заблокирован потоком до wait ()

Вы находитесь рядом, но у вас отсутствует некоторая синхронизация.Чтобы сделать wait() или notify(), вам нужно находиться в блоке synchronized.

Если вы хотите написать задачу, которая возвращает какое-то значение, я бы сделал что-то вроде следующего.Получите результат в поле, обновите это поле внутри методов synchronized onComplete() или onFail().Тогда ваш вызывающий поток может использовать метод waitForResult(), чтобы вернуть его, как только он завершится.

public class MyTask implements Task {
    private String result;
    public synchronized void onComplete() {
        result = "it worked";
        // this is allowed because the method is synchronized
        notify();
    }
    public synchronized void onFail() {
        result = "it failed";
        // this is allowed because the method is synchronized
        notify();
    }
    public synchronized String waitForResult() {
        // a while loop is a good pattern because of spurious wakeups
        // also, it's important to realize that the job might have already
        // finished so we should always test it _before_ we wait
        while (result == null) {
            wait();
        }
        return result;
    }
}

Поток, который проверяет все для завершения, должен будет просто сделать:

String result = myTask.waitForResult();

Надеюсь, это поможет.

0 голосов
/ 18 мая 2018

Вы можете создать interface, передать его AsyncTask (в конструкторе), а затем вызвать метод в onPostExecute()

Например:

Ваш интерфейс:

public interface OnTaskCompleted{
    void onTaskCompleted();
}

Ваша активность:

public class YourActivity implements OnTaskCompleted{
    // your Activity
}

И ваша AsyncTask:

public class YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type
    private OnTaskCompleted listener;

    public YourTask(OnTaskCompleted listener){
        this.listener=listener;
    }

    // required methods

    protected void onPostExecute(Object o){
        // your stuff
        listener.onTaskCompleted();
    }
}
...