我在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'
谁能帮我解决这个问题。
答案 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
注释,看来您想注入它。但是由于KotlinTemplateApplication
是Application
,因此您需要在组件上手动执行此操作:
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
中使用内部这对我来说就像是魅力。