【发布时间】:2016-07-11 05:04:01
【问题描述】:
我有一个扩展 TextView 的自定义视图。我应该在哪里调用我的组件来注入视图?
component.inject(customTextView);
【问题讨论】:
标签: java android view dependency-injection dagger-2
我有一个扩展 TextView 的自定义视图。我应该在哪里调用我的组件来注入视图?
component.inject(customTextView);
【问题讨论】:
标签: java android view dependency-injection dagger-2
所以,我发现我需要在自定义视图的构造函数中添加注入(在所有视图中,或者一个调用另一个)
例子:
public class CustomTextView extends TextView {
@Inject
AnyProvider anyProvider;
public CustomTextView(Context context) { this(context, null); }
public CustomTextView(Context AttributeSet attrs) {
super(context, attrs);
Application.getComponent(context).inject(this);
}
}
【讨论】:
ApplicationComponent - 由applicationInjector() 返回 - 应该扩展AndroidInjector<MyApplication>,因此可以转换为ApplicationComponent。我收到一个编译器警告,告诉我重写 ApplicationComponent.Builder.build() 的返回类型以澄清这一点。多次调用applicationInjector() 可能不太好,因为它会多次创建组件,所以我正在存储对它的引用……但不确定这是否是最佳实践。也许跟进一个新问题。
我对这种事情的一般解决方案是这样的
public class WelcomeView
extends LinearLayout {
private static final String TAG = "WelcomeView";
public WelcomeView(Context context) {
super(context);
init(context);
}
public WelcomeView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public WelcomeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@TargetApi(21)
public WelcomeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
if(!isInEditMode()) {
Application.getComponent(context).inject(this);
}
}
【讨论】:
((CustomApplication)(context.getApplicationContext()).getComponent().inject(this);
Component。我见过像单例枚举、全局 LinkedHashMap、MortarScope、自定义 ContextWrapper 等解决方案。
更新:自 2.10 版本的 Dagger 起,此答案无效。
自定义视图:
public class CustomView extends View {
@Inject
AnyObject anyObject;
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
MainActivity mainActivity = (MainActivity) getContext();
mainActivity.getComponent().inject(CustomView.this);
}
}
活动:
ActivityComponent mComponent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mComponent = DaggerActivityComponent.builder()
.appComponent(getApp().getAppComponent())
.activityModule(new ActivityModule(MainActivity.this))
.build();
mComponent.inject(MainActivity.this);
...
}
public ActivityComponent getComponent() {
return mComponent;
}
具有 Activity 范围的 Dagger2 组件:
@ActivityScope
@Component(dependencies = AppComponent.class, modules = {ActivityModule.class})
public interface ActivityComponent extends AppComponent {
void inject(MainActivity mainActivity);
void inject(CustomView customView);
}
范围:
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {}
【讨论】:
onFinishInflate(...)。