Подтвердить что ты не робот

Как использовать кинжал в проекте библиотеки Android

В настоящее время я пытаюсь добавить Кинжал в мои проекты Android. Для проектов приложений это легко и понятно для меня, как построить ObjectGraph. Но я не совсем понимаю, что лучший способ сделать это в моих проектах библиотеки Android.

Должен ли я продолжать создавать ObjectGraph в классе приложений приложений и передавать OG в LibraryModule - plinging OG библиотеки в OG Apps? Или я должен построить весь ObjectGraph в библиотеке?

Что делать, если мне нужно ввести класс в библиотеку ObjectGraph.inject(this)? В моих проектах приложений я могу получить OG из класса Application. Но как справиться с этим в библиотеке? Должен ли я добавить метод @Provides для объекта ObjectGraph?

Большое спасибо за помощь.

Изменить: Вкратце: Как я могу вызвать ObjectGraph.inject(this) в моем проекте библиотеки, где у меня нет доступа к OG, потому что он строится в классе приложений?

4b9b3361

Ответ 1

В случае, если кто-то использует Dagger 2, вот что я сделал в своем приложении:

В библиотечном модуле я создал следующий модуль и компонент:

@Module
public class ModuleUtil {

    @Provides
    public RestTemplate provideRestTemplate() {
        return new RestTemplate();
    }

}

@Singleton
@Component(
        modules = {
                ModuleUtil.class
        })
public interface MainComponent {
    void inject(Postman postman);
}

И затем я создал Синглтон ниже, чтобы управлять инъекциями:

public class DaggerWrapper {

    private static MainComponent mComponent;

    public static MainComponent getComponent() {
        if (mComponent == null) {
            initComponent();
        }
        return mComponent;
    }

    private static void initComponent () {
       mComponent = DaggerMainComponent
                .builder()
                .utilModule(new ModuleUtil())
                .build();
    }
}

Когда какой-либо класс из библиотечного модуля должен вводить свои члены, я просто вызываю DaggerWrapper.getComponent().inject(this); и это не так.

Ответ 2

Я делаю так:

  • Классы @Module относятся к основному проекту и предоставляют реализации, которые вы вводите в библиотечные элементы, поэтому в библиотечных проектах нет классов @Module

  • Элементы библиотеки, ожидающие зависимости, должны иметь доступ к ObjectGraph и вызывать .inject() для себя, но основной проект должен предоставить экземпляр объекта ObjectGraph в библиотеку с предоставленной зависимостью @Module

  • Как получить ObjectGraph из основного проекта в библиотеку? У вас может быть такой интерфейс:

    interface Injector {
        void inject(Object object);
        public ObjectGraph getObjectGraph(); 
    }

Контекстные объекты, такие как Activity или Application class, реализуют этот интерфейс (владельцы объектов ObjectGraph).

Если у вас есть пример Activity в библиотечном модуле, который нужно что-то вводить из основного проекта, это будет выглядеть так:

class LibraryActivity extends Activity {

    @Inject ActivationModule instance;

    void onCreate(... ) {
        Injector injector = (Injector)getApplicationContext();
        injector.inject(this)
    }
}

ActivationModule - это класс/интерфейс в проекте библиотеки.

Основной проект имеет класс приложения, который реализует интерфейс Injector и создает ObjectGraph с предоставленным dependecy для ActivationModule в проекте библиотеки.

class MyApplicationInTheMainProject extends Application implements Injector {

    ObjectGraph graph;

    @Override
    public void onCreate() {
        super.onCreate();
        graph = ObjectGraph.create(new ActivationModuleImpl(this));
    }

    @Override public void inject(Object object) {
        graph.inject(object);
    }

    @Override public ObjectGraph getObjectGraph() {
        return graph;
    }
}


@Module(injects = {
        LibraryActivity.class
}, library = true)
class ActivationModuleImpl implements ActivationModule {
    ....
}

Ответ 3

если вы передаете эту библиотеку людям, и они ничего не знают о вашем сценарии, поэтому вы должны написать ее так, чтобы ваш кинжал отлично работал без какой-либо помощи пользователя. (легче работать с лучшей практикой)

Я просто написал для вас некоторую библиотеку, чтобы показать, как это сделать. я написал библиотеку таким образом, что вы даже можете запустить ее отдельно и увидеть результат на вкладке сообщений. пользователь вашей библиотеки не должен ничего знать о кинжале и ничего не делает, он просто использует библиотеку, и кинжал будет настроен:

https://github.com/amirziaratii/libraryUsingDagger.git

Если эта библиотека - это то, что вы используете ее самостоятельно и для собственного проекта, лучше всего это сделать в этом проекте моего друга:

https://github.com/mmirhoseini/trakt.tv

на все ваши вопросы отвечают в этих двух проектах. задайте любой вопрос и плохой ответ в комментарии.

Ответ 4

Вот полный пример использования кинжала в приложении Шаг 1 Добавьте уровень отступления к уровню проекта gradle  classpath 'com.neenbedankt.gradle.plugins: android-apt: 1.8' Шаг 2 Уровень депинансирования уровня

применить плагин: 'com.android.application' применить плагин: 'android-apt' применить плагин: "com.neenbedankt.android-apt"

compile 'com.google.dagger:dagger:2.0'
provided 'com.google.dagger:dagger-compiler:2.0'
provided 'org.glassfish:javax.annotation:10.0-b28'

Шаг 3 Постройте кинжал с классом вашего приложения

Открытый класс TubeMateApp расширяет приложение {

public  AppComponent component;
public static TubeMateApp singleton;


public static TubeMateApp getInstance() {
    return singleton;
}

@Override
public void onCreate() {
    super.onCreate();
    singleton = this;
    setupGraph();
}

private void setupGraph() {
    component = DaggerAppComponent.builder()
            .appModule(new AppModule(this))
            .build();

    component.inject(this);
}


public AppComponent component() {
    return component;
}

} Шаг 4 Создайте AppModule следующим образом

@Module открытый класс AppModule {

private TubeMateApp app;

public AppModule(TubeMateApp application) {
    this.app = application;
}



@Provides
public Application provideApplication() {
    return app;
}

@Provides
@Singleton
Prefs prefs(){
    return Prefs.with(app);
}

// To use your custom requirement code here for example i have used Picasso with in the application

@Provides
@Singleton
Picasso getPicasso(){
    return Picasso.with(app);
}

@Provides
@Singleton
LayoutInflater getLayoutInflater() {
    return (LayoutInflater) app.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

} Шаг 5 Создайте компоненты приложения, которые необходимо вводить компоненты приложения для dagger здесь Шаг 6 Используйте кинжал в основной активности всплеска как применить кинжал впрыск см. этот скриншот