2013-02-26 64 views
5

我一直對此感到沮喪,我無法找到一個好的答案,所以希望有人能夠提供指導。片段,我什麼時候「活躍」?

我有一個片段,使用AsyncTask相當廣泛。我經常被那些片段叫做getActivity()的bug所困擾,它返回null。我認爲這些是因爲片段中的某些方法在附加活動之前或分離之後調用的。

什麼是在我的代碼中處理這個問題的正確方法?我不希望有這個成語散落得到處都是,

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

看文檔的Fragment,我可以想出許多可能鉤到解決這個問題:isDetached()onActivityCreated()onAttach()isResumed()和等等。什麼是正確的組合?

編輯:

有幾個人建議暫停時取消任務,但是這意味着標準的成語,

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實際上更簡單**是**,不像看起來那麼簡單)。 – 2013-02-26 22:09:33

+0

@ G.BlakeMeike感謝您的反饋。我們實際上在應用中有兩種模式:'IntentService'和'AsyncTask'。我更喜歡'AsyncTask'的調用語義。回覆:錯誤的架構 - 我不知道我是否同意。任何時候你需要一個上下文,你必須調用'getActivity()'。所以需要在onPostExecute()中獲得一個字符串,這意味着我有錯誤的弓? – 2013-02-26 22:32:34

+0

呃..是的,我猜這就是我所說的。與AsyncTask的整個交易是它有一個完全脫離活動的生命週期。在AT的任何特定時間,你都不能指望任何*活動環境。你有沒有考慮過將ApplicationContext傳遞給AT的構造函數? – 2013-02-26 22:36:06

回答

2

嘗試取消您的AsyncTasks在或onStop方法。當Fragment不再有效時(getActivity()返回null),這將防止onPostExecute被調用。

或者您可以通過在Fragment中調用​​3210來檢查是否附有Fragment

+0

謝謝。問題是我需要保持對我執行的每個'AsyncTask'的處理。例如,保存它們的堆棧,當'onPostExecute()'被調用或者當我取消它們時彈出它們。沒有'isAttached()'方法,只有'isDetached()',這隻有在片段被分離時纔是正確的,而不是當它尚未被連接時(見javadocs)。 – 2013-02-26 21:16:06

+0

發佈答案後,我實際上已將'isAttached'方法直接更改爲'isAdded';另請參見http://stackoverflow.com/questions/10919240/fragment-myfragment-not-attached-to-activity – nhaarman 2013-02-26 21:17:49

+0

另外,通常我會嘗試將每個Activity的'AsyncTask'數量保持在3以下,這樣做是可行的。 – nhaarman 2013-02-26 21:19:21

0

就協調生命週期而言,我保留onActivityCreated作爲心理基準 - 它標記了基本活動已完成自己的onCreate的點。在此之前,我不相信從getActivity()有活動。

獲取活動返回null聽起來像是你調用getActivity()太早(即創建之前)或太遲(即當它停止與片段交互時)。在onPause()中停止任務將阻止getActivity返回null,因爲一旦片段停止與基礎活動交互(因爲活動本身已暫停),它將切斷任務。我認爲等待onStop()可能太晚了,因爲如果任務在基礎活動暫停時仍然運行,它仍然可能會導致null。

1

回答我自己的問題...

我找不到一個好的解決方案。總之,要麼使用Loader,要麼檢查getActivity()在使用之前不返回null。我研究了使用Loader s,但該模式對應用程序的結構和數據檢索的性質做了很多假設,但對我無效。

相關問題