【发布时间】:2017-12-04 14:09:25
【问题描述】:
我将 MVP 架构与 Dagger2 一起使用。我想使用构造函数注入在我的 Presenter 中获取 Context。
我的活动:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_appintroduction);
activityComponent().inject(this);
ButterKnife.bind(this);
skipall.bringToFront();
}
我的演示者:
@ConfigPersistent
public class AppIntroPresenter extends BasePresenter<AppIntroMvpView> {
private final DataManager mDataManager;
private final Context ctx1;
@Inject
public AppIntroPresenter(DataManager dataManager,Context context) {
mDataManager = dataManager;
ctx1=context;
}
public void openCamView(Context ctx) {
ctx.startActivity(new Intent(ctx, CameraActivity.class));
}
}
我的应用程序组件:
@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(SyncService syncService);
@ApplicationContext Context context();
Application application();
RibotsService ribotsService();
PreferencesHelper preferencesHelper();
DatabaseHelper databaseHelper();
DataManager dataManager();
RxEventBus eventBus();
ClassService classService();
AnsweredQuestionService answeredQuestionService();
}
我的活动组件:
@PerActivity
@Subcomponent(modules = ActivityModule.class)
public interface ActivityComponent {
void inject(MainActivity mainActivity);
void inject(CameraActivity cameraActivity);
void inject(AppIntroActivity appIntroActivity);
}
我的应用模块:
@Module
public class ApplicationModule {
protected final Application mApplication;
public ApplicationModule(Application application) {
mApplication = application;
}
@Provides
Application provideApplication() {
return mApplication;
}
@Provides
@ApplicationContext
Context provideContext() {
return mApplication;
}
@Provides
@Singleton
RibotsService provideRibotsService() {
return RibotsService.Creator.newRibotsService();
}
@Provides
@Singleton
ClassService provideClassService() {
return ClassService.Creator.newClassService();
}
@Provides
@Singleton
AnsweredQuestionService provideAnsweredQuestionService() {
return AnsweredQuestionService.Creator.newAnsweredQuestionService();
}
}
我的活动模块:
@Module
public class ActivityModule {
private Activity mActivity;
public ActivityModule(Activity activity) {
mActivity = activity;
}
@Provides
Activity provideActivity() {
return mActivity;
}
}
运行代码后出现错误:
Error:(17, 8) error: [uk.co.ribot.androidboilerplate.injection.component.ActivityComponent.inject(uk.co.ribot.androidboilerplate.ui.AppIntro.AppIntroActivity)] android.content.Context cannot be provided without an @Provides-annotated method.
android.content.Context is injected at
uk.co.ribot.androidboilerplate.ui.AppIntro.AppIntroPresenter.<init>(…, context)
uk.co.ribot.androidboilerplate.ui.AppIntro.AppIntroPresenter is injected at
uk.co.ribot.androidboilerplate.ui.AppIntro.AppIntroActivity.mAppIntroPresenter
uk.co.ribot.androidboilerplate.ui.AppIntro.AppIntroActivity is injected at
uk.co.ribot.androidboilerplate.injection.component.ActivityComponent.inject(appIntroActivity)
我知道当我在 My Presenter 中向构造函数注入添加上下文时,我得到了这个错误,但我不知道为什么?如果我从构造函数中删除上下文:
@Inject
public AppIntroPresenter(DataManager dataManager,Context context) {
mDataManager = dataManager;
ctx1=context;
}
然后一切正常。但我需要注入的上下文。请帮我解决这个问题?
【问题讨论】:
-
其实为什么要在presenter里面放上下文呢?演示者应该告诉视图执行与上下文相关的操作(例如显示 Toast 等)
-
Thanx 矩阵,但我们想要获取保存图像的 uri:Uri photoURI = FileProvider.getUriForFile(getApplicationContext(), getApplicationContext().getPackageName() + ".provider", file);因此,我们需要在 Presenter 中需要应用程序上下文。
-
不,你不这样做是因为你说你想让 Uri 在 Intent 中使用它。因此,当您需要使用 Intent 做某事时,您将告诉视图 addDataToIntent(String filepath) 并在视图中使用 Context 创建它。演示者必须没有从 android.*; 导入。记住这一点,以备将来之需。您可以使用您的模型和演示者,只需更改视图并构建 Web 应用程序。
-
我可以将上下文作为参数从活动传递给演示者吗?
-
Dagger 不知道任何
Context,它只知道@ApplicationContext Context(参见您的模块/组件)。如果你想使用Context,那么你要么需要为你的组件或子组件添加一个未命名/非限定的注释,要么将限定的注释添加到你的构造函数参数并请求应用程序上下文。