简体   繁体   English

Dagger Dagger-MissingBinding]

[英]Dagger Dagger-MissingBinding]

I have a problem with this code and I can't find it.我有这个代码的问题,我找不到它。

Error错误

/home/dashwood/AndroidStudioProjects/DaggerTest2/app/src/main/java/com/dashwood/daggertest/extra/ApplicationComponent.java:16: error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends android.app.Activity>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.app.Activity>>> cannot be provided without an @Provides-annotated method.
public interface ApplicationComponent {
       ^
      java.util.Map<java.lang.Class<? extends android.app.Activity>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.app.Activity>>> is injected at
          com.dashwood.daggertest.di.ActivityInjector(activityInjectors)
      com.dashwood.daggertest.di.ActivityInjector is injected at
          com.dashwood.daggertest.extra.A.activityInjector
      com.dashwood.daggertest.extra.A is injected at
          com.dashwood.daggertest.extra.ApplicationComponent.inject(com.dashwood.daggertest.extra.A)

ActivityInjector.java ActivityInjector.java

public class ActivityInjector {
    private final Map<String, AndroidInjector<? extends Activity>> cache = new HashMap<>();
    private Map<Class<? extends Activity>, Provider<AndroidInjector.Factory<? extends Activity>>> activityInjectors;

    @Inject
    ActivityInjector(Map<Class<? extends Activity>, Provider<AndroidInjector.Factory<? extends Activity>>> activityInjectors) {
        this.activityInjectors = activityInjectors;
    }

    void inject(Activity activity) {
        if (!(activity instanceof BaseActivity)) {
            throw new IllegalArgumentException("Activity must extends BaseActivity");
        }
        String instanceId = ((BaseActivity) activity).getInstanceId();
        if (cache.containsKey(instanceId)) {
            //noinspection unchecked
            ((AndroidInjector<Activity>) cache.get(instanceId)).inject(activity);
            return;
        }
        //noinspection unchecked
        AndroidInjector.Factory<Activity> injectorFactory =
                (AndroidInjector.Factory<Activity>) activityInjectors.get(activity.getClass()).get();
        AndroidInjector<Activity> injector = injectorFactory.create(activity);
        cache.put(instanceId, injector);
        injector.inject(activity);
    }

    void clear(Activity activity) {
        if (!(activity instanceof BaseActivity)) {
            throw new IllegalArgumentException("Activity must extends BaseActivity");
        }
        cache.remove(((BaseActivity) activity).getInstanceId());
    }

    static ActivityInjector get(Context context) {
        return ((A) (context.getApplicationContext())).getActivityInjector();
    }
}

ActivityScope.java活动范围.java

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {

}

ControllerKey.java控制器密钥.java

@MapKey
@Target(ElementType.METHOD)
public @interface ControllerKey {
    Class<? extends Controller> value();
}

Injector.java注入器.java

public class Injector {
    private Injector() {

    }

    public static void inject(Activity activity) {
        ActivityInjector.get(activity).inject(activity);
    }

    public static void clearComponent(Activity activity) {
        ActivityInjector.get(activity).clear(activity);
    }

    public static void inject(Controller controller) {
        ScreenInjector.get(controller.getActivity()).inject(controller);
    }

    public static void clearComponent(Controller controller) {
        ScreenInjector.get(controller.getActivity()).clear(controller);
    }
}

MainScreenBindingModule.java主屏幕绑定模块.java

@Module(subcomponents = {
        TrendingReposComponent.class,
})
public abstract class MainScreenBindingModule {
    @Binds
    @IntoMap
    @ControllerKey(TrendingReposController.class)
    abstract AndroidInjector.Factory<? extends Controller> bindingTrendingReposInjector(TrendingReposComponent.builder builder);

}

ScreenInjector.java屏幕注入器.java


@ActivityScope
public class ScreenInjector {

    private final Map<Class<? extends Controller>, Provider<AndroidInjector.Factory<? extends Controller>>> screenInjector;
    private final Map<String, AndroidInjector<Controller>> cache = new HashMap<>();

    @Inject
    ScreenInjector(Map<Class<? extends Controller>, Provider<AndroidInjector.Factory<? extends Controller>>> screenInjector) {
        this.screenInjector = screenInjector;
    }

    void inject(Controller controller) {
        if (!(controller instanceof BaseController)) {
            throw new IllegalArgumentException("Controller must extends BaseController");
        }
        String instanceId = controller.getInstanceId();
        if (cache.containsKey(instanceId)) {
            Objects.requireNonNull(cache.get(instanceId)).inject(controller);
            return;
        }
        //noinspection unchecked
        AndroidInjector.Factory<Controller> injectFactory =
                (AndroidInjector.Factory<Controller>) Objects.requireNonNull(screenInjector.get(controller.getClass())).get();
        AndroidInjector<Controller> injector = injectFactory.create(controller);
        cache.put(instanceId, injector);
        injector.inject(controller);
    }

