如何使用 HILT 将 Repository 实例提供到 Firebase 消息传递服务类中

Har*_*abh 10 android dependency-injection kotlin firebase dagger-hilt

我在我的项目中使用 HILT 设置了 DI。现在我必须集成 FCM 推送通知,因此我必须向 Firebase 消息传递服务类提供存储库实例,以便在调用新令牌时将新的 fcm 令牌更新到服务器(从服务类执行 api 调用)。我该如何做到这一点以及最佳实践是什么?

应用程序模块

@Module
@InstallIn(ApplicationComponent::class)
class ApplicationModule {

    @Provides
    @Singleton
    fun provideServiceTokenAuthenticator(sharedPreferences: SharedPreferences,
        @ApplicationContext appContext: Context,chatManager: ChatManager): ServiceTokenAuthenticator =
        ServiceTokenAuthenticator(sharedPreferences, appContext,chatManager)


    @Provides
    @Singleton
    fun provideApiService(okHttpClient: OkHttpClient): ApiService {
        return Retrofit.Builder().baseUrl(BuildConfig.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava3CallAdapterFactory.create()).client(okHttpClient).build()
            .create(ApiService::class.java)
    }

    @Provides
    @Singleton
    fun provideOkHttpClient(serviceTokenAuthenticator: ServiceTokenAuthenticator,sharedPreferences: SharedPreferences): OkHttpClient {
        val loggingInterceptor = HttpLoggingInterceptor()
        loggingInterceptor.level = HttpLoggingInterceptor.Level.HEADERS
        loggingInterceptor.level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE

        return OkHttpClient.Builder().connectTimeout(2, TimeUnit.MINUTES)
            .readTimeout(2, TimeUnit.MINUTES).writeTimeout(2, TimeUnit.MINUTES)
            .addInterceptor(object : Interceptor {
                override fun intercept(chain: Interceptor.Chain): Response {
                    val ongoing = chain.request().newBuilder()
                    sharedPreferences.appLanguage?.let {ongoing.addHeader("Accept-Language", it)  }
                    return chain.proceed(ongoing.build())
                }
            })
            .retryOnConnectionFailure(true).authenticator(serviceTokenAuthenticator)
            .addNetworkInterceptor(StethoInterceptor()).addInterceptor(loggingInterceptor)
            .build()
    }

    @Provides
    @Singleton
    fun provideRepository(apiService: ApiService, sharedPreferences: SharedPreferences,
        chatManager: ChatManager,localeHelper: LocaleHelper): Repository =
        Repository(apiService, sharedPreferences, chatManager,localeHelper)


    @Provides
    fun provideChatManager(@ApplicationContext appContext: Context): ChatManager {
        return ChatManager(appContext)
    }

    @Provides
    @Singleton
    fun provideLocaleHelper(@ApplicationContext appContext: Context): LocaleHelper {
        return LocaleHelper(appContext)
    }


}
Run Code Online (Sandbox Code Playgroud)

在这你可以看到

@Provides
@Singleton
fun provideRepository(apiService: ApiService, sharedPreferences: SharedPreferences,
    chatManager: ChatManager,localeHelper: LocaleHelper): Repository =
    Repository(apiService, sharedPreferences, chatManager,localeHelper)
Run Code Online (Sandbox Code Playgroud)

我需要向 FCM Listener 服务类提供存储库

class FcmListener: FirebaseMessagingService() {
    override fun onNewToken(token: String) {
        super.onNewToken(token)
        Timber.e("Fcm Token $token")
        //how to get repository instance here to make api call?
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        Timber.e("Fcm message data ${remoteMessage.data}")
        Timber.e("Fcm message  ${remoteMessage.notification}")
        Notifier.showNotification(remoteMessage,applicationContext)


    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我已经用剑柄而不是匕首设置了所有内容。这些是使用的依赖项

 // Hilt
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02"
implementation 'com.google.dagger:hilt-android:2.28-alpha'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
kapt 'com.google.dagger:hilt-android-compiler:2.28-alpha'
Run Code Online (Sandbox Code Playgroud)

请帮助实现这一流程。非常感谢您的帮助

Aza*_*mov 14

服务就像刀柄的入口点,因为它们的范围独立于应用程序生命周期。这就是为什么你必须首先制作它们@AndroidEntryPoint

@AndroidEntryPoint
class MyFirebaseNotificationService : FirebaseMessagingService() {
Run Code Online (Sandbox Code Playgroud)

之后你可以像平常一样将你的 Repo 注入其中。但要注意范围,它也应该是 singleComponent。否则无法注入Services内部。所以总体来说:

@AndroidEntryPoint
class FcmListener: FirebaseMessagingService() {

@Inject 
lateinit var repository : Repository

override fun onNewToken(token: String) {
    super.onNewToken(token)
    Timber.e("Fcm Token $token")
    //how to get repository instance here to make api call?
}

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    super.onMessageReceived(remoteMessage)
    Timber.e("Fcm message data ${remoteMessage.data}")
    Timber.e("Fcm message  ${remoteMessage.notification}")
    Notifier.showNotification(remoteMessage,applicationContext)


}
Run Code Online (Sandbox Code Playgroud)

}


小智 1

如果我正确理解你的问题,你需要将一个对象注入到一个不由 Hilt 管理的类中。如果是这种情况,这就是要走的路:https ://developer.android.com/training/dependency-injection/hilt-android#not-supported