-1

I have a class that's being injected using DI via dagger. However when the activity is destroyed and recreated, the model class seems to contain the data automatically without me insert/repopulating the data.

public class MyApplication extends Application {

    private ExpressionFactoryComponent mExpressionFactoryComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        // Building dagger DI component
        mExpressionFactoryComponent = DaggerExpressionFactoryComponent.builder().
                expressionFactoryModule(new ExpressionFactoryModule(new ExpressionFactory(this))).build();
    }
}

Module:

@Module
public class ExpressionFactoryModule {
    private ExpressionFactory mExpressionFactory;

    public ExpressionFactoryModule(ExpressionFactory expressionFactory) {
        this.mExpressionFactory = expressionFactory;
    }

    @Provides
    ExpressionFactory provideStringExpressionFactory() {
        return mExpressionFactory;
    }
}
user2498079
  • 2,872
  • 8
  • 32
  • 60
  • Post your module. Most likely you gave it a scope. Scoped variables exist for the lifetime of the component they're used to create, and subsequent requests return the same variable. – Gabe Sechan Mar 28 '17 at 19:22
  • I haven't given any scope to the variable. I'm currently learning dagger 2 – user2498079 Mar 28 '17 at 19:30
  • @GabeSechan I have posted the Module code in the question – user2498079 Mar 28 '17 at 19:31
  • Are you sure this is not simply a case of the Activity/Fragment saving the instance state of the views? – David Rawson Mar 28 '17 at 20:29
  • Nope. I haven't made this ExpressionFactory class parcellable or persisted it on disk. When I removed Dagger2 DI, the ExpressionFactory member variables remained empty after activity's recreation. I reenabled Dagger and yep it started persisting the Expression Factory class – user2498079 Mar 28 '17 at 20:50

1 Answers1

1

The one reason for this is that ExpressionFactory is instantiated in MyApplication class and then passed into the constructor of ExpressionFactoryModule while creating ExpressionFactoryComponent. You should pass an Application instance in your module constructor and then create an instance of your class withing a metod with @Provide annotation passing that Application instance in your class's constructor.

This how things should be done with dagger. But to solve your problem you need to create another component class and build the component in an activity if you need to have an instance of your class living withing an activity only.

Here is the solution (ExpressionFactoryComponent is renamed to AppComponent here):

public class MyApplication extends Application {

    private static AppComponent appComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        // Building dagger DI component
        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this)).build();
    }

    public static AppComponent getAppComponent() {
        return appComponent;
    }
}


@Component(modules = {AppModule.class})
public interface AppComponent {

    Application getApplication();

    void inject(App application);
}


@Module
public class AppModule {

    private Application application;

    public AppModule(Application application) {
        this.application = application;
    }


    @Provides
    Application provideApplication() {
        return application;
    }
}


@Component(dependencies = AppComponent.class, modules = {
        ActivityModule.class})
public interface ActivityComponent {

    void inject(MainActivity activity);

}

@Module
public class ActivityModule {

    private Activity activity;

    public ActivityModule(Activity activity) {
        this.activity = activity;
    }

    @Provides
    Activity provideActivity() {
        return activity;
    }


    @Provides
    ExpressionFactory provideStringExpressionFactory(Application application) {
        return new ExpressionFactory(application);
    }

}

public class MainActivity extends AppCompatActivity{


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ActivityComponent activityComponent = DaggerActivityComponent.builder()
                    .activityModule(new ActivityModule(activity))
                    .appComponent(App.getAppComponent())
                    .build();

        activityComponent.inject(this); 

    }

}
dzikovskyy
  • 5,027
  • 3
  • 32
  • 43