Android, используя контекст AppModule в целом, приложение использует dagger 2

#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 зависимостей внутри классов без контекста.