Получение ссылки на вызов Activity из AsyncTask (НЕ как внутренний класс) - PullRequest
6 голосов
/ 27 апреля 2010

Возможно ли вообще изнутри AsyncTask, который НЕ является внутренним классом вызывающего класса Activity, получить ссылку на экземпляр Activity, который инициировал выполнение AsyncTask?

Мне известно о этой теме , однако она не совсем точно описывает, как ссылаться на вызывающую активность. Некоторые предлагают передать ссылку на Activity в качестве параметра конструктору AsyncTask, однако сообщается, что это всегда приводит к исключению NullPointerException.

Итак, я в растерянности. Мой AsyncTask обеспечивает надежную функциональность, и я не хочу дублировать его как внутренний класс в каждой Деятельности, которая хочет его использовать. Должно быть элегантное решение.

Ответы [ 2 ]

10 голосов
/ 27 апреля 2010

«Элегантное решение» состоит в том, чтобы на самом деле попробовать передать его в качестве параметра (конструктору или execute()) и посмотреть, работает ли оно, вместо того, чтобы предположить человека, который задал этот предыдущий вопрос (затем ответил на свой вопрос дважды) знает, что делает. Я не могу придумать ничего, присущего AsyncTask, которое могло бы привести к тому, что Activity будет плохим параметром конструктора, а любой другой объект будет просто в порядке.

Теперь я не передал Activity (или другой Context) в качестве параметра AsyncTask, потому что мои AsyncTasks всегда являются закрытыми внутренними классами. Фактически, тот факт, что вы хотите публичную AsyncTask для меня, является запахом кода, предполагая, что эти задачи должны быть опосредованы Service или какой-либо другой контрольной точкой. Но это только я.

UPDATE

Лучший ответ для работы с этим шаблоном можно найти здесь: Фоновая задача, диалог прогресса, изменение ориентации - есть ли 100% -ное рабочее решение?

4 голосов
/ 27 апреля 2010

Мои AsyncTask всегда живут в отдельном пакете, но все еще привязаны к определенному типу Activity. Они принимают его экземпляр в конструкторе и сохраняют в локальной переменной.
Попробуйте думать с точки зрения создания абстрактного Activity класса, который инкапсулирует AsyncTask связанный материал и расширяется другими действиями.
Вот так:

public abstract RemoteListActivity<T> extends ListActivity{

// calls AsyncTask, shows spinning progress dialog, etc

protected abstract T someConcreteMethod();

}

public final class CustomerListActivity extends RemoteListActivity<Customer>{

protected final Customer someConcreteMethod();

}

В качестве альтернативы, если вещи не вписываются в одну иерархию, есть интерфейс:

interface LazyLoadable {
    void setLoadingState();
    void setDefaultState();
}

public class MyActivity extends Activity implements LazyLoadable{
}

public final class AsyncTask extends AsyncTask<Void, Void, Void>{

    private final LazyLoadable lazyLoadable;

    public MyAsyncTask(Context ctx, LazyLoadable lazyLoadable){
        super(ctx);
        this.lazyLoadable = lazyLoadable;
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...