lateinit属性dispatchAndroidInjector尚未初始化

时间:2018-11-07 18:34:21

标签: android kotlin dagger-2

我在dagger2中运行片段时收到上述错误“ lateinit属性dispatchingAndroidInjector尚未初始化”
以上错误是在

下面的应用程序类中触发的

KotlinTemplateApplication.kt

     class KotlinTemplateApplication:Application(), HasActivityInjector  {
        lateinit var retroComponent:RetroComponent

@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>

companion object {
    @get:Synchronized
    lateinit var instance: KotlinTemplateApplication
     private set
}

override fun onCreate() {
    super.onCreate()
    instance = this
    retroComponent = DaggerRetroComponent.builder().retroModule(RetroModule(APIURL.BASE_URL)).build()
    //retroComponent.inject()

}



   fun fetchRetroComponent():RetroComponent{
   return retroComponent
   }

override fun activityInjector(): AndroidInjector<Activity> {
    return dispatchingAndroidInjector
}
   }


我的Fragment类如下:
我在片段的onAttach()方法中调用了与匕首相关的代码:

RetroDIFragment:

      class RetroDIFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
lateinit var retroDIListViewModel: RetroDIListViewModel
lateinit var retroFitDIView: View
@Inject
lateinit var apiService: APIService

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    arguments?.let {
        param1 = it.getString(ARG_PARAM1)
        param2 = it.getString(ARG_PARAM2)
    }
    retroDIListViewModel = ViewModelProviders.of(activity!!).get(RetroDIListViewModel::class.java)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    retroFitDIView =  inflater.inflate(R.layout.fragment_retro_di, container, false)

    return retroFitDIView
}

override fun onAttach(context: Context?) {
    super.onAttach(context)
    AndroidInjection.inject(activity)
    KotlinTemplateApplication.instance.fetchRetroComponent().inject(this@RetroDIFragment)

    retroDIListViewModel.fetchPostsFromWebSevice(apiService).observe(this,object : Observer<List<RetroModel>>{
        override fun onChanged(t: List<RetroModel>?) {
            for (i in t!!.indices)
                println(t[i].id)
        }

    })
}
companion object {
    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment RetroDIFragment.
     */
    // TODO: Rename and change types and number of parameters
    @JvmStatic
    fun newInstance(param1: String, param2: String) =
            RetroDIFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
}
    }


我的组件如下:

RetroComponent:

 @Singleton
@Component(modules = arrayOf(RetroModule::class))
  interface RetroComponent {
    fun inject(retroDIFragment: RetroDIFragment)
   }


我的模块如下:

 @Module
   public class RetroModule(var urlPath:String) {


init{
    this.urlPath  = urlPath
}

@Singleton
@Provides
fun provideServiceAPI(retrofit: Retrofit):APIService{
    return retrofit.create(APIService::class.java)
}

@Singleton
@Provides
fun provideRetrofit():Retrofit{
    val retrofit = Retrofit.Builder()
            .baseUrl(urlPath)
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .client(providesOkHttpClientBuilder())
            .build()
    return  retrofit

}


private fun providesOkHttpClientBuilder(): OkHttpClient {

    val httpClient = OkHttpClient.Builder()
    return httpClient.readTimeout(1200, TimeUnit.SECONDS)
            .connectTimeout(1200, TimeUnit.SECONDS).build()

}
}


我的活动如下

class RetroFitActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_retro_fit)
    supportFragmentManager.beginTransaction().replace(R.id.container_retro_di, RetroDIFragment()).commit()
}
   }


我在Gradle中添加了以下代码:

 implementation 'com.google.dagger:dagger:2.19'
implementation 'com.google.dagger:dagger-android:2.19'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.19'
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
kapt 'com.google.dagger:dagger-android-processor:2.19'
kapt 'com.google.dagger:dagger-compiler:2.19'
//moxy
compile 'com.arello-mobile:moxy-app-compat:1.1.1'
kapt 'com.arello-mobile:moxy-compiler:1.1.1'




谁能帮我解决这个问题。

5 个答案:

答案 0 :(得分:1)

我在Dagger2.26v中遇到了相同的问题, 修理 , 确保ApplicationComponent extends AndroidInjector<SampleApplication>喜欢 这个:

@Singleton
@Component(modules = AndroidInjectionModule::class)
interface ApplicationComponent : AndroidInjector<SampleApplication> { …}

答案 1 :(得分:0)

dispatchingAndroidInjector属性必须最终设置。

@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>

@Inject注释,看来您想注入它。但是由于KotlinTemplateApplicationApplication,因此您需要在组件上手动执行此操作:

retroComponent.inject(this@KotlinTemplateApplication)

答案 2 :(得分:0)

要在片段中使用匕首,必须在KotlinTemplateApplication中添加DispatchingAndroidInjector <Fragment>

编辑KotlinTemplateApplication

class KotlinTemplateApplication : Application() , HasActivityInjector, HasSupportFragmentInjector {


    @Inject lateinit var activityInjector: DispatchingAndroidInjector<Activity>


    @Inject lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment>



    override fun onCreate() {
        super.onCreate()

                ........

        DaggerAppComponent.builder().application(this).build().inject(this)

                .........
    }




    override fun activityInjector(): AndroidInjector<Activity> = activityInjector

    override fun supportFragmentInjector(): AndroidInjector<Fragment> = fragmentInjector

}

您还可以为Fragments创建一个特殊的模块,然后将其添加到RetroComponent接口

@Component(modules = arrayOf(RetroModule :: class,FragmentModule :: class)

@Module
abstract class FragmentModule {
    @ContributesAndroidInjector
    internal abstract fun contributeRetroDIFragment(): RetroDIFragment
}

然后在片段RetroDIFragment中

class RetroDIFragment : Fragment() {
    ......

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        retroFitDIView =  inflater.inflate(R.layout.fragment_retro_di, container, false)

        return retroFitDIView
    }

   .........

    /*---------------- Dagger Injection for Fragment -------------*/
    @Override
    override fun onAttach(context: Context?) {
        AndroidSupportInjection.inject(this)
        super.onAttach(context);
    }

}

答案 3 :(得分:0)

您需要更改AppComponent类的注入方法参数:

@Singleton
@Component(modules = [
        AndroidInjectionModule::class,
        ActivityModule::class,
        AppModule::class
])
interface AppComponent {

        @Component.Builder
        interface Builder {
                @BindsInstance
                fun application(application: Application): Builder

                fun build(): AppComponent
        }

        fun inject(app: Application) // This is the piece of code you need to change
}
@Singleton
@Component(modules = [
        AndroidInjectionModule::class,
        ActivityModule::class,
        AppModule::class
])
interface AppComponent {

        @Component.Builder
        interface Builder {
                @BindsInstance
                fun application(application: Application): Builder

                fun build(): AppComponent
        }

        fun inject(app: YourCustomAppClass) // Change to your custom app class
}

此外,您在哪里进行此操作

  DaggerAppComponent
            .builder()
            .application(yourAppInstance)
            .build()
            .inject(yourAppInstance)

yourAppInstance必须是YourCustomApp类类型,而不是Application类型。

答案 4 :(得分:0)

这可能为时已晚,但这对我有用...

@set:Inject
internal var activityDispatchingAndroidInjector:DispatchingAndroidInjector<Activity>? = null

删除 lateinit 并在 @set:Inject 而不是 @Inject

中使用内部

这对我来说就像是魅​​力。