在 Android 中“注入所有内容”是一种不好的做法吗?

2024-04-26

在研究依赖注入时,我发现了一些建议的方法注入一切 http://frogermcs.github.io/inject-everything-viewholder-and-dagger-2-example/和其他人说没有必要这样做 https://stackoverflow.com/a/37517764/6100078.

在我当前的项目中,我关于依赖注入的经验法则是“如果该类是我创建的,我将其设置为可注入“。换句话说,只有像这样的类SimpleDateFormat, ArrayList, HashMap是我的项目中的新事物。我这样做的目的是我可以@Inject任何地方的任何班级一次调用Injector.getApplicationComponent().inject(this) in the Activity。基本上我所有的类都有一个非参数构造函数@Inject.

我最初使用 DI 是因为我认为一旦使用 DI 将会提高性能和内存使用率new运算符仅由 Dagger 生成的类使用。但我读了一篇post https://stackoverflow.com/a/21544630/6100078Dagger 1 开发人员表示 DI 对性能没有影响,使用基本上是为了减少样板文件。

第一个问题是:

  • Dagger 2在Android应用中没有任何性能优势吗?

我的项目运行没有问题,我认为“注入一切”的方法有助于更好地组织,尽管有一些缺点。

使用此方法的一个示例是以下类:

public class TimelineEntryAdapter {

@Inject
Provider<TwitterEntry> mTwitterProvider;

@Inject
Provider<InstagramEntry> mInstagramProvider;

@Inject
Provider<FacebookEntry> mFacebookProvider;

@Inject
TimelineEntryComparator mComparator;

@Inject
public TimelineEntryAdapter() {
}

第二个问题是:

  • 在 Android 中注入所有内容是一种不好的做法吗?

如果第二个问题的答案是“否”,是否有更好的方法来处理非参数构造函数来创建类?因为当我创建一个非参数构造函数时@Inject注释和类需要一些参数才能使用,我必须使用setters:

public class SavelArtist {

private MusicBrainzArtist mMusicBrainzArtist;

private DiscogsArtist mDiscogsArtist;

private List<SavelTweet> mTweetList;

private SpotifyArtist mSpotifyArtist;

private List<SavelInstagram> mInstaTimeline;

private List<SavelFacebook> mFacebookTimeline;

private List<SavelRelease> mReleases;

@Inject
Provider<SavelRelease> mReleaseProvider;

@Inject
public SavelArtist() {
}

public void setMusicBrainzArtist(MusicBrainzArtist mbArtist) {
    mMusicBrainzArtist = mbArtist;
}

public void setDiscogsArtist(DiscogsArtist discogsArtist) {
    mDiscogsArtist = discogsArtist;
}

public void setTweetList(List<SavelTweet> tweetList) {
    mTweetList = tweetList;
}

public void setSpotifyArtist(SpotifyArtist spotifyArtist) {
    mSpotifyArtist = spotifyArtist;
}

public void setInstaTimeline(List<SavelInstagram> instaTimeline) {
    mInstaTimeline = instaTimeline;
}

public void setFacebookTimeline(List<SavelFacebook> fbTimeline) {
    mFacebookTimeline = fbTimeline;
}

一旦在流程中同时获取所有参数,就可以在构造函数上设置所有参数。


在研究依赖注入时,我发现一些方法建议注入所有内容,而另一些方法则认为没有必要这样做。

The froger_mcs 博客条目 http://frogermcs.github.io/inject-everything-viewholder-and-dagger-2-example/您引用的内容并不提倡注入所有内容。它非常明确地指出:

这篇文章的目的是展示我们can做,不是我们做的should do.

它还指出了注入所有内容的缺点:

如果您想将 Dagger 2 用于项目中的几乎所有内容,您很快就会发现生成的注入代码使用了一大块 64k 方法计数限制。

现在,回答您的问题:

Dagger 2在Android应用中没有任何性能优势吗?

虽然 Dagger 2 比其他基于反射的 DI 框架(例如 Guice)提供了性能优势,但它并没有声称比通过调用构造函数手动构建对象图提供任何性能优势。您可以自己检查生成的类,看看这些类最终仍然调用构造函数。

在 Android 中注入所有内容是一种不好的做法吗?

让我们看一下下面非常常见的 Android 代码:

Intent nextActivity = new Intent(this, NextActivity.class);
startActivity(nextActivity);

我们是否应该提取一个IntentFactory并使用 Dagger 2 注入它只是为了避免new关键字在这里?在这一点上,很容易走上迂腐之路。中的建议其他答案你引用 https://stackoverflow.com/a/37517764/6100078关于注射剂和新剂之间的区别更加灵活和优雅。

继续你的下一个问题:

如果第二个问题的答案是“否”,是否有更好的方法来处理非参数构造函数来创建类?因为当我使用 @Inject 注释创建非参数构造函数并且类需要使用一些参数时,我必须使用 setter:

使用 setter 是错误的参数方法。你应该区分依赖关系 and 参数。依赖关系通常与对象本身具有相同的生命周期。在对象的生命周期中,可以使用不同的参数调用为该对象公开的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Android 中“注入所有内容”是一种不好的做法吗? 的相关文章

随机推荐