データベースインスタンスをMyFirebaseMessagingService
を拡張するFirebaseMessagingService
クラスに渡して、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)
}
}
以下は、Dagger2の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)
}
}
データベースとdaoをMyFirebaseMessagingService
クラスに提供することは可能ですか?
上記のメソッドを使用してexampleOneDao
をMyFirebaseMessagingService
クラスに提供しようとしましたが、次のException
がスローされます。
MyFirebaseMessagingService: Java.lang.InstantiationException: Java.lang.Class<com.example.user.app.firebase.messaging.MyFirebaseMessagingService> has no zero argument constructor
ありがとうございました。
最終的にこのリンクから解決策を得ました: https://github.com/googlesamples/Android-architecture-components/issues/25
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)
}
}
Daggerとの依存関係をサービスに注入するには、型エラーMyFirebaseMessagingServiceを回避するために、コンストラクターからではなく、パブリッククラス変数を使用する必要があります。ゼロ引数コンストラクターはありません。
ソリューション パスを実装した後
から:
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
Kotlinの実装は次のとおりです。
Application.kt
@Inject
lateinit var dispatchingServiceInjector: DispatchingAndroidInjector<Service>
override fun serviceInjector(): AndroidInjector<Service> {
return dispatchingServiceInjector
}
Module.kt
@Module
abstract class FirebaseServiceModule {
@ContributesAndroidInjector
abstract fun contributeMyFirebaseMessengingService(): MyFirebaseMessengingService
}
Component.kt
@Component(modules = [FirebaseServiceModule::class])
interface Component {
...
}
MyFirebaseMessengingService.kt
override fun onCreate() {
AndroidInjection.inject(this);
super.onCreate()
}