Android 片段和依赖注入
Posted
技术标签:
【中文标题】Android 片段和依赖注入【英文标题】:Android Fragment and Dependency Injection 【发布时间】: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 中吗?有没有其他方法可以达到效果?
【问题讨论】:
【参考方案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方法,即使它们之前已经调用过。以上是关于Android 片段和依赖注入的主要内容,如果未能解决你的问题,请参考以下文章
Android Dagger片段可以访问AppModule和ActivityModule依赖关系,但不能访问FragmentModule依赖关系
IOC 控制反转Android 视图依赖注入 ( 视图依赖注入步骤 | 视图依赖注入代码示例 )
IOC 控制反转Android 布局依赖注入 ( 布局依赖注入步骤 | 布局依赖注入代码示例 )