Фрагменты заменяются при выполнении AsyncTask – NullPointerException в getActivity ()

Недавно я преобразовал свою деятельность в фрагменты.

Используя что-то похожее на Tab-Navigation, фрагменты заменяются, когда пользователь выбирает другую вкладку. После заполнения фрагмента я запускаю хотя бы одну AsyncTask, чтобы получить некоторую информацию из Интернета. Однако, если пользователь переключится на другую вкладку так же, как выполняется doBackground-метод из моей AsyncTask, – этот фрагмент заменен, и поэтому я получаю NullPointerException в отмеченных строках:

 @Override protected Object doInBackground(Object... params) { ... String tempjson = helper.SendPost(getResources().getText(R.string.apiid)); //ERROR: Fragment not attached ... } protected onPostExecute(Object result) { ... getActivity().getContentResolver() //NULLPOINTEREXCEPTION getView().findViewById(R.id.button) //NULL ... } 

getActivity() и getResources() вызывает ошибку, потому что мой Фрагмент заменен.

Вещи, которые я пробовал:

  • Вызов метода отмены в моей AsyncTask (не будет исправлять первую ошибку или вторую ошибку, если фрагмент заменен, когда onPostExecute() )
  • Если getActivity() имеет значение null или вызывает this.isDetached() (не является реальным исправлением, и мне нужно будет его проверять всякий раз, когда я вызываю getActivity() и так далее)

Поэтому мой вопрос: что было бы лучше, чтобы избавиться от этих проблем AsyncTask? У меня не было этих проблем с помощью «Активных действий», поскольку они не были «убиты» / отключены при изменении вкладок (что привело к увеличению использования памяти – причина, по которой мне нравится переключаться на фрагменты)

Solutions Collecting From Web of "Фрагменты заменяются при выполнении AsyncTask – NullPointerException в getActivity ()"

Поскольку AsyncTask работает в фоновом режиме, ваш фрагмент может быть отделен от его родительской активности к моменту завершения. Как вы узнали, вы можете использовать isDetached() для проверки. В этом нет ничего плохого, и вам не нужно каждый раз проверять, просто рассмотрите фрагменты и жизненные циклы активности.

Две другие альтернативы:

  • Используйте Loaders, они предназначены для игры лучше с фрагментами
  • Переместите загрузку AsyncTask в родительскую активность и используйте интерфейсы для отделения от фрагментов. Активность будет знать, есть ли фрагмент или нет, и действовать соответствующим образом (возможно, отбрасывая результат, если фрагмент исчез).

Сегодня я столкнулся с одной и той же проблемой: когда я изменил отображаемый fragment , если AsyncTask еще не закончен, и он пытается получить доступ к view чтобы заполнить его еще несколькими элементами, он вернет NullPointerException .

Я решил проблему, переопределяющую один метод жизненного цикла фрагментов: onDetach() . Этот метод вызывается в момент, когда fragment отделяется от activity .

Что вам нужно сделать, так это вызвать метод cancel() в вашей AsyncTask . Это остановит выполнение задачи, чтобы избежать NullPointerExecption .

Вот пример onDetach() :

 @Override public void onDetach() { super.onDetach(); task.cancel(true); } 

Проверьте эту страницу, чтобы получить дополнительную информацию о жизненном цикле фрагментов: http://developer.android.com/reference/android/app/Fragment.html#Lifecycle. И это, чтобы больше узнать об отмене задачи: http://developer.android. ком / ссылки / Android / OS / AsyncTask.html

Попробуйте вызвать setRetainInstance(true); В функции onCreate() вашего класса фрагмента?