我很擅长使用dagger2。我收到java.lang.IllegalArgumentException:没有为Class NotificationsFragment绑定的注入器工厂,并查看了多个示例项目,似乎无法找到解决方案
FriendAlertApplication.kt
class FriendAlertApplication : Application(), HasActivityInjector{
@Inject lateinit var activityDispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
override fun onCreate() {
super.onCreate()
DaggerApplicationComponent
.builder()
.application(this)
.build()
.inject(this)
setupTimber()
}
private fun setupTimber() {
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
}
override fun activityInjector(): AndroidInjector<Activity> {
return activityDispatchingAndroidInjector
}
}
ApplicationComponent.kt
@Component(modules = arrayOf( ActivityBuilderModule::class,
ApplicationModule::class,
AndroidSupportInjectionModule::class))
interface ApplicationComponent {
@Component.Builder
interface Builder {
@BindsInstance fun application(application: Application): Builder
fun build(): ApplicationComponent
}
fun inject(app: FriendAlertApplication)
}
ApplicationModule.kt
@Module(subcomponents = arrayOf(HomeActivitySubComponent::class,
TestActivitySubComponent::class))
open class ApplicationModule {
@Provides
@PerApplication
fun provideContext(application: Application): Context {
return application
}
}
ActivityBuilderModule.kt
@Module
abstract class ActivityBuilderModule {
@PerActivity
@ContributesAndroidInjector(modules = arrayOf(HomeActivityModule::class))
abstract fun bindHomeActivity(): HomeActivity
@PerActivity
@ContributesAndroidInjector(modules = arrayOf(TestActivityModule::class))
abstract fun bindTestActivity(): TestActivity
}
HomeActivitySubComponent.kt
@Subcomponent(modules = arrayOf(HomeActivityModule::class,
FragmentBuilderModule::class))
interface HomeActivitySubComponent : AndroidInjector<HomeActivity> {
@Subcomponent.Builder
abstract class Builder : AndroidInjector.Builder<HomeActivity>()
}
NotificationsFragmentSubComponent.kt
@Subcomponent(modules = arrayOf(NotificationsFragmentModule::class))
interface NotificationsFragmentSubComponent :
AndroidInjector<NotificationsFragment> {
@Subcomponent.Builder
abstract class Builder : AndroidInjector.Builder<NotificationsFragment>()
}
HomeActivityModule.kt
@Module
abstract class HomeActivityModule {
}
FragmentBuilderModule.kt
@Module
abstract class FragmentBuilderModule {
@PerFragment
@ContributesAndroidInjector(modules = arrayOf(NotificationsFragmentModule::class))
abstract fun bindNotificationsFragment(): NotificationsFragment
}
NotificationsFragmentModule.kt
@Module
abstract class NotificationsFragmentModule {
@PerFragment
@Provides
internal fun provideNotificationView(notificationsFragment:
NotificationsFragment): NotificationsContract.View {
return notificationsFragment
}
@PerFragment
@Provides
internal fun provideNotificationsPresenter(mainView: NotificationsContract.View,
getNotifications: GetNotifications, mapper: NotificationMapper):
NotificationsContract.Presenter {
return NotificationsPresenter(mainView, getNotifications, mapper)
}
}
HomeActivity.kt
class HomeActivity : AppCompatActivity(), HasSupportFragmentInjector, BottomNavigationView.OnNavigationItemSelectedListener {
@Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
private var bottomNavigationView: BottomNavigationView? = null
private var containerLayout : FrameLayout? = null
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNavigationView)
containerLayout = findViewById<FrameLayout>(R.id.containerLayout);
bottomNavigationView?.setOnNavigationItemSelectedListener(this)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when(item.itemId){
R.id.menu_broadcast ->
Log.d("","")
R.id.menu_myplace ->
Log.d("","")
R.id.menu_friends ->
Log.d("","")
R.id.menu_notifications -> switchToNotificationsFragment()
}
return true
}
fun switchToNotificationsFragment() {
val manager = supportFragmentManager
manager.beginTransaction().replace(R.id.containerLayout, NotificationsFragment().instantiate(Bundle())).commit()
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
return fragmentDispatchingAndroidInjector
}
}
NotificationFragment.kt
class NotificationsFragment : Fragment(), NotificationsContract.View {
@Inject lateinit var notificationsPresenter : NotificationsContract.Presenter
@Inject lateinit var notificationsAdapter : NotificationsAdapter
@Inject lateinit var mapper : NotificationMapper
private var notificationsRecyclerView: RecyclerView? = null
override fun setPresenter(presenter: NotificationsContract.Presenter) {
notificationsPresenter = presenter;
}
fun instantiate(@Nullable arguments: Bundle): NotificationsFragment {
val notificationsFragment = NotificationsFragment()
notificationsFragment.setArguments(arguments)
return notificationsFragment
}
override fun showProgress() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun hideProgress() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun showNotifications(notifications: List<NotificationView>) {
notificationsAdapter.notifications = notifications.map { mapper.mapToViewModel(it) }
notificationsAdapter.notifyDataSetChanged()
notificationsRecyclerView?.visibility = View.VISIBLE
}
override fun hideNotifications() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun showErrorState() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun hideErrorState() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun showEmptyState() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun hideEmptyState() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
var view = inflater!!.inflate(R.layout.fragment_notifications, container, false)
notificationsRecyclerView = view.findViewById<RecyclerView>(R.id.notificationsRecyclerView)
setupNotificationsRecyclerView()
return view;
}
override fun onAttach(context: Context?) {
AndroidSupportInjection.inject(this)
super.onAttach(context)
}
override fun onStart() {
super.onStart()
notificationsPresenter.start()
}
private fun setupNotificationsRecyclerView() {
notificationsRecyclerView?.layoutManager = LinearLayoutManager(context)
notificationsRecyclerView?.adapter = notificationsAdapter
}
}