我开始使用Dagger设置依赖注入,如下所示。请感到鼓舞来纠正我的实施,因为我可能在那里有错误!实现遵循项目提供的android-simple 示例。在下文中,您可以看到我如何成功地为Activities
和Fragments
. 我现在尽量保持简单,所以我决定注入Timber作为Android 的 log util的记录器替代品。
import android.app.Application;
import java.util.Arrays;
import java.util.List;
import dagger.ObjectGraph;
import com.example.debugging.LoggingModule;
public class ExampleApplication extends Application {
private ObjectGraph mObjectGraph;
protected List<Object> getModules() {
return Arrays.asList(
new AndroidModule(this),
new ExampleModule(),
new LoggingModule()
);
}
private void createObjectGraphIfNeeded() {
if (mObjectGraph == null) {
Object[] modules = getModules().toArray();
mObjectGraph = ObjectGraph.create(modules);
}
}
public void inject(Object object) {
createObjectGraphIfNeeded();
mObjectGraph.inject(object);
}
}
到目前为止,AndroidModule
它没有在任何地方使用,但在需要 aContext
和时可能会有所帮助,LayoutInflater
例如在CursorAdapters
.
import android.content.Context;
import android.view.LayoutInflater;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
/**
* A module for Android-specific dependencies which require a {@link Context}
* or {@link android.app.Application} to create.
*/
@Module(library = true)
public class AndroidModule {
private final ExampleApplication mApplication;
public AndroidModule(ExampleApplication application) {
mApplication = application;
}
/**
* Allow the application context to be injected but require that it be
* annotated with {@link ForApplication @Annotation} to explicitly
* differentiate it from an activity context.
*/
@Provides @Singleton @ForApplication Context provideApplicationContext() {
return mApplication;
}
@Provides @Singleton LayoutInflater provideLayoutInflater() {
return (LayoutInflater) mApplication
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
}
我不确定哪些特定于应用程序的提供程序会出现在这里。我现在继续记录。
import dagger.Module;
@Module(
complete = false
)
public class ExampleModule {
public ExampleModule() {
// TODO put your application-specific providers here!
}
}
我准备LoggingModule
了提供对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;
}
}
基类Activities
将自身注入到对象图中...
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 abstract class BaseFragmentActivity extends SherlockFragmentActivity {
@Inject Timber mTimber;
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
super.onCreate(savedInstanceState);
((ExampleApplication) getApplication()).inject(this);
}
}
......以及木材已经存在的任何子类的好处。
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");
// ...
}
}
相同的Fragments
:基类做了肮脏的工作......
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 abstract class BaseListFragment extends SherlockListFragment {
@Inject Timber mTimber;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((ExampleApplication) getActivity().getApplication()).inject(this);
}
}
...并且子类受益于其超类。
package com.example.fragments;
import android.os.Bundle;
public class ProfilesListFragment extends BaseListFragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// TODO This might be a good example to inject resources
// in the base class. But how?
setEmptyText(getResources()
.getString(R.string.profiles_list_no_content));
mTimber.i("onActivityCreated");
// ...
}
}
到目前为止,一切都很好。但是如何将Timber注入到, , , 和BaseCursorAdapter
helperBaseContentProvider
方法BaseSQLiteOpenHelper
中BaseService
呢?BaseAsyncTask
static
Christopher Perry不推荐使用的android 示例指出了如何将Adapter注入ListFragment,但没有指出如何将Context
, Resources
, LayoutInflater
,Cursor
注入(Cursor)Adapter
或只是Timber。
参考: