ContributesAndroidInjector doesn't work for Fragment inside an Activity
If you have a nested ContributesAndroidInjector then it doesn't work properly. Dagger complains about a missing injector factory. Dagger with code generation works fine, only dagger reflect is crashing.
@Module
public interface ExampleActivityModule {
@ContributesAndroidInjector
ExampleFragment fragment();
}
Full Example here https://github.com/kokeroulis/dagger-reflect/commit/adbd4ab65ffd52847c68c5967d82f6454ba25090
stacktrace
E java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.ExampleActivity}: java.lang.IllegalArgumentException: No injector factory bound for Class<com.example.ExampleFragment>
E at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
E at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
E at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
E at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
E at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
E at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
E at android.os.Handler.dispatchMessage(Handler.java:106)
E at android.os.Looper.loop(Looper.java:193)
E at android.app.ActivityThread.main(ActivityThread.java:6669)
E at java.lang.reflect.Method.git invoke(Native Method)
E at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
E at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
E Caused by: java.lang.IllegalArgumentException: No injector factory bound for Class<com.example.ExampleFragment>
E at dagger.android.DispatchingAndroidInjector.inject(DispatchingAndroidInjector.java:136)
E at dagger.android.AndroidInjection.inject(AndroidInjection.java:181)
E at dagger.android.AndroidInjection.inject(AndroidInjection.java:91)
E at com.example.ExampleFragment.onAttach(ExampleFragment.java:11)
E at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1242)
E at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2426)
E at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2205)
E at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2161)
E at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2062)
E at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3051)
E at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2998)
E at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:182)
E at android.app.Activity.performCreate(Activity.java:7143)
E at android.app.Activity.performCreate(Activity.java:7127)
E at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
E at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
E ... 11 more
Part of the code which reproduces this issue
@Component(modules = {
AndroidInjectionModule.class,
ActivityBindingModule.class
})
interface AppComponent {
void inject(ExampleApp app);
DispatchingAndroidInjector<Object> androidInjector();
}
public final class ExampleActivity extends Activity implements HasAndroidInjector {
@Inject
DispatchingAndroidInjector<Object> androidInjector;
@SuppressLint("SetTextI18n")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().add(new ExampleFragment(), "some tag").commit();
}
@Override
public AndroidInjector<Object> androidInjector() {
return androidInjector;
}
}
@Module
public interface ExampleActivityModule {
@ContributesAndroidInjector
ExampleFragment fragment();
}
public final class ExampleApp extends Application implements HasAndroidInjector {
private AppComponent component;
@Inject
DispatchingAndroidInjector<Object> androidInjector;
@Override
public void onCreate() {
super.onCreate();
component = Dagger.create(AppComponent.class);
component.inject(this);
}
@Override
public AndroidInjector<Object> androidInjector() {
return androidInjector;
}
}
public class ExampleFragment extends Fragment {
@Override
public void onAttach(Context context) {
AndroidInjection.inject(this);
super.onAttach(context);
}
}
@kokeroulis I having similar issue. Did you find a workaround for this?
@obsantos I am using a forked version of this project with custom workarounds. the latest branch is this one https://github.com/kokeroulis/dagger-reflect/commits/atsiap/module_with_generic_try_to_add_workaround_new_fixes
The "workarounds" that are included there might not work for every case, this is why they are just left there instead of opening a PR here but the project in which i am using them is quite big and complicated, so they might be useful for you...
I will upload another branch in a few days which will include fixes for the @IntoMap.. In the above branch there are cases in which the @IntoMap doesn't work...
What about a PR only with this commit . It could make any sense?
It would be great to have this