2015-04-20 47 views
5

我有一個使用碎片的MainActivity。Android中的碎片和線程

MainActivity的OnCreate完成它的onCreate與使用

welcomeFragment = new MyWelcomeFragment(); 
fr.beginTransaction().replace(R.id.mainContent, welcomeFragment).commit() 

由於MyWelcomeFragment對的onResume的一部分,一個線程開始,從我的網絡服務器獲取更新。如果用戶在線程完成並轉到MyNewsFragment之前選擇一個動作,那麼尚未完成在MyWelcomeFragment的線程堆棧中運行的線程會發生什麼情況?

主題與創建:(MyThread的程序和處理程序是實例變量)

myThread = new Thread(new Runnable() { 
       @Override 
       public void run() { 
        sendDataToServer(""); 
        handler = new Handler(Looper.getMainLooper()); 
        handler.post(new Runnable() { 
         public void run() { 
          onTaskDone(); 
         } 
        }); 
       } 
      }); 
      myThread.start(); 
+0

什麼是*線程棧*? – dcow

+1

這個'onTaskDone'可能會有問題,如果它試圖更新視圖部分和'活動'已經完成。你爲什麼不使用標準的'AsyncTask' API? –

+0

線程將繼續運行,直到它完成任務 – apk

回答

2

Dalvik將所有線程引用保留在運行時中,以便線程將繼續運行,除非它被終止或完成(某些reference)。因此,根據您開始線索的位置,您可能會創建多個線索。有no clean way取消線程,在這種情況下,您可能需要先取消sendDataToServer內的http請求,並使用共享標誌停止線程。

在一個更大的圖片,我建議

  • 移動聯網的方法來活動,並處理它那裏,因爲它更長的壽命比 片段
  • 採用Android抽射處理網絡。有了它,您可以管理無意的多個請求,將數據發送到您的服務器。由於每個請求都可以附加標籤,因此您可以取消任何帶有隊列中的特定標籤(在您的情況下,對應於sendDataToServer進程的標籤),然後再啓動一個新標籤。
  • 並最終使用已經由例如OttoEventBus的庫提供的發佈者 - 訂閱者模式。這允許片段或活動之間的通信,同時避免與生命週期相關的問題。要點:發佈者將事件發送給註冊的訂閱者,而與聽衆不同的是發佈者和訂閱者都完全分離。在你的情況下,當sendDataToServer完成時,你不知道包含onTaskDone的片段是否還在。如果這個方法操縱用戶界面,而碎片已經摧毀了它的視圖,那麼你肯定會得到一個錯誤。所以onTaskDone應該被包裝在一個訂閱者方法中,其父代片段被註冊到http事件發佈者,並在其視圖銷燬後立即註銷。
0

線程將繼續運行,直到MyWelcomeFragment是活的,如果你沒有在onPause()殺死它。

+0

這是不正確的。如果沒有被殺死並且仍然活着,即使在碎片或活動被破壞之後,線程仍將繼續運行。 – inmyth

1

它會一直運行,直到run()方法完成,這可能需要多長時間才能完成,因爲處理程序應該比網絡IO快得多 - 或者線程是力量中斷。

如果用戶切換片段,您還對結果感興趣嗎?

你是否保留對歡迎片段的引用? (通過片段管理器或活動) - 如果是這樣,您仍然可以訪問結果。

如果用戶返回歡迎片段,則以前的線程引用將會丟失。

+0

任務完成後,結果將寫入共享的pref並更新計數。這隻需要在片段被激活時發生,這就是爲什麼它不在主要活動中。 – justdan0227