    void clear(Controller controller) {
        if (!(controller instanceof BaseController)) {
            throw new IllegalArgumentException("Controller must extends BaseController");
        }
        cache.remove(controller.getInstanceId());
    }

    static ScreenInjector get(Activity activity) {
        if (!(activity instanceof BaseActivity)) {
            throw new IllegalArgumentException("Controller must be hosted BaseActivity");
        }

        return ((BaseActivity) activity).getScreenInjector();
    }
}

ScreenScope.java屏幕范围.java

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ScreenScope {

}

A.java一个.java

public class A extends Application {

    @Inject
    ActivityInjector activityInjector;
    private ApplicationComponent component;

    @Override
    public void onCreate() {
        super.onCreate();
        component = DaggerApplicationComponent.builder()
                .applicationModule(new ApplicationModule(this))
                .build();
        component.inject(this);
    }

    public ActivityInjector getActivityInjector() {
        return activityInjector;
    }
}

ActivityScreenBinding.java ActivityScreenBinding.java

@Module(subcomponents = {
        MainActivityComponent.class,
})
public abstract class ActivityBindingModule {
    @Binds
    @IntoMap
    @ClassKey(MainActivity.class)
    abstract AndroidInjector.Factory<? extends Activity> provideMainActivtyInjector(MainActivityComponent.Builder builder);
}

ApplicationComponent.java应用组件.java

@Singleton
@Component(modules = {
        ApplicationModule.class,
        ActivityBindingModule.class,
})
public interface ApplicationComponent {
    void inject(A myApplication);
}

ApplicationModule.java应用程序模块

@Module
public class ApplicationModule {
    private final Application application;

    public ApplicationModule(Application application) {
        this.application = application;
    }

    @Provides
    Context provideApplicationContext() {
        return application;
    }
}

BaseActivity.java基本活动.java

public abstract class BaseActivity extends AppCompatActivity {
    @Inject
    ScreenInjector screenInjector;
    @Inject
    ScreenNavigator screenNavigator;
    private static final String INSTANCE_ID_KEY = "instance_id";
    private String instanceId;
    private Router router;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            instanceId = savedInstanceState.getString(INSTANCE_ID_KEY);
        } else {
            instanceId = UUID.randomUUID().toString();
        }
        Injector.inject(this);
        ViewGroup screenContainer = findViewById(R.id.screen_container);
        if (screenContainer == null) {
            throw new IllegalArgumentException("Activity must have a view name 'screen_container'");
        }
        router = Conductor.attachRouter(this, screenContainer, savedInstanceState);
        screenNavigator.initWithRouter(router, initialScreen());
        setContentView(layoutRes());
        monitorBackStack();
        super.onCreate(savedInstanceState);
        super.onBackPressed();
    }

    @LayoutRes
    protected abstract int layoutRes();

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(INSTANCE_ID_KEY, instanceId);
    }

    public String getInstanceId() {
        return instanceId;
    }

    protected abstract Controller initialScreen();

    @Override
    public void onBackPressed() {
        if (!screenNavigator.pop()) super.onBackPressed();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        screenNavigator.clear();
        if (isFinishing()) {
            Injector.clearComponent(this);
        }
    }

    public ScreenInjector getScreenInjector() {
        return screenInjector;
    }

    private void monitorBackStack() {
        router.addChangeListener(new ControllerChangeHandler.ControllerChangeListener() {
            @Override
            public void onChangeStarted(@Nullable Controller to, @Nullable Controller from, boolean isPush, @NonNull ViewGroup container, @NonNull ControllerChangeHandler handler) {

            }

            @Override
            public void onChangeCompleted(@Nullable Controller to, @Nullable Controller from, boolean isPush, @NonNull ViewGroup container, @NonNull ControllerChangeHandler handler) {
                if (!isPush && from != null) {
                    Injector.clearComponent(from);
                }
            }
        });
    }
}

BaseController.java基础控制器.java

public abstract class BaseController extends Controller {

    private boolean isInjected = false;

    @Override
    protected void onContextAvailable(@NonNull Context context) {
        if (!isInjected) {
            Injector.inject(this);
            isInjected = true;
        }
        super.onContextAvailable(context);

    }
}

MainActivityComponent.java主活动组件.java

@ActivityScope
@Subcomponent(modules = {
        MainScreenBindingModule.class,
        NavigationModule.class,
})
public interface MainActivityComponent extends AndroidInjector<MainActivity> {
    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity>{
        @Override
        public void seedInstance(MainActivity instance) {

        }
    }
}

