Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 匕首2作用域活动上下文问题_Android_Dependency Injection_Dagger 2_Android Mvp - Fatal编程技术网

Android 匕首2作用域活动上下文问题

Android 匕首2作用域活动上下文问题,android,dependency-injection,dagger-2,android-mvp,Android,Dependency Injection,Dagger 2,Android Mvp,我正在尝试跟随一个MVP/Dagger2/RxJava项目 我无法将活动上下文注入到我的演示者中,因为我知道子组件具有对所有父级提供的逻辑的开放访问权限,所以每一次注入都会通过 应用程序组件是在应用程序类中构建的,然后在基本presenter活动中访问,然后注入presenter和其余部分的相关依赖项。配置持久性组件主要用于保存演示者状态 如果我只是手动将活动中的上下文传递给演示者,那么DI的目的就失败了 我已经尝试将作用域添加到所有组件和模块,以确保可以从图中正确访问依赖项,但是这没有起作用

我正在尝试跟随一个MVP/Dagger2/RxJava项目

我无法将活动上下文注入到我的演示者中,因为我知道子组件具有对所有父级提供的逻辑的开放访问权限,所以每一次注入都会通过

应用程序组件是在应用程序类中构建的,然后在基本presenter活动中访问,然后注入presenter和其余部分的相关依赖项。配置持久性组件主要用于保存演示者状态

如果我只是手动将活动中的上下文传递给演示者,那么DI的目的就失败了

我已经尝试将作用域添加到所有组件和模块,以确保可以从图中正确访问依赖项,但是这没有起作用

我试图使用上下文的构造函数注入,实际上我在演示者与之通信的活动中接收到上下文,但演示者没有,因此引发了一个错误。所以我想知道为什么活动可以访问活动上下文,而演示者却不能

任何指导都将不胜感激

错误

应用模块

配置持久组件

活动组件

活动模块

应用程序类

主讲人

/**********编辑**********/

为了帮助保存演示者的状态并允许传入活动上下文,我的解决方案发布在下面。欢迎任何反馈

     @ActivityContext
    public class LoginActivityPresenter extends BasePresenter<LoginContract.View> {

      Context context;

      @Inject
      LoginStateHolder loginStateHolder;

      @Inject
      public LoginActivityPresenter(Context context, Gson gson) {
        this.context = activity;
        this.gson = gson;
      }
}

@ConfigPersistent
public class LoginStateHolder {

  String title;

  @Inject
  public LoginStateHolder(Context context) {
    title = "Save me";
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getTitle() {
    return title;
  }
}
登录活动演示者

@ActivityContext
public class LoginActivityPresenter extends BasePresenter<LoginContract.View> {

  @Inject LoginPresenterStorage loginPresenterStorage;

  Gson gson;

  @Inject
  public LoginActivityPresenter(Activity activity, Gson gson) {
    this.context = activity;
    this.gson = gson;
  }
}
应用程序组件

@Singleton
@Component(modules = {ApplicationModule.class, BusModule.class, PrefsModule.class, NetModule.class})
public interface ApplicationComponent {

    @ApplicationContext Context context();
    Application application();
    EventBus bus();
    SharedPreferences prefs();
    Gson gson();

}
@ActivityContext
@Subcomponent(modules = ActivityModule.class)
public interface ActivityComponent {

  void inject(LoginActivity loginActivity);

}
@ConfigPersistent
@Component(dependencies = ApplicationComponent.class)
public interface ConfigPersistentComponent {

  ActivityComponent plus(ActivityModule activityModule);

}
活动组件

@Singleton
@Component(modules = {ApplicationModule.class, BusModule.class, PrefsModule.class, NetModule.class})
public interface ApplicationComponent {

    @ApplicationContext Context context();
    Application application();
    EventBus bus();
    SharedPreferences prefs();
    Gson gson();

}
@ActivityContext
@Subcomponent(modules = ActivityModule.class)
public interface ActivityComponent {

  void inject(LoginActivity loginActivity);

}
@ConfigPersistent
@Component(dependencies = ApplicationComponent.class)
public interface ConfigPersistentComponent {

  ActivityComponent plus(ActivityModule activityModule);

}
ConfigPersistentComponent

@Singleton
@Component(modules = {ApplicationModule.class, BusModule.class, PrefsModule.class, NetModule.class})
public interface ApplicationComponent {

    @ApplicationContext Context context();
    Application application();
    EventBus bus();
    SharedPreferences prefs();
    Gson gson();

}
@ActivityContext
@Subcomponent(modules = ActivityModule.class)
public interface ActivityComponent {

  void inject(LoginActivity loginActivity);

}
@ConfigPersistent
@Component(dependencies = ApplicationComponent.class)
public interface ConfigPersistentComponent {

  ActivityComponent plus(ActivityModule activityModule);

}
活动模块

@ConfigPersistent
public class LoginPresenterStorage {

  private String test = "";

    @Inject
  public LoginPresenterStorage(Activity activity) {
    test = "I didn't die";
  }

  public String getTest() {
    return test;
  }
}
@Module
public class ActivityModule {

  private Activity activity;

