2013-02-26 5 views
5

私はこれによって絶望的でした。私は良い答えを見つけることができません。フラグメント、いつ私は "アクティブ"ですか?

私はAsyncTaskを非常に広く使用する断片を持っています。私は、フラグメントがgetActivity()を呼び出し、nullを返すバグに常に悩まされています。私は、アクティビティがアタッチされる前、またはアタッチされた後に、フラグメント内のいくつかのメソッドが呼び出されるため、これらが起こっていると仮定します。

私のコードでこれを正しく処理する方法はありますか? 、isDetached()onActivityCreated()onAttach()isResumed()、と私はFragmentのためのドキュメントを見て

Activity activity = getActivity(); 
if (activity != null) { // do something } 

、このイディオムは、あらゆる場所に散らばっていたくない、私はこの問題を解決するために多くの可能なフックを思い付くことができませんそうです。適切な組み合わせは何ですか?

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(); 
} 
+0

答えは間違いですが...あなたのバグは建築的です。私はあなたがAsyncTasksを使って何をしているのか正確にはわかりませんが、getActivityが実行中にnullを返した場合、AsyncTaskを使用しないでください。タスクで何をしていても、サービスで実行する必要があります。状態の発見を知る必要のあるアクティビティ/フラグメントは、サービスに取得を依頼することができます。 IntentServiceをチェックしてください:AsyncTaskよりも使いやすく、シンプルです(実際はAsyncTaskよりも簡単です**実際は**は**よりも単純ではありません)。 –

+0

@ G.BlakeMeikeはフィードバックに感謝します。私たちは実際には 'IntentService'と' AsyncTask'の両方のパターンをアプリに持っています。私は 'AsyncTask'の呼び出しセマンティクスを大いに好んでいます。再:間違ったアーキテクチャ - 私は同意するか分からない。コンテキストが必要なときはいつでも 'getActivity()'を呼び出さなければなりません。 onPostExecute()内の文字列を取得する必要があるので、私は間違ったアーチを持っていますか? –

+0

まあ、ええ、私はそれがかなり私が言っていると思う。 AsyncTaskの全面的な取り組みは、アクティビティから完全に切り離されたライフサイクルを持つことです。あなたはATの生活の中でいつでも、*どんな*アクティビティ・コンテキストも周りにいるとは信じられません。あなたはATのコンストラクタにApplicationContextを渡すことを考えましたか? –

答えて

2

がまたはonStop方法であなたのAsyncTasksをキャンセルするようにしてください。これにより、FragmentがもうアクティブでないときにonPostExecuteが呼び出されるのを防ぐことができます(getActivity()nullを返します)。

Fragmentに​​3210と電話すると、Fragmentが付いているかどうかを確認できます。

+0

問題は私が実行するすべての 'AsyncTask'にハンドルを保持する必要があることです。 'onPostExecute()'が呼び出されたとき、またはそれらをキャンセルするときにスタックをポップするなど)。 'isDetached()'だけのisAttached()メソッドはありません。フラグメントがまだデタッチされていない場合にのみtrueで、まだアタッチされていない場合にはtrueになりません(javadocsを参照)。 –

+0

私は実際に 'isAttached'メソッドを' isAdded'に変更しました;)http://stackoverflow.com/questions/10919240/fragment-myfragment-not-attached-to-activity – nhaarman

+0

また、私は通常、 'Activity' /' Fragment'を 'AsyncTask'の数で3以下に抑えようとしています。 – nhaarman

0

調整ライフサイクルの点では、onActivityCreatedをメンタルベンチマークとして保持しています。これは、基礎となるアクティビティが自身の完了したポイントであるonCreateを示しています。その前に私はgetActivity()からの活動があるとは思わない。

getActivity()を早く(つまり作成する前に)呼び出すか、遅すぎる(つまり、フラグメントとのやり取りを停止した)のように、アクティビティを取得するとnullのサウンドが返されます。 onPause()でタスクを停止すると、アクティビティ自体が一時停止しているため、フラグメントが基本アクティビティとのやりとりをやめた後にタスクを切断するので、getActivityがnullを返すことはありません。私はonStop()の待機が遅れている可能性があると考えています。もし基本的な活動が一時停止したときにタスクがまだ実行されていれば、それはまだreutrn nullかもしれません。

1

私自身の質問に答える...

私は良い解決策を見つけることができませんでした。要約すると、Loaderを使用するか、またはgetActivity()がヌルを返さないことを確認してから使用してください。私はLoaderを使って調べましたが、パターンはアプリの構造と私にとってはうまくいかなかったデータ検索の性質について多くの仮定をしています。

関連する問題