如何使用 Dagger 2 向 MyFirebaseMessagingService 提供数据库,以便我可以在 android 中本地存储 fcm 消息

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

如何才能将数据库实例传递给扩展

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)
    }
}

下面是 Dagger 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

谢谢。

android firebase kotlin firebase-cloud-messaging dagger-2
3个回答
31
投票

终于从这个链接得到了解决方案:https://github.com/googlesamples/android-architecture-components/issues/253

由于

MyFirebaseMessagingService
是一个
Service
类,所以对于
Service
类的注入,Dagger 提供了一种方法,我们可以通过该方法将依赖注入到Service 类中。以下是在服务类中启用注入的步骤:

1) Make Application实现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)
    }


}

4
投票

这里是 Kotlin 实现:

Application.kt

class MyApplication: Application, HasServiceInjector {

    @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()
}

0
投票

使用 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 
    lateinit var exampleOneDao: ExampleOneDao

    override fun onMessageReceived(remoteMessage: RemoteMessage?) {
    //need db instance to store data payload locally (Room)
    }
}

GL

来源

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