  public ActivityModule(Activity activity) {
    this.activity = activity;
  }

  @Provides
  @ActivityContext
  Activity providesActivity() {
    return activity;
  }

}
编辑

@Singleton
@Component(modules = {ApplicationModule.class, BusModule.class, PrefsModule.class, NetModule.class})
public interface ApplicationComponent {

    @ApplicationContext Context context();
    Application application();
    EventBus bus();
    SharedPreferences prefs();
    Gson gson();

}
@ActivityContext
@Subcomponent(modules = ActivityModule.class)
public interface ActivityComponent {

  void inject(LoginActivity loginActivity);

}
@ConfigPersistent
@Component(dependencies = ApplicationComponent.class)
public interface ConfigPersistentComponent {

  ActivityComponent plus(ActivityModule activityModule);

}
我犯了一个错误,即在活动模块中使用了相同的活动上下文。因此,我无法将活动注入演示者。将活动模块更改为原始@peractivity范围并遵循下面的答案将使活动上下文可注入。

@ConfigPersistent
@ConfigPersistent
public class LoginActivityPresenter extends BasePresenter<LoginContract.View> {
公共类LoginActivityPresenter扩展BasePresenter{
通过将LoginActivityPresenter标记为@ConfigPersistent scope,您告诉Dagger“在ConfigPersistentComponent中管理此类的实例”(即始终从给定的ConfigPersistentComponent实例返回相同的实例),这意味着它不应该从更窄的范围(如@ActivityScope)访问任何内容。毕竟,ConfigPersistentComponent将比ActivityComponent更有效,因此向LoginPresenter注入一个活动没有意义:按照现在的方式,您将使用不同的活动获得相同的LoginPresenter实例

消息“android.app.Activity无法在没有@Inject构造函数的情况下提供”来自ConfigPersistentComponent的生成,该组件没有活动绑定。当然,您的ActivityComponent有活动绑定,但这不是它试图使用当前批注存储LoginPresenter的位置

将该声明切换到@ActivityScope,一切都会好起来:您将为创建的每个活动获得不同的LoginActivityPresenter,并且您还可以访问@Singleton scope(ApplicationComponent)和@ConfigPersistent scope(ConfigPersistentComponent)中的所有内容

@ActivityScope
公共类LoginActivityPresenter扩展BasePresenter{
@ConfigPersistent
公共类LoginActivityPresenter扩展BasePresenter{
通过将LoginActivityPresenter标记为@ConfigPersistent scope,您告诉Dagger“在ConfigPersistentComponent中管理此类的实例”(即始终从给定的ConfigPersistentComponent实例返回相同的实例),这意味着它不应该从更窄的范围(如@ActivityScope)访问任何内容。毕竟,ConfigPersistentComponent将比ActivityComponent更有效,因此向LoginPresenter注入一个活动没有意义:按照现在的方式,您将使用不同的活动获得相同的LoginPresenter实例

消息“android.app.Activity无法在没有@Inject构造函数的情况下提供”来自ConfigPersistentComponent的生成,该组件没有活动绑定。当然,您的ActivityComponent有活动绑定,但这不是它试图使用当前批注存储LoginPresenter的位置

将该声明切换到@ActivityScope,一切都会好起来:您将为创建的每个活动获得不同的LoginActivityPresenter,并且您还可以访问@Singleton scope(ApplicationComponent)和@ConfigPersistent scope(ConfigPersistentComponent)中的所有内容

@ActivityScope
公共类LoginActivityPresenter扩展BasePresenter{

Hi Jeff,现在可以了,但是我在保存演示者以进行配置更改时遇到了一个问题,没有活动注入的原始示例可以很好地存储演示者以供重复使用并保存状态。但是,通过使用更窄的范围,每次都会为同一个活动创建演示者。如果我处理错了,我只是不知道我甚至不知道我的演示者是否需要一个活动上下文,特别是如果它必须比活动寿命长的话。当我分离演示者时,我总是可以删除上下文。也许我应该改用应用程序上下文,你对此有何想法?你需要在这里决定实例的角色。存储生命之外状态的片段一个活动的演示者不应该注入该活动,因此如果您删除该上下文引用,您可以继续。另一方面,演示者通常有特定于活动的实现,因此您可能也需要一些密切协作的活动范围演示者,或者您的LoginActivityPresenter保持活动范围,您可以创建一个配置igPersistent holder用于其持久数据。无论哪种方法都可以,您只需要决定哪种方法最适合您的需要。我如何创建ConfigPersistent ho
@ConfigPersistent
@Component(dependencies = ApplicationComponent.class)
public interface ConfigPersistentComponent {

  ActivityComponent plus(ActivityModule activityModule);

}
@Module
public class ActivityModule {

  private Activity activity;

  public ActivityModule(Activity activity) {
    this.activity = activity;
  }

  @Provides
  @ActivityContext
  Activity providesActivity() {
    return activity;
  }

}
@ConfigPersistent
public class LoginActivityPresenter extends BasePresenter<LoginContract.View> {
@ActivityScope
public class LoginActivityPresenter extends BasePresenter<LoginContract.View> {