TrendingReposComponent.java TrendingReposComponent.java

@ScreenScope
@Subcomponent
public interface TrendingReposComponent extends AndroidInjector<TrendingReposController> {
    @Subcomponent.Builder
    abstract class builder extends AndroidInjector.Builder<TrendingReposController>{

    }
}

TrendingReposController.java TrendingReposController.java

public class TrendingReposController extends BaseController {

    @NonNull
    @Override
    protected View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedViewState) {
        return null;
    }
}

DefaultScreenNavigator.java DefaultScreenNavigator.java

@ActivityScope
public class DefaultScreenNavigator implements ScreenNavigator {

    private Router router;

    @Inject
    DefaultScreenNavigator() {

    }

    @Override
    public void initWithRouter(Router router, Controller rootScreen) {
        this.router = router;
        if (router.hasRootController()) {
            return;
        }
        router.setRoot(RouterTransaction.with(rootScreen));
    }

    @Override
    public boolean pop() {
        return router!=null && router.handleBack();
    }

    @Override
    public void clear() {
        router = null;
    }
}

NavigationModule.java导航模块.java

@Module
public abstract class NavigationModule {
    @Binds
    abstract ScreenNavigator provideScreenNavigator(DefaultScreenNavigator screenNavigator);
}

ScreenNavigator.java屏幕导航器.java

public interface ScreenNavigator {
    void initWithRouter(Router router, Controller rootScreen);

    boolean pop();

    void clear();
}

MainActivity.java主活动.java

public class MainActivity extends BaseActivity {

    @Override
    protected int layoutRes() {
        return R.layout.activity_main;
    }

    @Override
    protected Controller initialScreen() {
        return new TrendingReposController();
    }
}

Gradle摇篮

dependencies {

    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'



    implementation 'com.google.dagger:dagger:2.39.1'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.39.1'
    implementation 'com.google.dagger:dagger-android:2.39.1'
    implementation 'com.google.dagger:dagger-android-support:2.39.1'
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.39.1'

    implementation "com.squareup.retrofit2:retrofit:2.7.1"
    implementation "com.squareup.retrofit2:converter-moshi:2.7.1"

    implementation "com.squareup.moshi:moshi:1.12.0"
    annotationProcessor("com.ryanharter.auto.value:auto-value-moshi-extension:1.1.0")
    implementation("com.ryanharter.auto.value:auto-value-moshi-runtime:1.1.0")
    annotationProcessor("com.ryanharter.auto.value:auto-value-moshi-factory:1.1.0")



    annotationProcessor "com.google.auto.value:auto-value:1.8.2"

    implementation 'io.reactivex.rxjava3:rxjava:3.0.3'
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
    implementation 'com.jakewharton.rxrelay3:rxrelay:3.0.1'

    implementation 'com.bluelinelabs:conductor:3.1.1'


}

I fix that error because AndroidInjector.factory can't extends any class.我修复了这个错误,因为 AndroidInjector.factory 不能扩展任何类。 After that i saw many errors and fix all of them you can see fix this code from my GitHub之后,我看到了许多错误并修复了所有错误,您可以从我的 GitHub 中看到修复此代码

https://github.com/dashwood01/Dagger-Test https://github.com/dashwood01/Dagger-Test

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 得到错误[Dagger / MissingBinding] - Getting the error [Dagger/MissingBinding] 错误:[Dagger / MissingBinding] [dagger.android.AndroidInjector.inject(T)] Dagger - error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] Dagger 错误:尝试构建项目时出现[Dagger / MissingBinding] - error: [Dagger/MissingBinding] when trying building the project 错误:[Dagger/MissingBinding] 错误消息没有意义 - error: [Dagger/MissingBinding] error message doesn't make sense 匕首/缺少绑定。 如果没有@Provides 注释的方法,则无法提供输出器 - Dagger/MissingBinding. Outputter cannot be provided without an @Provides-annotated method 匕首-MissingBinding地图 <Class<? extends ViewModel> ,供应商 <ViewModel> &gt;如果没有@Provides注释的方法,则无法提供 - Dagger - MissingBinding Map<Class<? extends ViewModel>,Provider<ViewModel>> cannot be provided without an @Provides-annotated method 为什么在ViewModelProvider.Factory实现中添加@Singleton批注会导致编译错误[Dagger / MissingBinding]? - Why adding @Singleton annotation to ViewModelProvider.Factory implementation causes a compile error [Dagger/MissingBinding]? 匕首的范围2 - Scopes in Dagger 2 匕首+春天 - Dagger + Spring AndroidAnnotations和Dagger - AndroidAnnotations and Dagger
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM