匕首匕首- missing binding]



这段代码有问题,我找不到它。

误差

/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

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

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

ControllerKey.java

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

Injector.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

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

ScreenInjector.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

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

A.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

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

ApplicationComponent.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

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

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

@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

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

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

@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

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

ScreenNavigator.java

public interface ScreenNavigator {
void initWithRouter(Router router, Controller rootScreen);
boolean pop();
void clear();
}

MainActivity.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'

}

我修复了这个错误,因为AndroidInjector。工厂不能扩展任何类。在那之后,我看到了许多错误并修复了所有这些错误,你可以看到从我的GitHub

修复这段代码https://github.com/dashwood01/Dagger-Test

最新更新