Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructing dependencies graph asynchronously in Dagger 2

This is a more theoretical question. Please let me know if I'm going in the wrong direction.

Is there any way to load some of graph dependencies asynchronously/in parallel in Dagger 2? Should it be even considered in a context of Dagger ?

My problem is mainly connected with app launch time. A lot of external dependencies like Mixpanel, Crashlytics/Fabric, Retrofit (RestAdapter) cause that the app is warming up longer than 1 second.

What helped me a lot is Lazy<> interface, but the final effect still doesn't satisfy me.

Any ideas?

Example

App has SplashActivity which depends on SplashActivityPresenter, which depends on: Mixpanel, RestAdapter and Crashlytics libraries (and a couple "smaller" objects). Each of them has .init() method which takes a lot of time (Mixpanel initialization takes about 200ms on Nexus 5, Android M. So in result it will take about 2 seconds before user sees Splash screen.

Is there any way to Construct those objects in parallel ?

like image 895
froger_mcs Avatar asked Sep 23 '15 11:09

froger_mcs


People also ask

What is @component in dagger?

Now Component in a Dagger works by creating a graph of all the dependencies in the project so that it can find out where it should get those dependencies when they are needed. In order to implement this, an interface needs to be created and should be annotated with @Component.

How does the custom scope work in dagger?

A scope is an annotations class with specific additional annotations: @Scope and @Retention. @Scope annotation is provided by Dagger library to define custom scopes. In our example, we create two scopes: @ActivityScope (for activities) and @FragmentScope (for fragments).

How do you inject a dagger in fragment?

onCreate() , an activity attaches fragments that might want to access activity bindings. When using fragments, inject Dagger in the fragment's onAttach() method. In this case, it can be done before or after calling super. onAttach() .


2 Answers

Keep the graph creation synchronous and defer object creation until subscribed to with Rx's defer. Downstream injections can be notified via a Subject, upon the object's creation.

@Module public static class AppModule{

    @Provides @Singleton
    public Observable<A> provideA(){
        return Observable.defer(
                () -> Observable.just(new A()) 
        );
    }
}

public class MainActivity extends AppCompatActivity{

    @Inject Observable<A> aObservable;
    A a;
    AppComponent appComponent;

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

        if(appComponent == null){ 
            appComponent = ((App) getApplication())
                .getAppComponent(); 
        }
        appComponent.inject(this);

        aObservable.subscribeOn(Schedulers.io())
                   .observeOn(AndroidSchedulers.mainThread())
                   .subscribe(new Action1<A>(){
                       @Override public void call(final A aa){
                           a = aa;
                           Log.d("MainActivity", "a = aa");
                       }
                   });
    }
}

Caveats: must manually check for object !null, or rely on the Subject acting as an eventbus, which would pass down the boolean status of the object that downstream injected objects must wait for.

like image 86
ersin-ertan Avatar answered Nov 15 '22 14:11

ersin-ertan


There's nothing special about Dagger 2's object graph creation. If you want it to be done in a background thread, just call DaggerYourComponent.create() or DaggerYourComponent.Builder.build() on a background thread (use your preferred method to do this - e.g. an AsyncTask).

If you have any @Inject constructors which assume they will be run on the UI thread, then you'll have to modify those, but otherwise you shouldn't have any issues.

like image 22
vaughandroid Avatar answered Nov 15 '22 15:11

vaughandroid