Android
Кинжал 2
Поиск…
Синтаксис
- @Module
- @Component (dependencies = {OtherComponent.class}, modules = {ModuleA.class, ModuleB.class})
- DaggerMyComponent.create ()
- DaggerMyComponent.builder (). MyModule (newMyModule ()). Создать ()
замечания
Не путать с кинжалом по квадрату, предшественником кинжалом 2.
Настройка компонентов для инъекций приложений и активности
Базовый AppComponent
который зависит от одного AppModule
для предоставления общесистемных одноэлементных объектов.
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App app);
Context provideContext();
Gson provideGson();
}
Модуль для использования вместе с AppComponent
который будет предоставлять свои одноэлементные объекты, например, экземпляр Gson
для повторного использования во всем приложении.
@Module
public class AppModule {
private final Application mApplication;
public AppModule(Application application) {
mApplication = application;
}
@Singleton
@Provides
Gson provideGson() {
return new Gson();
}
@Singleton
@Provides
Context provideContext() {
return mApplication;
}
}
Подклассовое приложение для настройки кинжала и синглтон-компонента.
public class App extends Application {
@Inject
AppComponent mAppComponent;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent.builder().appModule(new AppModule(this)).build().inject(this);
}
public AppComponent getAppComponent() {
return mAppComponent;
}
}
Теперь компонент, зависящий от действия, который зависит от AppComponent
чтобы получить доступ к объектам singleton.
@ActivityScope
@Component(dependencies = AppComponent.class, modules = ActivityModule.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
И многократно используемый ActivityModule
который будет обеспечивать основные зависимости, такие как FragmentManager
@Module
public class ActivityModule {
private final AppCompatActivity mActivity;
public ActivityModule(AppCompatActivity activity) {
mActivity = activity;
}
@ActivityScope
public AppCompatActivity provideActivity() {
return mActivity;
}
@ActivityScope
public FragmentManager provideFragmentManager(AppCompatActivity activity) {
return activity.getSupportFragmentManager();
}
}
Собирая все вместе, мы настроены и можем внедрить нашу деятельность и обязательно использовать то же самое Gson
всех приложений!
public class MainActivity extends AppCompatActivity {
@Inject
Gson mGson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainActivityComponent.builder()
.appComponent(((App)getApplication()).getAppComponent())
.activityModule(new ActivityModule(this))
.build().inject(this);
}
}
Пользовательские области
@Scope
@Documented
@Retention(RUNTIME)
public @interface ActivityScope {
}
Области - это просто аннотации, и вы можете создавать свои собственные, где это необходимо.
Инъекция конструктора
Занятия без зависимостей могут быть легко созданы кинжалом.
public class Engine {
@Inject // <-- Annotate your constructor.
public Engine() {
}
}
Этот класс может быть предоставлен любым компонентом. Он не имеет никаких зависимостей и не имеет ограничений . Дополнительного кода не требуется.
Зависимости объявляются как параметры в конструкторе. Кинжал вызовет конструктор и предоставит зависимости, если эти зависимости могут быть предоставлены.
public class Car {
private Engine engine;
@Inject
public Car(Engine engine) {
this.engine = engine;
}
}
Этот класс может быть предоставлен каждым компонентом, если этот компонент может также обеспечить все его зависимости - Engine
в этом случае. Так как Engine
также может быть инжектирован конструктором, любой компонент может обеспечить Car
.
Вы можете использовать инъекцию конструктора, когда все зависимости могут быть предоставлены компонентом. Компонент может обеспечить зависимость, если
- он может создать его, используя инъекцию конструктора
- модуль компонента может обеспечить его
- он может быть предоставлен родительским компонентом (если он является
@Subcomponent
) - он может использовать объект, подвергаемый компоненту, зависящему от (зависимостей компонентов)
Использование @Subcomponent вместо @Component (dependencies = {...})
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App app);
Context provideContext();
Gson provideGson();
MainActivityComponent mainActivityComponent(ActivityModule activityModule);
}
@ActivityScope
@Subcomponent(modules = ActivityModule.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
public class MainActivity extends AppCompatActivity {
@Inject
Gson mGson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((App)getApplication()).getAppComponent()
.mainActivityComponent(new ActivityModule(this)).inject(this);
}
}
Как добавить кинжал 2 в build.gradle
Начиная с выпуска Gradle 2.2, использование плагина android-apt больше не используется. Должен использоваться следующий способ настройки кинжала 2. Для более старой версии Gradle используйте предыдущий метод, показанный ниже.
Для Gradle> = 2.2
dependencies {
// apt command comes from the android-apt plugin
annotationProcessor 'com.google.dagger:dagger-compiler:2.8'
compile 'com.google.dagger:dagger:2.8'
provided 'javax.annotation:jsr250-api:1.0'
}
Для Gradle <2.2
Чтобы использовать Dagger 2, необходимо добавить плагин android-apt
, добавьте его в root build.gradle:
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
Затем build.gradle модуля приложения должен содержать:
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
…
}
final DAGGER_VERSION = '2.0.2'
dependencies {
…
compile "com.google.dagger:dagger:${DAGGER_VERSION}"
apt "com.google.dagger:dagger-compiler:${DAGGER_VERSION}"
}
Ссылка: https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2
Создание компонента из нескольких модулей
Dagger 2 поддерживает создание компонента из нескольких модулей. Вы можете создать свой компонент таким образом:
@Singleton
@Component(modules = {GeneralPurposeModule.class, SpecificModule.class})
public interface MyMultipleModuleComponent {
void inject(MyFragment myFragment);
void inject(MyService myService);
void inject(MyController myController);
void inject(MyActivity myActivity);
}
Затем два модуля ссылок GeneralPurposeModule
и SpecificModule
могут быть реализованы следующим образом:
GeneralPurposeModule.java
@Module
public class GeneralPurposeModule {
@Provides
@Singleton
public Retrofit getRetrofit(PropertiesReader propertiesReader, RetrofitHeaderInterceptor headerInterceptor){
// Logic here...
return retrofit;
}
@Provides
@Singleton
public PropertiesReader getPropertiesReader(){
return new PropertiesReader();
}
@Provides
@Singleton
public RetrofitHeaderInterceptor getRetrofitHeaderInterceptor(){
return new RetrofitHeaderInterceptor();
}
}
SpecificModule.java
@Singleton
@Module
public class SpecificModule {
@Provides @Singleton
public RetrofitController getRetrofitController(Retrofit retrofit){
RetrofitController retrofitController = new RetrofitController();
retrofitController.setRetrofit(retrofit);
return retrofitController;
}
@Provides @Singleton
public MyService getMyService(RetrofitController retrofitController){
MyService myService = new MyService();
myService.setRetrofitController(retrofitController);
return myService;
}
}
Во время фазы ввода зависимостей компонент будет брать объекты из обоих модулей в соответствии с потребностями.
Этот подход очень полезен с точки зрения модульности . В этом примере используется модуль общего назначения, используемый для создания таких компонентов, как объект Retrofit
(используемый для обработки сетевой связи) и PropertiesReader
(отвечающий за обработку файлов конфигурации). Существует также специальный модуль, который обрабатывает создание конкретных контроллеров и классов обслуживания в отношении этого конкретного компонента приложения.