【问题标题】:Am I doing dependency injection in activity code correctly?我是否正确地在活动代码中进行依赖注入?
【发布时间】:2018-12-10 17:37:54
【问题描述】:

我目前正在编写我的第一个 android 项目,我想根据依赖注入模式对其进行重构。从我的应用程序中最简单的活动开始 - 启动屏幕 - 我问自己,我是否正确理解了模式的概念。

这是到目前为止我的SplashActivity 的代码:

public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);

        Fragment fragmentToDisplay = null;
        if (!(getIntent().getBooleanExtra("isLaunch", true))) {
            fragmentToDisplay = new LoginFragment();
        } else {
            if (savedInstanceState == null) {
                fragmentToDisplay = new SplashFragment();
            }
        }
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragmentToDisplay).commit();
    }
}

根据 IntentExtra "isLaunch" 的内容,我想显示不同的片段。现在,我读到每个new ServiceXY() 都会使代码的可测试性降低,这实际上不是依赖注入的目标。所以我像这样重构了我的代码:

public class SplashActivity extends AppCompatActivity {

    private SplashFragment splashFragment;
    private LoginFragment loginFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);

        splashFragment = new SplashFragment();
        loginFragment = new LoginFragment();

        Fragment fragmentToDisplay = null;
        if (!(getIntent().getBooleanExtra("isLaunch", true))) {
            fragmentToDisplay = loginFragment;
        } else {
            if (savedInstanceState == null) {
                fragmentToDisplay = splashFragment;
            }
        }
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragmentToDisplay).commit();
    }
}

但是,这似乎并没有太大的不同。如果我想测试,如果显示正确的片段,这将如何提高我的代码的可测试性?谢谢转发。

【问题讨论】:

  • “我已经读到每个新的 ServiceXY() 都会使代码的可测试性降低” 你在哪里读到这个?我认为,由于片段(重构代码)的可用参考,可测试性变得更好。

标签: android android-fragments testing android-activity dependency-injection


【解决方案1】:

你是对的,你的改变没有太大的区别,也没有注入依赖。由于您的 SplashActivity 对象负责创建片段,因此它们仍然依赖于 SplashActivity 对象。

如果要使用依赖注入,则必须在 SplashActivity 之外的某处创建片段对象,然后将它们传递给对象。

遵循依赖注入原则,您的服务将是片段类型,使用该服务的客户端将是 SplashActivity,因此您需要另一个对象将正确的服务“注入”到客户端。 https://stackify.com/dependency-injection/

您可以使用第一个 sn-p 中的代码,但无需检查 oncreate 中的布尔值来设置正确的片段类型,您只需将片段对象传入 splashactivity 类并转到fragmentToDisplay = fragmentPassedIntoClass。然后您可以测试传递给类的片段是否是正确的类型,以及事务是否正确开始。注射器将负责传递正确的fragmentPassedIntoClass

MainFragment fragment;
if(splash){ fragment = new SplashFragment(); }
if(login){fragment = new LoginFragment(); }

// Pass fragment variable into splash activity
SplashActivity activty = new SplashActivity(fragment);

public class SplashActivity{
    MainFragment mFragment;

    public SplashActivty(MainFragment fragment){
        mFragment = fragment;
    }
}

【讨论】:

  • 抱歉,我跑题了。所以我必须通过“注入器”将两个片段实例传递给活动?哪个是一个好的做法,特别是在哪种方法中?我认为,使用活动构造函数不是一个好方法。
  • 您想使用 LoginFragment 或 SplashFragment 对吗?因此,您将创建一个基类,例如“MainFragment”,然后 LoginFragment 和 SplashFragment 将从该基类派生。因此,如果您的活动有一个 MainFragment 类型的对象,您可以将其传递给 SplashFragment 或 LoginFragment 并将其存储在同一个 MainFragment 变量中。对于注入,请查看此代码中的示例。 en.wikipedia.org/wiki/Dependency_injection
  • 我在我的原始帖子中添加了非常简单的示例,以获得基本想法。在这种情况下,类型 MainFragment 与您在原始代码中使用的类型“Fragment”同义
  • 幸运的是,这两个片段已经有一个共同的超类 :D。我根据你的提示改变了我的活动,测试仍然有效。谢谢(我仍然有一些解决方法可以将初始片段传递给我的活动,但我现在走在正确的轨道上:))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-23
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-20
  • 2020-05-11
相关资源
最近更新 更多