我正在使用Android Dagger2,但我收到以下错误.
我的AppModule类是:
@Module
public class AppModule {
@Provides
public DownloadFilePresenterImp provideDownloadfilePresenterImp(DownloadFileView downloadFileView) {
return new DownloadFilePresenterImp(downloadFileView);
}
}
Run Code Online (Sandbox Code Playgroud)
我的AppComponent接口是:
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(DownloadFileView target);
}
Run Code Online (Sandbox Code Playgroud)
我的DaggerInject类
public class DaggerInjector {
private static AppComponent mAppComponent = DaggerAppComponent
.builder()
.appModule(new AppModule())
.build();
public static AppComponent getAppComponent() {
return mAppComponent;
}
}
Run Code Online (Sandbox Code Playgroud)
我想注入我的Fragment(DownloadFileView)
@Inject DownloadFilePresenterImp mDownloadFilePresenterImp;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.download_file_view, container, false);
/* Initialize presenter */
DaggerInjector.getAppComponent().inject(DownloadFileView.this);
/* Use mDownloadFilePresenterImp here */
return view;
}
Run Code Online (Sandbox Code Playgroud)
和我的DownloadFilePresenterImp构造函数部分
public class DownloadFilePresenterImp implements DownloadFilePresenterContact {
public DownloadFilePresenterImp(DownloadFileView downloadFileView) {
mDownloadFileContract = downloadFileView;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误:
Error:(17, 10) error: com.sunsystem.downloadfilechatapp.downloader.DownloadFileView cannot be provided without an @Inject constructor or from an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
com.sunsystem.downloadfilechatapp.downloader.DownloadFileView is injected at
com.sunsystem.downloadfilechatapp.downloader.dagger.AppModule.provideDownloadfilePresenterImp(downloadFileView)
com.sunsystem.downloadfilechatapp.downloader.DownloadFilePresenterImp is injected at
com.sunsystem.downloadfilechatapp.downloader.DownloadFileView.mDownloadFilePresenterImp
com.sunsystem.downloadfilechatapp.downloader.DownloadFileView is injected at
com.sunsystem.downloadfilechatapp.downloader.dagger.AppComponent.inject(target)
Run Code Online (Sandbox Code Playgroud)
非常感谢任何建议,
Dav*_*jak 27
该错误只表明dagger无法提供所述依赖关系.您必须以某种方式将它添加到您的组件 - 因为它是Fragment- 您将不得不使用@Module.
我假设你AppComponent是由你Application的开始创建的.您AppComponent的生命周期比您的活动和片段生命周期都长.因此,它是合理的,它不知道如何在您的案例中提供活动或片段.
DownloadFilePresenterImp意志取决于你DownloadFileView.DownloadFilePresenterImp你的DownloadFileViewAppComponent是对活动一无所知的内容,显然没有关于片段的内容.它具有不同的范围和生命周期.为了不进一步引起混淆,我将讨论片段,因为它们和活动生命周期是你必须记住的.你可以使用DownloadFileView模块,但那些长名称会让人感到困惑.
要提供片段或活动,您必须使用模块.例如
@Module FragmentModule {
Fragment mFragment;
FragmentModule(Fragment fragment) { mFragment = fragment; }
@Provides Fragment provideFragment() { return mFragment; }
// here you could also provide your view implementation...
@Provides DownloadFileView provideDownloadFileView() {
return (DownloadFileView) mFragment;
}
}
Run Code Online (Sandbox Code Playgroud)
由于此模块应仅与片段生命周期一起使用,因此必须使用子组件或具有依赖关系的组件AppComponent.
@Component(dependencies=AppComponent.class, modules=FragmentModule.class)
interface FragmentComponent {
// inject your fragment
void inject(DownloadFileView fragment);
}
Run Code Online (Sandbox Code Playgroud)
在您的片段中,您必须正确创建组件...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.download_file_view, container, false);
// properly create a component that knows about the fragment
DaggerFragmentComponent.builder()
.appComponent(DaggerInjector.getAppComponent())
.fragmentModule(new FragmentModule(this))
.build()
.inject(DownloadFileView.this);
return view;
}
Run Code Online (Sandbox Code Playgroud)
另外,我强烈建议您查看并使用构造函数注入
public class DownloadFilePresenterImp implements DownloadFilePresenterContact {
@Inject
public DownloadFilePresenterImp(DownloadFileView downloadFileView) {
mDownloadFileContract = downloadFileView;
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您喜欢冗余代码,则可以将provideDownloadfilePresenterImp(View)方法移动FragmentModule到具有相同效果的方法.
完成.
好...这应该工作
@Module
public class AppModule {
@Provides
public DownloadFilePresenterImp provideDownloadfilePresenterImp() {
return new DownloadFilePresenterImp();
}
}
Run Code Online (Sandbox Code Playgroud)
和
public class DownloadFilePresenterImp implements DownloadFilePresenterContact {
private WeakReference<DownloadFileView> weak;
public DownloadFilePresenterImp() {
}
public void setDownloadFileView(DownloadFileView view) {
weak = new WeakReference<>(view);
}
public void doSomething() {
if (weak != null) {
DownloadFileView view = weak.get();
if (view != null) {
[...]
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,图(组件)提供的所有对象都必须使用图本身所属或构建的对象来构建。因此,我删除了DownloadFilePresenterImp(DownloadFileView downloadFileView)会导致泄漏的构造函数,并用创建对视图的WeakReference的setter进行了替换。
编辑
如果要注入在运行时生成的对象,唯一的方法是将该对象传递给AppComponent。在您的情况下,可能是:
AppComponent.java
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(DownloadFileView target);
}
Run Code Online (Sandbox Code Playgroud)
AppModule.java
@Module
public class AppModule {
private final DownloadFileView downloadFileView;
public AppModule(DownloadFileView downloadFileView) {
this.downloadFileView = downloadFileView;
}
@Provides
public DownloadFilePresenterImp provideDownloadfilePresenterImp() {
return new DownloadFilePresenterImp(downloadFileView);
}
}
Run Code Online (Sandbox Code Playgroud)
下载FilePresenterImp.java
public class DownloadFilePresenterImp {
private final DownloadFileView downloadFileView;
public DownloadFilePresenterImp(DownloadFileView downloadFileView) {
this.downloadFileView = downloadFileView;
}
}
Run Code Online (Sandbox Code Playgroud)
下载FileView.java
public class DownloadFileView extends Fragment {
private AppComponent mAppComponent;
@Inject
DownloadFilePresenterImp impl;
public DownloadFileView() {
// Required empty public constructor
mAppComponent = DaggerAppComponent
.builder()
.appModule(new AppModule(this))
.build();
mAppComponent.inject(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_download_file_view, container, false);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
37337 次 |
| 最近记录: |