2017-09-27 22 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