【问题标题】:Android Fragment and Dependency InjectionAndroid 片段和依赖注入
【发布时间】:2014-06-16 01:15:19
【问题描述】:

正如标题所说,我试图找出哪一个是在片段中注入依赖项的最佳方法。 我想独立于 RoboGuice 等外部框架。

现在,以最简单的方式,我有一个抽象某种逻辑的接口,并且我想从一个 Activity 中注入这个接口的实现。我知道我必须为我的片段提供一个默认构造函数,因为系统可能需要在某些时候重新创建片段,并且创建片段的新实例的常用方法是提供处理创建的静态方法,例如这个:

public static Fragment newInstance() {
    final Bundle bundle = new Bundle();
    ...
    final Fragment fragment = new MyFragment();
    fragment.setArguments(bundle);
    return fragment;
}

如何将我的依赖项传递给片段?我应该让它实现 Parcelable 或 Serializable 接口,然后将其打包到 Bundle 中吗?有没有其他方法可以达到效果?

【问题讨论】:

    标签: android dependency-injection dependencies fragment code-injection


    【解决方案1】:

    一个简单的解决方案是声明一个接口,该接口声明片段所需的依赖项。然后让Fragment的Context实现这个接口,在需要的时候从Context中轮询依赖。

    合同:

    public interface MyDependencies {
    
        MyDep getDep();
    
    }
    

    活动:

    public MyActivity extends Activity implements MyDependencies {
    
        @Override
        public MyDep getDep(){
           return createMyDependencyOrGetItFromASingletonOrGetItFromApplication()
        }
    }
    

    片段:

    public void onActivityCreated(Bundle b){
         super.onActivityCreated(b)
    
         if (getActivity() instanceOf MyDependencies) {
             MyDep dep = ((MyDependencies) getActivity).getDep();
         } else {
             throw new RuntimeException("Context does not support the Fragment, implement MyDependencies")
         }
    }
    

    因此,事实上,由于契约是由接口定义的,因此与 Activity 没有不必要的耦合。

    【讨论】:

    • 喜欢那个方法名“createMyDependencyOrGetItFromASingletonOrGetItFromApplication”lol
    【解决方案2】:

    你为什么不从你的活动中获取依赖?

    public void onActivityCreated( Bundle b){
         super.onActivityCreated(b)
         DependencyClass c = ((MyActivity)getActivity()).getDependency();
    }
    

    【讨论】:

    • 如果我这样做,我最终会将 Fragment 耦合到 Activity 对吗?我仍然希望 Fragment 是独立且可重用的。
    【解决方案3】:

    如果你不能通过构造函数传入依赖(如果你需要一个默认构造函数),并且你不想使用像 Dagger 或 RoboGuice 这样的依赖注入库,另一种经典的方法是使用 setter “注入”依赖项。

    Fragment MyFragment {
    
    Depend mDepend;
    
    ....
    
    
        public void setDepend(Depend depend) {
            mDepend = depend;
        }
    
    }
    

    然后在您的活动中,您可以在 onCreate 方法中注入依赖项。

    所以在你的活动中是这样的:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);
        MapFragment wrapperFragment = new WrapperFragment();
        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .add(R.id.map_container, wrapperFragment).commit();
        // find the fragment
        // call the setter
        }
    }
    

    【讨论】:

    • 这个解决方案的问题是,当android重新创建片段时,它使用默认构造函数并且不调用set方法,即使它们之前已经调用过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    • 2021-11-19
    • 2020-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多