Dagger 2.14.1注入Fragment崩溃:No injector was found for fragment
No injector was found for fragment错误 我帮你排查下这个崩溃问题,核心原因是针对AndroidX/Support Fragment的Injector接口实现错误,再加上Fragment初始化逻辑的顺序问题,咱们一步步来修复:
1. 修正Activity和Application的Injector接口
你用的是AndroidX的Fragment(androidx.fragment.app.Fragment),但你的Application和MyRequestActivity都实现了原生的HasFragmentInjector接口——这个接口是给旧版android.app.Fragment用的。对于Support/AndroidX Fragment,必须实现HasSupportFragmentInjector接口,并提供对应的supportFragmentInjector()方法。
修改Application类:
public class Application extends Application implements HasActivityInjector, HasSupportFragmentInjector { @Inject DispatchingAndroidInjector<Activity> androidInjector; @Inject DispatchingAndroidInjector<Fragment> mFragmentInjector; private String androidId; @Override public void onCreate() { super.onCreate(); if (BuildConfig.DEBUG) { Timber.plant(new Timber.DebugTree()); } Stetho.initializeWithDefaults(this); DaggerAppComponent.builder().create(this).inject(this); } public String getAndroidId() { return androidId; } @Override public AndroidInjector<Activity> activityInjector() { return androidInjector; } // 替换原来的fragmentInjector()为supportFragmentInjector() @Override public AndroidInjector<Fragment> supportFragmentInjector() { return mFragmentInjector; } }
修改MyRequestActivity类:
public class MyRequestActivity extends AppCompatActivity implements HasActivityInjector, HasSupportFragmentInjector { @Inject DispatchingAndroidInjector<Activity> mDispatchingAndroidInjector; @Inject DispatchingAndroidInjector<Fragment> mFragmentInjector; @Inject ViewModelProvider.Factory factory; private MyRequestsViewModel myRequestsViewModel; private DataPassingViewModel dataPassingviewModel; @Override protected void onCreate(Bundle savedInstanceState) { AndroidInjection.inject(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_request); ButterKnife.bind(this); myRequestsViewModel = ViewModelProviders.of(this, factory).get(MyRequestsViewModel.class); dataPassingviewModel = ViewModelProviders.of(this).get(DataPassingViewModel.class); } // 替换原来的fragmentInjector()为supportFragmentInjector() @Override public AndroidInjector<Fragment> supportFragmentInjector() { return mFragmentInjector; } @Override public AndroidInjector<Activity> activityInjector() { return mDispatchingAndroidInjector; } }
2. 修复Fragment的onAttach逻辑
你的PendingFragment在onAttach里就调用了rvPending.setLayoutManager(),但此时onCreateView还没执行,rvPending还没被ButterKnife绑定,肯定会空指针!另外,注入操作的顺序也需要调整:
@Override public void onAttach(Context context) { super.onAttach(context); // 先调用super,确保Fragment已经关联到Activity if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { AndroidSupportInjection.inject(this); } this.mContext = context; dataPassingViewModel = ViewModelProviders.of(getActivity()).get(DataPassingViewModel.class); observeOn(); } @SuppressWarnings("deprecation") @Override public void onAttach(Activity activity) { super.onAttach(activity); // 先调用super if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { AndroidSupportInjection.inject(this); } this.mContext = activity; dataPassingViewModel = ViewModelProviders.of(getActivity()).get(DataPassingViewModel.class); observeOn(); } // 把RecyclerView的初始化移到onViewCreated里,此时View已经加载完成 @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); rvPending.setLayoutManager(new LinearLayoutManager(getContext())); rvPending.setNestedScrollingEnabled(true); // 这里也可以初始化Adapter等相关逻辑 }
3. 确认AppComponent和AppModule的配置
确保你的AppComponent正确包含了AppModule,并且AppModule中的@ContributesAndroidInjector配置正确:
@Module abstract class AppModule { // 确认这里指向的是你的PendingFragment @ContributesAndroidInjector abstract PendingFragment pendingFragmentInjector(); // 其他模块注入逻辑... } @Component(modules = {AppModule.class, AndroidInjectionModule.class}) interface AppComponent { void inject(Application app); }
如果PendingFragment有自己的依赖模块,记得在@ContributesAndroidInjector里加上modules参数,比如:
@ContributesAndroidInjector(modules = PendingFragmentModule.class) abstract PendingFragment pendingFragmentInjector();
最后一步:清理重建项目
Dagger的生成代码有时候会缓存过时,执行Build -> Clean Project然后Build -> Rebuild Project,确保所有生成的代码都是最新的。
按照这些步骤修改后,应该就能解决注入失败的问题了!
内容的提问来源于stack exchange,提问作者Sachin Varma

