web-dev-qa-db-ja.com

Androidライブラリプロジェクトで短剣を使用する方法

現在、DaggerをAndroidプロジェクトに追加しようとしています。アプリプロジェクトの場合、ObjectGraphの作成方法は簡単で明確です。しかし、最善の方法はわかりません。これは私のAndroidライブラリプロジェクト。

アプリのApplicationクラスでObjectGraphを構築し続け、OGをLibraryModuleに渡します。ライブラリのOGをApps OGに追加しますか?または、ライブラリにObjectGraph全体を構築する必要がありますか?

ObjectGraph.inject(this)によってライブラリにクラスを注入する必要がある場合はどうなりますか?私のAppsプロジェクトでは、ApplicationクラスからOGを取得できます。しかし、ライブラリでこれを処理する方法は? ObjectGraphに@Providesメソッドを追加する必要がありますか?

ご協力ありがとうございます。

編集:要するに:アプリケーションクラスでビルドされているためOGにアクセスできないライブラリプロジェクトでObjectGraph.inject(this)を呼び出すにはどうすればよいですか?

49
sebastian

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);を呼び出すだけです。

私はこの方法でやっています:

  1. @Moduleクラスはメインプロジェクトに属し、ライブラリ要素に注入する実装を提供するため、ライブラリプロジェクトには@Moduleクラスはありません。

  2. 依存関係を予期しているライブラリ要素は、ObjectGraphにアクセスし、それ自体で.inject()を呼び出す必要がありますが、メインプロジェクトは、指定された@Module依存関係を持つObjectGraphインスタンスをライブラリに与える必要があります

  3. ObjectGraphをメインプロジェクトからライブラリに取得する方法は?次のようなインターフェースを使用できます。

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

ActivityクラスやApplicationクラスなどのコンテキストオブジェクトは、このインターフェイス(ObjectGraphオブジェクトのホルダー)を実装します。

メインプロジェクトから注入するものを必要とするライブラリモジュールのアクティビティの例がある場合、これは次のようになります。

class LibraryActivity extends Activity {

    @Inject ActivationModule instance;

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

ActivationModuleは、ライブラリプロジェクトのクラス/インターフェイスです。

メインプロジェクトには、インジェクターインターフェイスを実装し、ライブラリプロジェクトのActivationModuleに提供された依存関係を使用してObjectGraphを作成するアプリケーションクラスがあります。

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 {
    ....
}
12
LaLiLuLeLo

このライブラリを人々に提供していて、彼らがあなたのシナリオについて何も知らない場合、ユーザーの助けなしであなたのダガーが完全に機能するようにそれを書かなければなりません。 (より良いプラクティスで作業しやすい)

方法を示すためのライブラリをいくつか作成しました。ライブラリをスタンドアロンで実行し、[メッセージ]タブで結果を確認できるようにライブラリを作成しました。ライブラリのユーザーは、短剣について何も知る必要がなく、ライブラリを使用するだけで、短剣が設定されます:

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

このライブラリが自分で、自分のプロジェクトで使用するものである場合、ベストプラクティスは私の友人のこのプロジェクトのように行うことです。

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

これらの2つのプロジェクトでは、すべての質問に答えています。コメントで質問や悪い答えをしてください。

5
Amir Ziarati