AsyncTask Best Practice о том, как проверить, продолжается ли все еще действие - PullRequest
4 голосов
/ 03 августа 2011

После завершения AsyncTask я обычно выполняю одно из следующих действий;

  1. Вызовите метод для объекта / интерфейса обратного вызова, который я определил в действии, и передайте конструктору подкласса My AsyncTask.
  2. Предоставьте AsyncTask с обработчиком и вызовите myHandler.sendMessage () когда задача завершена.

Я хочу спросить, что считается наилучшей практикой после завершения AsyncTask.Если пользователь нажал кнопку «Домой» во время обработки задачи, действие больше не находится на переднем плане.Как только приложение пытается выполнить какую-либо операцию пользовательского интерфейса, в ответ на выполнение задачи ОС выдает исключение WindowManager $ BadTokenException.

Я, конечно, могу окружить свой код пользовательского интерфейса ловушкой для исключения BadTokenException.Это кажется хакерским.Есть ли какой-нибудь способ узнать, находится ли активность впереди?

Ответы [ 4 ]

2 голосов
/ 03 августа 2011

Может быть, вам не понравится мой ответ, но я считаю AsyncTask неработающим (по причинам, подобным этому).

Редактировать: Мой первоначальный ответ рекомендовал использовать IntentService и транслировать результат.Это так же неэффективно, как отправка письма себе.

Вы можете использовать AsyncTaskLoader, который решает проблемы AsyncTask, но API AsyncTaskLoader далек оттакже идеально.В частности, вы должны убедиться, что идентификатор загрузчика уникален, и знать, что результаты кэшируются для идентификатора, а не для аргументов.Кроме того, распространение исключения так же прервано, как и в случае AsyncTask.

Более современный и безопасный способ решения этой проблемы - использовать Guava future .

1 голос
/ 06 октября 2011

Вы можете проверить, активна ли активность или нет. Я обычно делаю свой подкласс AsyncTask как статический (чтобы избежать утечки памяти), поэтому я передаю ссылку на действие (снова обернутую в WeakReference, чтобы избежать утечек памяти).

Когда выполняется onPostExecute, я выполняю необходимые проверки при использовании WeakReferences плюс вызов Activity.isFinishing () для действия, чтобы я мог проверить, что действие не находится в процессе уничтожения, чтобы избежать изменений пользовательского интерфейса выполнения в умирающем действии.

1 голос
/ 04 августа 2011

Это означает, что вы используете тот, где контекст не подходит.Чтобы снять сомнения по поводу исключения, смотрите эту ссылку. Исключение плохого токена

0 голосов
/ 03 августа 2011

Определите объект вашей активности в onStart () как статический член -

private static MyActivity mActivity = null;
public void onStart() {
    mActivity = this;
}

public void onDestroy() {
    mActivity = null;
}

Затем в вашем методе AsyncTask сделайте что-то вроде:

if (mActivity != null) {
    mActivity.doSomething();  //make sure to use static member
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...