为了学习Dagger 2,我决定重写我的应用程序,但我仍然坚持为以下问题找到合适的解决方案.
出于这个例子的目的,让我们假设我们有一个名为Mode的接口:
public interface Mode { Object1 obj1(); //some other methods providing objects for app }
和两个实现:
NormalMode和DemoMode.
模式以单例存储,因此可以从应用程序内的任何位置访问.
public enum ModeManager { INSTANCE,; private Mode mode; public Mode mode() { if (mode == null) mode = new NormalMode(); return mode; } public void mode(Mode mode) { //to switch modules at runtime this.mode = mode; } }
NormalMode在运行时切换到DemoMode(假设,当用户在背景上点击几次时)
public void backgroundClicked5Times(){ ModeManager.INSTANCE.mode(new DemoMode()); //from now on every object that uses Mode will get Demo implementations,great! }
首先,我摆脱了单例并将模式定义为Dagger 2模块:
@Module public class NormalModeModule { @Provides public Object1 provideObject1() { return new NormalObject1(); } } @Module public class DemoModeModule { @Provides public Object1 provideObject1() { return new DemoObject1(); } }
现在在方法backgroundClicked5Times中,而不是处理单例,我想用DAG中的DemoModeModule替换NormalModeModule,所以其他需要Object1的类从现在开始将获得DemoObject1实现.
我怎么能在Dagger那样做?
提前致谢.
经过一段时间的匕首试验,我想出了一个似乎在我的用例中运行良好的解决方案.
原文链接:https://www.f2er.com/javaschema/281660.html>定义将保存有关模式的状态信息的类
public class Conf { public Mode mode; public Conf(Mode mode) { this.mode = mode; } public enum Mode { NORMAL,DEMO } }
>在模块中提供Conf的单例实例
@Module public class ConfModule { @Provides @Singleton Conf provideConf() { return new Conf(Conf.Mode.NORMAL); } }
>将模块添加到AppComponent
@Singleton @Component(modules = {AppModule.class,ConfModule.class}) public interface AppComponent { //... }
>定义基于模式提供不同对象的模块
@Module public class Object1Module { @Provides Object1 provideObject1(Conf conf) { if (conf.mode == Conf.Mode.NORMAL) return new NormalObject1(); else return new DemoObject1(); } }
>要在运行时切换模式,只需注入Conf对象并进行修改:
public class MyActivity extends Activity { @Inject Conf conf; //... public void backgroundClicked5Times(){ conf.mode = Conf.Mode.DEMO; //if you have dagger objects in this class that depend on Mode //execute inject() once more to refresh them } }