如何使用 Dagger 2 向 MyFirebaseMessagingService 提供数据库,以便我可以在 android 本地存储 fcm 消息
Posted
技术标签:
【中文标题】如何使用 Dagger 2 向 MyFirebaseMessagingService 提供数据库,以便我可以在 android 本地存储 fcm 消息【英文标题】:How to provide database to MyFirebaseMessagingService using Dagger 2 so that I can store fcm message locally in android 【发布时间】:2018-12-03 16:17:47 【问题描述】:我怎样才能将数据库实例传递给扩展FirebaseMessagingService
的MyFirebaseMessagingService
类,以便我可以在本地保存data
有效负载?
注意:我已经在我的应用中设置了 dagger 2,它运行良好。
下面是MyFirebaseMessagingService
类:
class MyFirebaseMessagingService @Inject constructor(exampleOneDao: ExampleOneDao?) : FirebaseMessagingService()
override fun onMessageReceived(remoteMessage: RemoteMessage?)
//need db instance to store data payload locally (Room)
下面是匕首2的AppModule
类
@Module(includes = arrayOf(ViewModelModule::class))
class AppModule()
// --- DATABASE INJECTION ---
@Provides
@Singleton
internal fun provideDatabase(application: Application): MyDatabase
return Room.databaseBuilder(application,
MyDatabase::class.java, "MyDatabase.db")
.build()
@Provides
@Singleton
internal fun provideExampleOneDao(database: MyDatabase): ExampleOneDao
return database.exampleOneDao()
@Provides
@Singleton
internal fun provideMyFirebaseMessagingService(exampleOneDao:
ExampleOneDao): MyFirebaseMessagingService
return MyFirebaseMessagingService(exampleOneDao)
是否可以为MyFirebaseMessagingService
类提供数据库和dao?
我尝试上述方法将exampleOneDao
提供给MyFirebaseMessagingService
类,但它抛出了以下Exception
MyFirebaseMessagingService: java.lang.InstantiationException: java.lang.Class<com.example.user.app.firebase.messaging.MyFirebaseMessagingService> has no zero argument constructor
谢谢。
【问题讨论】:
为什么不可能?你试过了吗? 是的,我试过了,但是它抛出了实例化异常。打算用我试过但没有成功的方法更新发布的代码 ***.com/questions/37052261/… 没有。自己做。关于这个主题有很多例子可以找到 @TimCastelijns 感谢您激励我寻找解决方案,我最终得到了很好的解决方案并且学习曲线很好。 【参考方案1】:使用 Dagger 将依赖项注入服务必须通过公共类变量,而不是来自构造函数,以避免类型错误MyFirebaseMessagingService 没有零参数构造函数。 p>
实施solution 通行证后
发件人:
class MyFirebaseMessagingService @Inject constructor(exampleOneDao: ExampleOneDao?) : FirebaseMessagingService()
override fun onMessageReceived(remoteMessage: RemoteMessage?)
//need db instance to store data payload locally (Room)
收件人:
class MyFirebaseMessagingService : FirebaseMessagingService()
@Inject
private lateinit var exampleOneDao: ExampleOneDao?
override fun onMessageReceived(remoteMessage: RemoteMessage?)
//need db instance to store data payload locally (Room)
GL
Source
【讨论】:
【参考方案2】:这是 Kotlin 的实现:
Application.kt
@Inject
lateinit var dispatchingServiceInjector: DispatchingandroidInjector<Service>
override fun serviceInjector(): AndroidInjector<Service>
return dispatchingServiceInjector
模块.kt
@Module
abstract class FirebaseServiceModule
@ContributesAndroidInjector
abstract fun contributeMyFirebaseMessengingService(): MyFirebaseMessengingService
组件.kt
@Component(modules = [FirebaseServiceModule::class])
interface Component
...
MyFirebaseMessengingService.kt
override fun onCreate()
AndroidInjection.inject(this);
super.onCreate()
【讨论】:
【参考方案3】:终于从这个链接得到了解决方案:https://github.com/googlesamples/android-architecture-components/issues/253
由于MyFirebaseMessagingService
是Service
类,所以对于Service
类中的注入,Dagger 提供了一种将依赖项注入到Service 类中的方法。以下是在服务类中启用注入的步骤:
1) 使应用程序实现 HasServiceInjector 并为服务注入 DispatchingAndroidInjector。
public class App extends Application implements HasActivityInjector, HasServiceInjector
@Inject
DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
// Add this line
@Inject
DispatchingAndroidInjector<Service> dispatchingServiceInjector;
@Override
public void onCreate()
super.onCreate();
AppInjector.init(this);
@Override
public AndroidInjector<Activity> activityInjector()
return dispatchingActivityInjector;
// override this method after implementing HasServiceInjector
@Override
public AndroidInjector<Service> serviceInjector()
return dispatchingServiceInjector;
2) 创建一个新模块以对您的服务执行注入。
@Module
abstract class ServiceBuilderModule
// for my case, the service class which needs injection is MyFirebaseMessagingService
@ContributesAndroidInjector
abstract MyFirebaseMessagingService contributeMyFirebaseMessagingService();
3) 在应用程序组件中注册新模块。
@Component(modules =
AndroidSupportInjectionModule.class,
AppModule.class,
ActivityBuilderModule.class,
// Need to define previously created module class here
ServiceBuilderModule.class
)
@Singleton
public interface AppComponent
@Component.Builder
interface Builder
@BindsInstance
Builder application(App application);
AppComponent build();
void inject(App app);
4) 最后,覆盖添加 AndroidInjection.inject(this) 的服务的 onCreate 方法。
public class MyFirebaseMessagingService extends FirebaseMessagingService
//So now we are able to inject here same as we do in Activity. No need for constructor injection
@Inject ExampleOneDao exampleOneDao
// Override this method first
@Override
public void onCreate()
AndroidInjection.inject(this);
super.onCreate();
@Override
public void onMessageReceived(RemoteMessage remoteMessage)
// use your dao here to store remoteMessage data payload into your database, e.g exampleOneDao.save(somethingHere)
【讨论】:
它在 Kotlin 中不起作用,它会触发错误 No injector factory bound for Class以上是关于如何使用 Dagger 2 向 MyFirebaseMessagingService 提供数据库,以便我可以在 android 本地存储 fcm 消息的主要内容,如果未能解决你的问题,请参考以下文章
Dagger 2 Activity 上下文/ApplicationContext 模块