Я постоянно расстраивался этим, и я не могу найти хороший ответ, поэтому надеемся, что кто-то здесь может предложить руководство.фрагменты, когда я «активен»?
У меня есть фрагмент, который довольно широко использует AsyncTask
. я постоянно страдает от ошибок, когда фрагмент вызывает getActivity()
, который возвращает null. Я предполагаю, что это происходит из-за того, что какой-либо метод в фрагменте активируется до того, как действие будет подключено или после его отсоединения.
Каков правильный способ справиться с этим в моем коде? я не хочу, чтобы эта идиома валялись повсюду,
Activity activity = getActivity();
if (activity != null) { // do something }
глядя на документы для Fragment
, я могу придумать множество возможных крюков для решения этой проблемы: isDetached()
, onActivityCreated()
, onAttach()
, isResumed()
, и скоро. Какая правильная комбинация?
EDIT:
Несколько человек предложили отменить задачи во время паузы, но это означает, что стандартная идиома,
new AsyncTask<...>.execute();
не могут быть использованы. Это означает, что каждый exec'd AsyncTask
должен быть отслежен до завершения или отменен. Я просто никогда не видел этого в примере кода от Google или в другом месте. Нечто подобное,
private final Set<AsyncTask<?>> tasks = new HashSet<>;
...
AsyncTask<?> t = new AsyncTask<...>() {
...
public void onPostExecute(...) {
tasks.remove(this);
...
}
}
tasks.add(t);
t.execute();
...
@Override
public void onPause() {
for (AsyncTask<?> t: tasks) {
t.cancel();
}
tasks.clear();
}
Определенно не ответ, но ... Ваша ошибка является архитектурной.Я не знаю точно, что вы делаете с AsyncTasks, но могу сказать, что если getActivity возвращает null, пока один из них запущен, вы не должны использовать AsyncTask. Все, что вы делаете в задаче, должно выполняться в Службе. Операция/фрагмент, который должен знать состояние поиска, может попросить Службу получить. Проверьте IntentService: он прост в использовании и намного проще, чем AsyncTask (нормально, теперь подождите: он проще, чем AsyncTask на самом деле ** **, не проще, чем он появляется). –
@ G.BlakeMeike спасибо за отзыв. у нас на самом деле есть оба шаблона в приложении: «IntentService» и «AsyncTask». Я предпочитаю семантику вызова 'AsyncTask'. Re: неправильная архитектура - я не знаю, согласен ли я. в любое время, когда вам нужен контекст, вы должны называть 'getActivity()'. так что нужно, чтобы сказать, что строка в onPostExecute() означает, что у меня неправильная арка? –
Ну .. да, я думаю, это в значительной степени то, что я говорю. Вся сделка с AsyncTask заключается в том, что у нее есть жизненный цикл, полностью отделенный от действий. Вы не можете рассчитывать на * любой * контекст активности, находящийся вокруг, в любой момент времени в жизни AT. Рассматривали ли вы передачу ApplicationContext в конструктор AT? –