java Dagger for Android:在调用 setContentView 后将 Activity 注入对象图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13986092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 14:38:55  来源:igfitidea点击:

Dagger for Android: Injecting an Activity to the object graph after calling setContentView

javaandroiddependency-injectiondagger

提问by curioustechizen

I want to use Dagger on Android to inject an instance of an Activityinto another class as follows:

我想在 Android 上使用 Dagger 将 an 的实例Activity注入另一个类,如下所示:

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());
        //...
        //...
    }
}

I am able to do the injection, but all fields of the Activityare nullat the time of injection.

我能够进行注入,但所有字段Activitynull在注入时

Here's how I am doing the injection:

这是我进行注射的方式:

My Activityis a module in itself.

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;
    }


}

This is my main module

这是我的主要模块

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

And my Applicationclass that bootstraps the object graph.

我的Application类引导对象图。

class CustomApplication extends Application{

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

    static getObjectGraph(){
        return sObjectGraph;
    }
}

I am looking for a way to explicitly perform the injection after I call setContentView.

我正在寻找一种在调用后setContentView显式执行注入的方法。

How do I go about doing this?

我该怎么做?



EDIT 1:

编辑 1:

I got it to work like this - however I am not sure if this is the "right way". What I do is

我让它像这样工作 - 但是我不确定这是否是“正确的方式”。我做的是

  1. Pass in the Activity to the Moduleconstructor
  2. Ensure that I build the ObjectGraphafterI do setContentView()so that a proper Activityinstance is passed in to the ObjectGraph.
  1. 将 Activity 传递给Module构造函数
  2. 确保ObjectGraph我这样做之后构建 ,setContentView()以便将正确的Activity实例传递给ObjectGraph.

My Activityis no longer a dagger Module.

Activity的不再是匕首了Module

This translates to the following in code:

这在代码中转化为以下内容:

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

    private Activity mActivity;

    public DaggerModule (Activity activity){
        this.mActivity = activity;
    }

    @Provides PresentationLayer providePresentation(){
        return new PresentationLayer(mActivity);
    }
}

And this is how my Activitylooks:

这就是我的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);
    }
}

This solution seems to address the points raised by Jesse Wilson in this answer. However, I am concerned about the performance, since the ObjectGraphis going to be built every time the Activityis created.

这个解决方案似乎解决了 Jesse Wilson 在这个答案中提出的观点。然而,我关心的性能,因为ObjectGraph将要建立的每个时间Activity被创建

Any thoughts?

有什么想法吗?

回答by Jesse Wilson

Unfortunately this probably isn't going to work with Dagger, or with most other dependency injection frameworks. The problem is that the lifecycle of Activitydoesn't cleanly line up with the lifecycle of PresentationLayer. For example, when you rotate your screen, Android will destroy the activity and create another one in its place. There's no hook for PresentationLayerto participate in that.

不幸的是,这可能不适用于 Dagger 或大多数其他依赖注入框架。问题是 的生命Activity周期与PresentationLayer. 例如,当您旋转屏幕时,Android 将销毁该 Activity 并在其位置创建另一个 Activity。没有PresentationLayer必要参与其中。

At Square we've been using Ottoto communicate between activities and their backends and it has worked well. See Eric Burke's sample code projectfor an example.

在 Square,我们一直使用Otto在活动及其后端之间进行通信,并且效果很好。有关示例,请参阅 Eric Burke 的示例代码项目