#android #dependency-injection #dagger-2
#Android #внедрение зависимостей #dagger-2
Вопрос:
Согласно приведенному ниже коду:
@Module
public class AppModule {
private Application application;
public AppModule(Application application) {
this.application = application;
}
@Singleton
@Provides
Context providesContext() {
return application;
}
@Singleton
@Provides
IAppDbHelper providesAppDbHelper() {
// a SQLiteOpenHelper class
return new AppDbHelper(application);
}
}
AppComponent:
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(MainActivity mainActivity);
void inject(SecondActivity secondActivity);
IAppDBHelper providesIAppDBHelper();
}
MainActivity:
открытый класс MainActivity расширяет AppCompatActivity {
@Inject
Помощник IAppDBHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((MyApplication)getApplication()).getComponent()
.inject(this);
// It's OK
helper.getWritable().execSQL("XXX");
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
}
SecondActivity:
public class SecondActivity extends AppCompatActivity {
@Inject
IAppDBHelper helper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
// nullPointer on helper
helper.getWritable().execSQL("XXX");
}
}
После inject
того AppComponent
, как я исправил ошибку внутри SecondActivity
, nullPointer
исправлены ошибки, но мой вопрос inject
в том, нужно ли мне AppComponent
каждый раз, когда я хочу вводить IAppDbHelper
? Так что же @Singleton
означает и впрыскивание внутрь меня MainActivity
? Разве они не должны вводить это IAppDbHelper
для меня SecondActivity
?
Ответ №1:
Вам нужно будет получить свой компонент и внедрить каждый класс, который создает Android. Обычно это означает все действия, фрагменты и представления. Dagger не может создавать эти классы, поэтому единственный способ, которым Dagger узнает о внешне созданном экземпляре, — это когда вы передаете его в inject
метод вашего компонента.
Во время внедрения @Inject
будут предоставлены все поля MainActivity и SecondActivity, и любые экземпляры, созданные Dagger, также будут иметь свои зависимости, и так далее по всей линии. Это означает, что вам обычно не нужен ваш компонент непосредственно за пределами ваших созданных извне классов, таких как Activities и Fragments, или (конечно) вашего экземпляра приложения, где вы создаете сам экземпляр компонента.
@Singleton
означает, что экземпляр останется неизменным между MainActivity, SecondActivity и любыми будущими экземплярами MainActivity или SecondActivity, которые Android может создавать при фоновой работе приложения. Тем не менее, вам все равно нужно запросить внедрение для этих классов, поскольку Android их создает, чтобы получить тот же экземпляр, который вы гарантировали @Singleton
.
Комментарии:
1. Спасибо за ваш полный ответ, так должен ли я передавать
Context
аргумент для каждого логического класса, который долженIAppDbHelper
вводить его снова? Моя проблема заключается в использовании этихsingleton
зависимостей внутри классов без контекста.