2017-05-11 32 views
0

我已經遷移到莫斯比3.0.3,現在正在調查PresenterManager的能力。 對於我來說,並沒有完全清楚主持人關於活動,片段和ViewGroup的一生。 我查看了ViewGroupMvpDelegateImpl,FragmentMvpDelegateImplActivityMvpDelegateImpl,並且無法100%確定演示者何時終止。莫斯比3主持人的生活 - MVP

至於我默認keepPresenterInstancekeepPresenterOnBackstack理解總是爲真,我們有這樣的情況:

  1. 片段的主持人存在,直到它的片段從堆棧中或整個過程被終止刪除。在這種情況下,我靠方法從FragmentMvpDelegateImpl

    protected boolean retainPresenterInstance() { 
    
        Activity activity = getActivity(); 
        if (activity.isChangingConfigurations()) { 
        return keepPresenterInstanceDuringScreenOrientationChanges; 
        } 
    
        if (activity.isFinishing()) { 
        return false; 
        } 
    
        if (keepPresenterOnBackstack && BackstackAccessor.isFragmentOnBackStack(fragment)) { 
        return true; 
        } 
    
        return !fragment.isRemoving(); 
    } 
    

但是,我們殘片childFragmentManagers或約從FragmentPagerAdapter(也在裏面另一個片段)片段?

  1. 活動和ViewGroup的演示者存在,直到他們的活動未完成或整個過程終止。在這種情況下,我靠方法從ActivityMvpDelegateImpl

    static boolean retainPresenterInstance(boolean keepPresenterInstance, Activity activity) 
    { 
        return keepPresenterInstance && (activity.isChangingConfigurations() 
         || !activity.isFinishing()); 
        } 
    

這是適用於所有ViewGroups,無論他們在哪裏居住?

問這個問題的原因是,在我們的應用程序中,我們有活動,片段,片段內的片段,自定義視圖組和所有人都有演示者。 這個想法是在detachView(final boolean retainInstance)的發佈者處釋放大量資源,但在內存中保留一些輕量級的內容(如inMemory緩存),以便在從後臺堆棧恢復視圖時重用該資源。

同樣,我們使用Dagger2,瞭解何時釋放適當的子組件非常重要。

回答

0
  • 活動:演示被破壞(由Presentation Manager的去除,因此可以被垃圾收集)當活動被結束(或活動過程死亡)。因此,活動會在屏幕方向更改期間保持演示者的身份,並且還會在後退堆棧上(如果您在後退堆棧中有多個活動)。工作得一樣莫斯比2.x的

  • 片段:在莫斯比2.x的演示只保持整個屏幕方向變化,如果你設置Fragment.setRetainInstanceState(true)。這在Mosby 3.x中不再需要,因爲Mosby 3.x使用PresenterManager來保持演示者不同方向的變化。此外,由於Mosby 3.x Presenter將保留,如果碎片在後面的堆棧上。這意味着,即使Fragment沒有View,因爲Fragment在後臺堆棧中,因此UI部件已被銷燬(已調用Fragment.onDestroyView()),Presenter實例將被保留,如果用戶彈出Fragment返回堆棧,你回來的主持人被重用。但是,當Fragment位於後端堆棧上時,View將與Presenter分離(presenter.detachView(true)將被調用),並在Fragment位於片段後端堆棧之上後重新連接。這是默認行爲,適用於任何種類的片段。 (子)背景堆棧上的ViewPager和嵌套的ChildFragments。您可以將其配置爲構造函數參數FragmentMvpDelegateImpl(keepPresenterInstance, keepPresenterOnBackstack),以便在屏幕方向更改期間根本不保留演示者,或者在後棧上片段時不保留演示者。

  • 查看組:在mosby 2.x中,他們根本沒有幸免於屏幕方向的改變。在Mosby 3.x中,他們使用PresenterManager。然而,你必須給每個ViewGroup一個id(@id/something)否則Android Framework不知道如何映射視圖(縱向視圖到橫向視圖)。正如您已經正確觀察到的那樣,ViewGroups會一直保留到「主機活動」消失或ViewGroup從編程的父代ViewGroup中移除,如parentViewGroup.removeChild(indexOfViewGroup)。無所謂,它駐留在哪裏。請注意,如果您將ViewGroup放在片段中,它可能會也可能不會運行良好。我還沒有想過/測試過這個邊緣案例。儘管如此,它會考慮「主機活動」(而不是Fragment作爲父級),但是,如果將碎片放到後端堆棧(並推入新的碎片),可能會出現碎片視圖包含你的ViewGroup將被刪除,這類似於以編程方式調用parentViewGroup.removeChild(indexOfViewGroup)(也許FragmentManager在內部調用它),這樣你的ViewGroup的演示者將被銷燬,但它可能不應該(因爲Fragment用戶可以彈出backstack以便片段)。在這種情況下,ViewGroup很可能會創建一個新的Presenter實例。正如已經說過的,我還沒有測試過,也沒有考慮過這個邊緣案例,但是由於Fragment不被ViewGroup知道,所以沒有辦法(據我所知)獲得對「主機片段」的引用。我建議在片段中使用Mosby片段或Mosby ViewGroups,但不要使用Mosby ViewGroup(如果真的需要,最好使用子片段)。

您可以通過在相應的委託構造函數中設置布爾標誌來配置所有這些行爲。

檢測是否按預期工作的最簡單方法是將日誌添加到createPresenter()方法和persenter.detachView()方法。另外Mosby提供了一些日誌用於調試。您可以在每個委託中啓用該功能,即FragmentMvpDelegateImpl.DEBUG = true(例如,在Application.onCreate()中調用此功能)。請注意,您必須爲每個代理(活動,片段,ViewGroup以及每個變體Mvp,Mvp + ViewState,Mvi)執行此操作。如果需要,也可以以相同方式啓用PresenterManager的日誌記錄。

+0

謝謝你這麼全面的答案。 在Mosby文檔中查看這些評論將很方便, –