Dagger 2不提供改造API。

问题描述 投票:0回答:1

我试着用Retrofit和Dagger 2调用API,在我的例子中,DataModel和它的模块被注入得很好,但API的模块却没有。我肯定我错过了什么,但不明白是什么。这是我的组件。

@Singleton
@Component(modules = [SMModule::class, SMNetworkModule::class])
interface SMComponent {

fun inject(fragment: SMListFragment)
}

模块:

@Module
class SMModule {

    @Provides
    fun provideSMModel(): SMListDataModel {
        return SMListDataModel()
    }
}

@Module
object SMNetworkModule {

    @JvmStatic
    @Singleton
    @Provides
    fun provideRetrofit(): Retrofit {
        val okHttpBuilder = OkHttpClient.Builder()
        if (BuildConfig.DEBUG) {
            val httpLoggingInterceptor = HttpLoggingInterceptor()
            httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
            okHttpBuilder.addInterceptor(httpLoggingInterceptor)
        }
        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(okHttpBuilder.build())
            .build()
    }

    @JvmStatic
    @Singleton
    @Provides
    fun provideSMInterface(retrofit: Retrofit): SMInterface =
        retrofit.create(SMInterface::class.java)
}

DataModel:

class SMListDataModel @Inject constructor() {

    @Inject
    lateinit var smApi: SMAPI

    override fun loadData(): DataResponse {
        return smApi.getData().blockingGet()
    }
}

我的API:

@Singleton
class SMAPI @Inject constructor() {

    @Inject
    lateinit var smInterface: SMInterface

    fun getData(): Single<DataResponse> {
        return smInterface.getData()
    }
}

在这里我注入了我的Fragment并调用DataModel:

@JvmField
@Inject
var dataModel: StocksListDataModel? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    DaggerSMComponent.create().inject(this)
}

override fun onResume() {
    super.onResume()
    val response = dataModel?.loadData()
}

然后我得到一个错误:

UninitializedPropertyAccessException: lateinit property smApi has not been initialized.

内的SMListDataModel。

我看了看 这个问题 在那里,我没有看到API的显式构造函数,它对他们来说是有效的。但对我来说却不行。

android kotlin retrofit2 dagger-2
1个回答
0
投票

我使用这个,它的工作原理很好。(提供Room & Retrofit).我希望它是有用的。

RemoteModule类。

@Module(includes = [AppModule::class])
class RemoteModule {

@Provides
@Singleton
fun provideArticleDatabase(application: App): RoomDataBase? {
    return Room.databaseBuilder(
        application.applicationContext,
        RoomDataBase::class.java,
        "fandogh"
    )
        .build()
}


@Provides
fun provideArticleDao(@Nullable articleDatabase: RoomDataBase): ILocalDataSource? {
    return articleDatabase.roomDao()
}

@Provides
@ApplicationScope
fun getApiInterface(retroFit: Retrofit): ApiService {
    return retroFit.create(ApiService::class.java)
}

@Provides
@ApplicationScope
fun getRetrofit(okHttpClient: OkHttpClient): Retrofit {
    return Retrofit.Builder()
        .baseUrl(Constants.BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
 //  .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .client(okHttpClient)
        .build()
}

@Provides
@ApplicationScope
fun getOkHttpCleint(httpLoggingInterceptor: HttpLoggingInterceptor,  myAuthHeaderInterceptor: MyAuthHeaderInterceptor): OkHttpClient {
     return OkHttpClient.Builder()
        .readTimeout(30, TimeUnit.SECONDS)
        .connectTimeout(30, TimeUnit.SECONDS)
        .callTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
    //  .addInterceptor {
    //   var request = it.request().newBuilder().addHeader("authorization", Constants.AUTHORIZATION_HEADER).build()
//       return@addInterceptor it.proceed(request)
 //      }
        .addInterceptor(myAuthHeaderInterceptor)
        .addInterceptor(httpLoggingInterceptor)
        .build()
}

@Provides
@ApplicationScope
fun getHttpLoggingInterceptor(): HttpLoggingInterceptor {
    val httpLoggingInterceptor = HttpLoggingInterceptor()
    httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
    return httpLoggingInterceptor
}

@Singleton
@Provides
fun getAuthHeaderInterceptor(sharedPrefrences: SharedPreferences):  MyAuthHeaderInterceptor {
    return MyAuthHeaderInterceptor(sharedPrefrences)
}

}

ViewModelModule。

@Module
abstract class ViewModelModule {


@Binds
abstract fun bindViewModelFactory(factory: DaggerViewModelFactory): ViewModelProvider.Factory // this needs to be only one for whole app (therefore marked as `@Singleton`)


@Binds
@IntoMap
@ViewModelKey(LoginViewModel::class)
abstract fun loginViewModel(viewModel: LoginViewModel): ViewModel

@Binds
@IntoMap
@ViewModelKey(ActMainViewModel::class)
abstract fun mainActivityViewModel(viewModel: ActMainViewModel): ViewModel

}

FragmentBuilder。

@Module
abstract class FragmentBuilder {



@FragmentScope
@ContributesAndroidInjector
abstract fun homeFragment(): HomeFragment?

}

ActivityBuilder:活动生成器。

@Module
abstract class ActivityBuilder {

@ActivityScope
@ContributesAndroidInjector
abstract fun loginActivity(): ActivityLogin?

@ActivityScope
@ContributesAndroidInjector
abstract fun mainActivity(): MainActivity?
}

AppModule:AppModule:ActivityBuilder:AppModule。

@Module
abstract class AppModule {

@Binds
@Singleton
abstract fun application(app: App?): Application?
}

ActivityScope : ActivityScope:ActivityBuilder:AppModule:AppModule。

@Scope
@Retention(value = AnnotationRetention.RUNTIME)
annotation class ActivityScope

FragmentScope : FragmentScope :

@Scope
@Retention(value = AnnotationRetention.RUNTIME)
annotation class FragmentScope {
 }

AppComponent:AppComponent。

@Singleton
@ApplicationScope
@Component(
modules = [AppModule::class, AndroidSupportInjectionModule::class, RemoteModule::class, ActivityBuilder::class,
    FragmentBuilder::class, ViewModelModule::class]
)
 interface AppComponent : AndroidInjector<App> {

fun inject(membersFragment: MembersFragment)

override fun inject(myApplication: App)

fun inject(instance: DaggerApplication)

@Component.Builder
interface Builder {

    @BindsInstance
    fun application(application: App): Builder

    fun build(): AppComponent


}
}

应用程序。

class App : DaggerApplication() {

 var appComponent: AppComponent? = null

override fun applicationInjector(): AppComponent {
    appComponent = DaggerAppComponent.builder().application(this).build()
    appComponent!!.inject(this)
    return appComponent!!
}
 }

并在ViewModel中使用。

class LoanViewModel @Inject constructor() : ViewModel() {

@Inject
lateinit var apiService: ApiService

  }
© www.soinside.com 2019 - 2024. All rights reserved.