2016-08-04 113 views
2

我有一個Fragment,做與互聯網低谷一些輔助Class,需要一個接口來處理異步回調一些像這樣的通信:片段異步接口回調處理

SomeInternetCommunicator.getResource(theResourceToGet, retrieverInterfaceInstance); 

界面看起來是這樣的:

public interface SomeInternetCommunicator { 
    void onResourceRetrieveSuccess(SomeResource resource); 
    void onResourceRetrieveFailed(CommunicatorException e); 
} 

問題是,有時候通話時間過長,用戶已經在其他地方導航,撥打getResourceFragment不是當前通話的一部分y再次運行Activity(不顯示,不在背後)。這會導致很多問題,因爲這個孤兒Fragment仍然試圖對回調作出反應,即使它不再是Activity的一部分。例如,getContext()返回null。

現在我在Fragment解決方法是這樣的:

SomeInternetCommunicator flocktrackerTrackerRetrieverInterface = new SomeInternetCommunicator() { 
      @Override 
      public void onResourceRetrieveSuccess(SomeResource resource) { 
       if(isVisible()){ 
        doRetrievalPostProcessing(resource); 
       } 
      } 

      @Override 
      void onResourceRetrieveFailed(CommunicatorException e) { 
       if(isVisible()){ 
        doExceptionHandling(); 
       } 
      } 
     }; 

使用isVisible()作品,因爲這將確保該片段是仍然在前臺,Activity的一部分,並準備做處理。然而,這並不能幫助我解決Fragment不可見的情況,但仍然是當前的Activity的一部分,這限制了我在顯示Fragment之前加載Fragment的可能性。 (Activity在後臺,Fragment位於BackstackFragment位,由ViewPager加載)。

在我進行後處理之前,有沒有更好的方法來確保Fragment仍然在當前的Activity的範圍之內?也許檢查isAdded()

This question似乎解釋了一個更廣泛但相關的情況,但它沒有答案。

謝謝!

+1

是isAdded()是正確的。如果您想在添加和刪除時執行更多操作,請覆蓋onAttach()和onDetach()。 – anhtuannd

回答

1

這裏有兩種常用的方法來這種情況下:

  1. 最好的辦法是有辦法從SomeInternetCommunicator清除接口實例。例如:

@Override public void onDestroyView(){ 
    SomeInternetCommunicator.removeMe(this); 
} 
  • 如果選項(1)是不可能的,因爲SomeInternetCommunicator是一個編碼不庫,則強制選項1通過使單獨的類來實現的接口成爲可能。
  • public class SomeInternetCommunicatorInterceptor implements SomeInternetCommunicatorInterface { 
    
        private SomeInternetCommunicatorInterface listener; 
    
        public void setListener(SomeInternetCommunicatorInterface listener){ 
         this.listener=listener; 
        } 
    
        @Override 
        public void onResourceRetrieveSuccess(SomeResource resource){ 
         if(listener != null){ 
           listener.onResourceRetrieveSuccess(resource); 
         } 
        } 
        @Override 
        public void onResourceRetrieveFailed(CommunicatorException e){ 
         if(listener != null){ 
           listener.onResourceRetrieveFailed(e); 
         } 
        } 
    } 
    

    然後在你的片段,你使用這個新的類爲:

    private SomeInternetCommunicatorInterceptor interceptor; 
    
    public void onCreateView(....){ 
    
    ... your code 
    
        interceptor = new SomeInternetCommunicatorInterceptor(); 
    
    } 
    
    onStart(){ 
        interceptor.setListener(this); 
    } 
    
    onStop(){ 
        interceptor.setListener(null); 
    } 
    
    public void onDestroyView(){ 
        interceptor = null; 
        super.onDestroyView(); 
    } 
    

    非常重要:

    如果你讓SomeInternetCommunicatorInterceptor一個內部類的片段,你必須讓它作爲static class

    +0

    謝謝!SomeInternetCommunicator確實是一個編碼不好的庫,但它是由我自己編寫的,所以我可以進行您所建議的更改。 – buzoherbert