2011-11-27 5 views
19

最近アクティビティをフラグメントに変換しました。AsyncTaskが実行されている間にフラグメントが置換されています - NullPointerException on getActivity()

Tab-Navigationと同様のものを使用して、ユーザーが別のタブを選択するとフラグメントが置き換えられます。 フラグメントが移入された後、少なくとも1つのAsyncTaskを起動して、インターネットから情報を取得します。しかし - ユーザーが別のタブに切り替えた場合、私のAsyncTaskからdoBackground-メソッドが実行されているだけのように - フラグメントがを交換しているので、私はマークされた行で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()を私のFragmentが置き換えられたためにエラーが発生します。私が試した

もの:

  • を私のAsyncTaskのメソッドをキャンセル呼び出す(onPostExecute()が実行されている間の断片を交換した場合、最初のエラーでも2番目のエラーが修正されません)
  • チェックする場合getActivity()nullまたはthis.isDetached()呼び出すことである(ない本当の修正をして、私はそうでgetActivity()を呼び出して、いつでも私はそれをチェックする必要があるだろう)

私の質問は次のとおりです。これらのAsyncTaskの問題を取り除くにはどうすればよいでしょうか?私はこれらの問題を、タブでの変更(タブでの変更で切り離されていない理由 - なぜフラグメントに切り替えるのか - 理由は私がフラグメントに切り替える理由)を使用していませんでした。

答えて

18

AsyncTaskはバックグラウンドで実行されていますあなたのフラグメントは、終了時までに親アクティビティーから切り離される可能性があります。あなたが知っているように、isDetached()を使って確認することができます。それには何も問題はなく、毎回チェックする必要はなく、フラグメントとアクティビティのライフサイクルを考慮するだけです。

他の二つの選択肢は:

  • 使用ローダー、それらは
  • が断片から分離するために親アクティビティと使用のインターフェイスにあなたのAsyncTaskのロードを移動した断片とよりよい再生するように設計されています。アクティビティは、フラグメントが存在するかどうかを知り、それに応じて動作します(フラグメントがなくなった場合に結果を廃棄する可能性があります)。
+8

isDetachedあなた自身が明示的にフラグメントを切り離した場合にのみ、()を呼び出します。そうでなければ、システムがあなたのアクティビティとあなたのフラグメントとの間のリンクを破壊したケースを処理するためにisAdded()を使うべきです。 – pcans

+0

@Nikolay Elenkovどのようにライフサイクルがgetactivityを呼び出す前に毎回チェックするのを避けることができますか? – Bear

-1

フラグメントクラスのonCreate()機能でsetRetainInstance(true);を呼び出してみましたか?私はAsyncTaskがまだ完了していない場合fragmentが表示されて変更されたとき、それはそれはNullPointerExceptionを返します、いくつかのより多くの要素を移入するviewにアクセスしようとします:

+1

これはこの場合は役に立ちませんが、問題は同じです。今のところ私はアクティビティとビューのフィールドを作成し、 'view = getView()'などを使って 'onActivityCreated()'に設定することで解決しました。 – Boni2k

4

今日、私は同じ問題に直面してきました。

フラグメントライフサイクルの1つの方法をオーバーライドする問題を解決しました。onDetach()。このメソッドはfragmentactivityから切り離される前に呼び出されます。

AsyncTaskcancel()メソッドを呼び出す必要があります。これは、NullPointerExecptionを避けてタスクの実行を停止します。

はここonDetach()のサンプルです:タスクをキャンセルについての詳細を表示する http://developer.android.com/reference/android/app/Fragment.html#Lifecycle そして、この:断片のライフサイクルに関する詳細情報を入手するために

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

チェックこのページをあなたが使用する必要があります http://developer.android.com/reference/android/os/AsyncTask.html

+0

ありがとう、どうもありがとうございました。これは1週間私を悩ませていた私の問題を解決しました! –