2017-09-27 32 views
1

我最近在Dagger 2上看過a talk by Gregory Kick。他在那裏解釋了關於靜態提供者方法,這可能有助於提高性能。所以我將我項目中的所有提供者方法修改爲static。但我在這裏有一個疑問。在我的項目中,有一些提供程序返回活動實例(外部依賴項)。所以我寫了module 與一個構造函數,從外部採取Activity匕首2:是否推薦使用靜態提供程序來處理活動和碎片?

@Module 
public class ActivityModule { 
    private static BaseActivity mActivity; 

    public ActivityModule(BaseActivity activity) { 
    mActivity = activity; 
    } 

    @ActivityScope 
    @Provides 
    Activity mActivity() { 
    return mActivity; 
    } 

    @ActivityScope 
    @Provides 
    BaseActivity baseActivity() { 
    return mActivity; 
    } 
} 

所以,如果非要讓供應商靜態它會看起來像如下

@Module 
public class ActivityModule { 
    private static BaseActivity mActivity; 

    public ActivityModule(BaseActivity activity) { 
    mActivity = activity; 
    } 

    @ActivityScoped 
    @Provides 
    static Activity mActivity() { 
    return mActivity; 
    } 

    @ActivityScoped 
    @Provides 
    static BaseActivity baseActivity() { 
    return mActivity; 
    } 
} 

所以,在這裏我保持活動實例在static成員。它會導致任何內存泄漏?或者匕首在活動被破壞時通過移除靜態引用自動管理它? 在這種情況下,建議保持靜態提供程序?

+1

Yup內存泄漏嘉豪 – EpicPandaForce

+0

@EpicPandaForce所以,只有在這種情況下,我應該避免靜態提供程序? – Jrd

+0

那麼除非你在'onDestroy()'中將該字段重置爲null,yeah – EpicPandaForce

回答

3

是否推薦使用靜態提供程序來處理Activities和fragments?

號所有你要做的是創建錯誤和內存泄漏源。根據經驗,不要將任何Android Framework類型放入靜態變量中。他們引用context,你會泄漏內存。

如前所述,靜態方法可能會提高性能,當然你可以使用它。你顯示的代碼的問題是返回一個靜態變量—的靜態方法,這種方法也會失敗調用模塊構造函數的目的。

如果您有一個只包含靜態方法的模塊,那麼您可能會獲得一些額外的性能並消除模塊實例分配的需要,正如他們在鏈接講話中提到的那樣。

靜態方法本身是可以的,但它們不應該與應用程序的其他部分交互,如讀取或寫入靜態變量。如果您有其他對象的依賴關係,請始終將它們作爲參數添加到您的provide-method中。這樣Dagger可以正確使用這些方法,並且可能會獲得一些性能。

從靜態提供程序返回新的片段實例怎麼樣?

@Provides @ActivityScoped static MyFragment provideFragment() { 
    return MyFragment.createInstance(); 
} 

我相信這實際上可能是好的。這是一個返回片段的新實例的靜態方法,不應包含任何副作用。

但請確保您重新創建您的@ActivityScoped組件,只要重新創建活動並且片段確保而不是保留其狀態。你真的想要避免FragmentManager管理組件中的碎片,或者更糟糕的是,兩者都是。

+2

徹底和正確的AFAIK,只要你對你的「@ ActivityScoped」片段的引用感到滿意,就像你的Activity一樣。如果你有一個長壽命的活動和一個沉重的片段,你可能不希望你的片段是'@ ActivityScoped',這樣GC就可以在你的片段不再顯示時收集你的片段。 –

+0

不錯的答案+1,但我通常只是告訴人們不要提供片段,因爲如果他們使用FragmentManager –

+0

那麼會出現錯誤的風險很高所以基本上,我可以使用靜態提供程序來處理我的應用程序範圍組件的所有提供者,Activity,Fragment,Context或這樣的框架組件除外?使用靜態提供程序用於應用程序範圍的組件,如Retrofit,Gson,Util類將是安全正確的? – Jrd