How to set up dependency injection using Dagger for other things then
Activities and Fragments?
I started setting up dependency injection using Dagger as follows. Please
feel encouraged to correct my implementation since I might have mistakes
in there! In the following you can see how I successfully added dependency
injection for Activities and Fragments. I try to keep it easy for now so I
decided to inject Timber as a logger substitution for Android's log util.
import android.app.Application;
import dagger.ObjectGraph;
import com.example.debugging.LoggingModule;
public class ExampleApplication extends Application {
private ObjectGraph mObjectGraph;
@Override public void onCreate() {
super.onCreate();
mObjectGraph = ObjectGraph.create(new LoggingModule());
}
public void inject(Object object) {
mObjectGraph.inject(object);
}
}
I prepared LoggingModule which provides access to Timber.
package com.example.debugging;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import com.example.BuildConfig;
import com.example.activities.BaseFragmentActivity;
import com.example.activities.DetailsActivity;
import com.example.fragments.BaseListFragment;
import com.example.fragments.ProfilesListFragment;
import timber.log.Timber;
@Module(injects = {
// Activities
BaseFragmentActivity.class,
DetailsActivity.class,
// Fragments
BaseListFragment.class,
ProfilesListFragment.class
})
public class LoggingModule {
@Provides @Singleton Timber provideTimber() {
return BuildConfig.DEBUG ? Timber.DEBUG : Timber.PROD;
}
}
The base class for Activities injects itself into the object graph ...
package com.example.activities;
import android.os.Bundle;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import javax.inject.Inject;
import com.example.ExampleApplication;
import timber.log.Timber;
public class BaseFragmentActivity extends SherlockFragmentActivity {
@Inject Timber mTimber;
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
super.onCreate(savedInstanceState);
((ExampleApplication) getApplication()).inject(this);
}
}
... and any sub class benefits from Timber being already present.
package com.example.activities;
import android.os.Bundle;
import com.example.R;
public class DetailsActivity extends BaseFragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
mTimber.i("onCreate");
// ...
}
}
Same for Fragments: the base class does the dirty job ...
package com.example.fragments;
import android.os.Bundle;
import com.actionbarsherlock.app.SherlockListFragment;
import javax.inject.Inject;
import com.example.ExampleApplication;
import timber.log.Timber;
public class BaseListFragment extends SherlockListFragment {
@Inject Timber mTimber;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((ExampleApplication) getActivity().getApplication()).inject(this);
}
}
... and the sub class benefits from its super class.
package com.example.fragments;
import android.os.Bundle;
public class ProfilesListFragment extends BaseListFragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setEmptyText("No data loaded");
mTimber.i("onActivityCreated");
// ...
}
}
So far so good. But how can inject Timber into BaseCursorAdapter,
BaseContentProvider, BaseSQLiteOpenHelper, BaseService, BaseAsyncTask and
static helper methods?
References:
Dagger
Jesse Wilson - Dagger: A Fast Dependency Injector for Android and Java
Eric Burke - Android App Anatomy
No comments:
Post a Comment