web-dev-qa-db-ja.com

java.lang.IllegalArgumentException:Class <MyActivity_>にバインドされたインジェクターファクトリがありません

私が持っているエラーは次のとおりです:

原因:Java.lang.IllegalArgumentException:クラスにバインドされたインジェクターファクトリがありません。インジェクターファクトリは、MyActivity_:[MyActivity]のスーパータイプにバインドされていました。サブタイプのインジェクターファクトリをバインドするつもりでしたか?

私が理解しているように、それはAndroidAnnotationsライブラリを使用しているために起こります。

AppComponent.class

@Singleton
@Component(modules = {
    AndroidInjectionModule.class,
    AppModule.class,
    ActivityBindingModule.class })
public interface AppComponent extends AndroidInjector<DaggerApplication> {

    @Component.Builder
    interface Builder {
         @BindsInstance Builder application(Application application);
         AppComponent build();
    }

    void inject(Application application);

    @Override
    void inject(DaggerApplication instance);
}

AppModule.class

@Module
public abstract class AppModule {

    @Binds
    abstract Context provideContext(Application application);

    @Provides
    @Singleton
    static SharedPreferencesManager providesPreferences(Application application){
        return SharedPreferencesManager_.getInstance_(application);
    }
}

ActivityBindingModule.class

@Module
public abstract class ActivityBindingModule {

    @ContributesAndroidInjector(modules = LoginActivityModule.class)
    @LoginActivityScope
    abstract LoginActivity bindLoginActivity();
}

Application.class

@EApplication
public class Application extends DaggerApplication {

    @Inject
    DispatchingAndroidInjector<Activity> activityDispatchingAndroidInjector;

    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        AppComponent appComponent = DaggerAppComponent.builder()
            .application(this)
            .build();

        appComponent.inject(this);
        return appComponent;
    }
}

LoginActivityModule.class

@Module
public class LoginActivityModule {

    @Provides
    @LoginActivityScope
    @ActivityContext
    public Context providesContext(LoginActivity loginActivity){
        return loginActivity;
    }

    @Provides
    @LoginActivityScope
    public LoginViewModel providesLoginViewModel(TelephonyManager telephonyManager,
                                             LoginModel loginModel,
                                             SharedPreferencesManager sharedPreferencesManager,
                                             LoginRemoteRepository loginRemoteRepository){
        return new LoginViewModel(telephonyManager, loginModel, sharedPreferencesManager, loginRemoteRepository,
            new CompositeSubscription());
    }

    @Provides
    @LoginActivityScope
    public LoginRemoteRepository providesRemoteRepository(@ActivityContext Context context,
                                                      MainApi mainApi,
                                                      SharedPreferencesManager sharedPreferencesManager){
        return new LoginRemoteRepository(mainApi, sharedPreferencesManager, context.getContentResolver());
    }

    @Provides
    @LoginActivityScope
    public LoginModel provideLoginModel(){
        return new LoginModel();
    }

    @Provides
    @LoginActivityScope
    public TelephonyManager provideTelephonyManager(Context context){
        return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    }
}

LoginActivity.class

@EActivity(R.layout.activity_login)
public class LoginActivity {

    @Inject
    LoginViewModel loginViewModel;

    @AfterViews
    void afterViews(){
        AndroidInjection.inject(this);
    }
}
8
aleksandrbel

十分な情報に基づく推測:AndroidAnnotationsを使用すると、クラスが実際に別の方法で呼び出されるために発生する可能性があります(アンダースコアがどこかに追加されています)。次に、同様にバインディングを定義する必要があります(アンダースコアがどこにあるかわかりません)。

@ContributesAndroidInjector(modules = LoginActivityModule_.class)
@LoginActivityScope
abstract LoginActivity bindLoginActivity();
2
Hendrik Marx

Dagger 2エラーの処理方法:「インジェクタファクトリは...のスーパータイプにバインドされました。サブタイプのインジェクタファクトリをバインドすることを意味しましたか?」

  1. いくつかのBaseActivityがあるとします。

    open class BaseActivity : MvpAppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
        }
    }
    

また、ActivityBuilderモジュール(BaseActivity自体を提供する)もあり、BaseActivityを正常に実行するために必要な依存関係を提供するモジュールもあります。

@Module
abstract class ActivityBuilder {
    @ContributesAndroidInjector(modules = [BaseModule::class])
    abstract fun bindBaseActivity(): BaseActivity
}
  1. そのようなChildActivityを追加する場合

    クラスChildActivity:BaseActivity(){}

「ねえ、ダガー2はBaseActivityの依存関係を満たし、それを拡張しているので、ChildActivityを起動して実行しますよね?」違う。 「インジェクタファクトリがスーパータイプの...にバインドされました...サブタイプのインジェクタファクトリをバインドするつもりでしたか?」という例外が発生します。

  1. 何をすべきか? Dagger 2にChildActivityを明示的に知らせます。

a)AndroidInjection.inject(this)をChildActivity onCreate()メソッドに追加します。

class ChildActivity : BaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
    }
}

b)BaseActivityのすべてのサブクラスをActivityBuilderモジュール(アクティビティを提供する)に追加します。 BaseActivityの依存関係を満たすBaseModuleも、子クラス(ChildActivity)の@ContributesAndroidInjectorに含める必要があることに注意してください。

@Module
abstract class ActivityBuilder {
    @ContributesAndroidInjector(modules = [BaseModule::class])
    abstract fun bindBaseActivity(): BaseActivity

    //Adding subclasses
    @ContributesAndroidInjector(modules = [BaseModule::class])
    abstract fun bindChildActivity(): ChildActivity
}
3
Alex Burov