4

I have an app using Dagger2 The component is instantiated in the onCreate of the Application:

@Override
public void onCreate() {
    super.onCreate();
    mComponent =  DaggerApplicationComponent.builder()
            .applicationModule(new ApplicationModule(this))
            .build();
}

Dagger is managing a "CacheRepository" which is a class storing the data used by the user across the app.

The issue I have is: when the app is killed by the system, the Application is destroyed and the instance of the component is lost. But when I launch the app again, the app tries to restore its previous state which includes getting data from the Cache which has now been reinitialized. So the app crashes as the data are null.

How can I prevent that?

An easy option would be to force the app to restart from scratch when killed by the system but I haven't found any solution to do so.

Another solution is to store the cache in the SharedPreferences (or any kind of storage) but I don't like this solution as most of the data in the cache are temporary and it makes the app more complex.

Eselfar
  • 3,759
  • 3
  • 23
  • 43
  • 1
    `How can I prevent that?` You have to save the valuable information on disk (`SharedPreferences`, sqlite, as a plain file) or save that in a `Bundle`. – azizbekian Oct 27 '17 at 17:16
  • You can persist your data locally IE with Realm, sqllite etc. Another solution would be looking into Custom Scopes for your dagger CacheRepository. – willermo Oct 27 '17 at 18:01
  • @willermo Yes but this is what I'd like to avoid as the data in my component are supposed to only be used when the app is alive and I don't need them when I restart the app from the beginning. – Eselfar Oct 27 '17 at 18:32

2 Answers2

2

I think I've found the solution thanks to this answer from @David Wasser:

The idea is to force the app to restart from the beginning (a splashscreen for example) if the Application has been killed.

in onCreate() of all activities, check if the "app initialization" has been performed by using a public static variable or singleton. If the initialization has not been done, you know that your app's process was killed and recreated and you need to either redirect the user to your root Activity (ie: start the app all over again) or do the initialization immediately in the onCreate() of the Activity.

It's maybe not the best solution but at least it's very simple. And you don't risk to corrupt your data or to store something that you want to keep only during the application lifetime.

Eselfar
  • 3,759
  • 3
  • 23
  • 43
0

You can persist your data locally IE with Realm, sqllite etc. Another solution would be looking into Custom Scopes for your dagger CacheRepository.

In Dagger 2 scopes mechanism cares about keeping single instance of class as long as its scope exists. In practice it means that instances scoped in @ApplicationScope lives as long as Application object. @ActivityScope keeps references as long as Activity exists (for example we can share single instance of any class between all fragments hosted in this Activity).

Source: Dependency injection with Dagger 2 - Custom scopes

willermo
  • 503
  • 3
  • 13
  • Yes this is my issue. When the app is killed by the system (when in the background and for example memory is low) the Application instance is destroyed. As a result the component is released. So when the app is launched again, it tries to restore it's previous state. But because the Application had been destroyed, it's recreated and the component too. So all the data in the previous component are lost and the restored Activity get null data and the app crashes. – Eselfar Oct 27 '17 at 18:30
  • I guess your only option is to persist the data locally. – willermo Oct 27 '17 at 19:33