8

Activity次のように、Android で Dagger を使用して、のインスタンスを別のクラスに挿入したいと考えています。

class PresentationLayer{
    Activity mActivity;
    
    @Inject
    public PresentationLayer(Activity activity){
        this.mActivity = activity;
    }
    
    public void presentData(User user){
        ((TextView)mActivity.findViewById(R.id.username))
            .setText(user.getName());
        //...
        //...
    }
}

注入はできますが、 のすべてのフィールドはActivity注入null時です

私が注射をしている方法は次のとおりです。

MyActivityはそれ自体がモジュールです。

@Module(
    complete = false
)
class MainActivity extends Activity{
    
    @Override
    public void onCreate(Bundle bundle){
        super.onCreate(bundle);
        setContentView(R.layout.main_activity);
        ObjectGraph objectGraph = CustomApplication.getObjectGraph();
        PresentationLayer pres = objectGraph.get(PresentationLayer.class);
    }
    
    @Provides Activity provideActivity(){
        return this;
    }
    
    
}

これは私のメインモジュールです

@Module(
    entryPoints = PresentationLayer.class,
    includes = MainActivity.class
)
class DaggerModule{
    @Provides PresentationLayer providePresentation(Activity activity){
        return new PresentationLayer(activity);
    }
}

そして、Applicationオブジェクト グラフをブートストラップするクラスです。

class CustomApplication extends Application{

    private static ObjectGraph sObjectGraph;
    @Override
    public void onCreate(){
        sObjectGraph = ObjectGraph.create(new DaggerModule());
    }
    
    static getObjectGraph(){
        return sObjectGraph;
    }
}

を呼び出した後setContentView、明示的に注入を実行する方法を探しています。

どうすればこれを行うことができますか?


編集1:

このように動作するようになりましたが、これが「正しい方法」であるかどうかはわかりません。私がすることは

  1. Activity をModuleコンストラクターに渡す
  2. 適切なインスタンスが に渡されるように、実行ObjectGraph にをビルドするようにしてください。setContentView()ActivityObjectGraph

Activityはもはや短剣ではありませんModule

これは、コードで次のように変換されます。

@Module(
    entryPoints = PresentationLayer.class
)
class DaggerModule{

    private Activity mActivity;
    
    public DaggerModule (Activity activity){
        this.mActivity = activity;
    }
    
    @Provides PresentationLayer providePresentation(){
        return new PresentationLayer(mActivity);
    }
}

そして、これが私のActivity見た目です:

class MainActivity extends Activity{
    
    @Override
    public void onCreate(Bundle bundle){
        super.onCreate(bundle);
        setContentView(R.layout.main_activity);
        ObjectGraph objectGraph = CustomApplication.getObjectGraph(this);
        PresentationLayer pres = objectGraph.get(PresentationLayer.class);
        User user = //get the user here
        pres.presentData(user);
    }
}

このソリューションは、この回答で Jesse Wilson によって提起されたポイントに対処しているようです。ただし、が作成されるたびObjectGraphに がビルドされるため、パフォーマンスが心配です。Activity

何かご意見は?

4

1 に答える 1

19

残念ながら、これはおそらく Dagger や他のほとんどの依存性注入フレームワークでは機能しません。問題は、 のライフサイクルが のライフサイクルとActivityきれいに一致しないことですPresentationLayer。たとえば、画面を回転させると、Android はアクティビティを破棄し、代わりに別のアクティビティを作成します。PresentationLayerそれに参加するためのフックはありません。

Square では、Ottoを使用してアクティビティとそのバックエンド間の通信を行ってきましたが、うまく機能しています。例については、 Eric Burke のサンプル コード プロジェクトを参照してください。

于 2012-12-21T14:42:12.803 に答える