如何使用Dagger2在Fragment中注入对BroadcastReceiver对象的创建? [英] How to inject the creation of a BroadcastReceiver object in Fragment using Dagger2?
问题描述
我需要将 NetReceiver
对象的创建注入到片段中,但是出现以下错误:
I need to inject the creation of NetReceiver
object into my Fragment but I get the following error:
错误:[Dagger / MissingBinding] com.example.myapp.NetReceiver.OnNetCallback如果没有@Provides注释的方法就无法提供。
error: [Dagger/MissingBinding] com.example.myapp.NetReceiver.OnNetCallback cannot be provided without an @Provides-annotated method.
让我告诉您我所尝试的。这是我的 NetReceiver
类:
Let me show you what I have tried. This is my NetReceiver
class:
public class NetReceiver extends BroadcastReceiver {
private OnNetCallback onNetCallback;
@Inject
public NetReceiver(OnNetCallback onNetCallback) {
this.onNetCallback = onNetCallback;
}
@Override
public void onReceive(Context context, Intent intent) {
if (someCondition) {
onNetCallback.enableOperation(true);
}
}
public interface OnNetCallback {
void enableOperation(boolean isOk);
}
}
如您所见,我想注入构造函数 NetCallback
对象。我还创建了一个看起来像这样的Module类:
As you can see, I want to inject in the constructor a NetCallback
object. I have also created a Module class that looks like this:
@Module
public abstract class NetReceiverModule {
@ContributesAndroidInjector //Error?!?!?!?!
abstract NetReceiver.OnNetCallback provideOnNetCallback();
@Singleton
@Provides
static NetReceiver provideNetReceiver(NetReceiver.OnNetCallback onNetCallback) {
return new NetReceiver(onNetCallback);
}
}
这是我的片段在工作时的样子:
This is how my fragment look liked when it worked:
public class MapFragment extends Fragment implements NetReceiver.OnNetCallback {
private NetReceiver netReceiver;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Inflate View
netReceiver = new NetReceiver(this); //Worked
}
@Override
public void onResume() {
super.onResume();
mainActivity.registerReceiver(netReceiver, intentFilter);
}
@Override
public void onPause() {
super.onPause();
mainActivity.unregisterReceiver(netReceiver);
}
}
这是它不工作时的样子:
And this is how it looks when it is not working:
public class MapFragment extends DaggerFragment implements NetReceiver.OnNetCallback {
@Inject NetReceiver netReceiver;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Inflate View
//netReceiver = new NetReceiver(this); //Worked
}
@Override
public void onResume() {
super.onResume();
mainActivity.registerReceiver(netReceiver, intentFilter);
}
@Override
public void onPause() {
super.onPause();
mainActivity.unregisterReceiver(netReceiver);
}
}
推荐答案
问题是 Dagger2
不能做魔术。如何知道从何处提供 OnNetCallback
。您的片段扩展了此回调,但是其构造函数都没有使用 @Inject
注释(因为不建议您创建显式的片段构造器),也没有提供 @Provides
在模块中带有注释的方法, OnNetCallback
也不通过 MapFragment
通过 @Bind
带注释的方法,当您尝试将这样的接口与 @Qualifier
一起注入时,这是必须。
The problem is that Dagger2
cannot do magic. How it should know from where to provide a OnNetCallback
. Your fragment extends this callback but neither its constructor is annotated with @Inject
annotation(because you are not advised to create explicit fragment constructors) nor it is provided with @Provides
annotated method in your module, nor OnNetCallback
is bind with MapFragment
via @Bind
annotated method which is a "must be" when you trying to inject interface like this along with a @Qualifier
.
但这不是主要问题。
即使您能够正确地完成所有先前的工作,它仍然不起作用,因为将存在循环依赖关系- MapFragment
取决于 NetReceiver
, NetReceiver
取决于 OnNetCallback
, OnNetCallback
是 MapFragment
,因此 NetReceiver
取决于 MapFragment
。匕首不会允许您这样做。
Even if you will manage to do all the previous stuff correctly it will still not work because there will be a circular dependency - MapFragment
depends on NetReceiver
, NetReceiver
depends on OnNetCallback
, OnNetCallback
is a MapFragment
, thus NetReceiver
depends on MapFragment
. Dagger won't let you do it.
如果您希望您的 MapFragment
实现 OnNetCallback
我建议如下:
If you want your MapFragment
to implement OnNetCallback
I would suggest something like:
public class NetReceiver extends BroadcastReceiver {
public OnNetCallback onNetCallback;
@Override
public void onReceive(Context context, Intent intent) {
if (someCondition && onNetCallback!= null) {
onNetCallback.enableOperation(true);
}
}
public interface OnNetCallback {
void enableOperation(boolean isOk);
}
}
public class MapFragment extends DaggerFragment implements NetReceiver.OnNetCallback {
@Inject NetReceiver netReceiver;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Inflate View
netReceiver.onNetCallback = this
}
@Override
public void onResume() {
super.onResume();
mainActivity.registerReceiver(netReceiver, intentFilter);
}
@Override
public void onPause() {
super.onPause();
mainActivity.unregisterReceiver(netReceiver);
}
}
如果要注入,请单独创建一些来自 OnNetCallback
的 Fragment
实现,并@在模块中提供并将其注入片段。
If you want it to be injected - create some separate from Fragment
implementation of OnNetCallback
and @Provide it in module and inject it into fragment.
也 @ContributesAndroidInjector
应该用于喷射器,但不能用于喷射器-它告诉 Dagger
该类应该注入一些用 @Inject
, @Provides
和 @Bind
批注。
Also @ContributesAndroidInjector
should be used for the injeters but not for the injectees - it tells Dagger
that this class should be injected with some stuff described with @Inject
, @Provides
and @Bind
annotations.
我也建议您阅读官方指南关于 Dagger2
和其在Android中的用法。
Also I would recommend you to read an official guide regarding Dagger2
and its usage for Android.
希望有帮助。
这篇关于如何使用Dagger2在Fragment中注入对BroadcastReceiver对象的创建?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!