我有一个Repository(context: Context)
类(接受上下文),它必须是单例的。
在正常情况下这很容易做到。但是在我的应用程序中,我有一个Foreground Service
,即使应用程序从最近的应用程序中删除,它也会运行。
我必须在这个Foreground Service
和应用程序中的其他Fragments
中使用Repository
对象。
什么是最好的方法来使Repository
单例?
目前我正在使用dagger-hilt
注入Service
类中的Repository
。我不确定这样做是否正确。
MainApplication.kt
@HiltAndroidApp
class MainApplication: Application() {}
HiltModule.kt
@Module
@InstallIn(SingletonComponent::class)
object HiltModule {
@Singleton
@Provides
fun getDataStore(@ApplicationContext mContext: Context) = Repository(mContext)
}
ForegroundService.kt
@AndroidEntryPoint
class ForegroundService : Service() {
@Inject
lateinit var dataRepo: Repository
}
我对Hilt一无所知,但是如果您同意前面的构造函数注入,您可以使用绑定服务。您可以在您的活动和前台服务之间设置绑定,然后在服务激活并注册后传入共享存储库实例。在我看来,这是在活动和服务之间进行通信的推荐方式。
我认为这也将有助于解决你在评论中提出的生命周期问题。我在前台服务上使用这种方法,它的生命周期与MainActivity不同,activity被销毁,服务继续在后台运行,没有问题。它也启动备份,并与前台进程同步,没有问题。柄可能无意中导致生命周期问题。
编辑:刚刚看到这个评论
常见的Android DI解决方案不能跨进程工作。如果你被选为有2+个进程(例如UI进程和前台服务)进程),您不能使用,说,柄。
class MainActivity : AppCompatActivity(), ForegroundServiceConnection {
private lateinit var mService: ForegroundService
private var mBound: Boolean = false
private val mConnection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
Log.d("SERVICE CONNECTED", "FOREGROUND RUNNING")
val binder = service as ForegroundService.ForegroundServiceBinder
mService = binder.getService()
mBound = true
mService.setCallbacks(this@MainActivity)
}
override fun onServiceDisconnected(arg0: ComponentName){
mBound = false
}
}
}
您还需要在服务中实现绑定:
class ForegroundService: LifecycleService() {
private val binder = ForegroundServiceBinder()
inner class ForegroundServiceBinder : Binder() {
fun getService(): ForegroundService = this@ForegroundService
}
override fun onBind(intent: Intent): IBinder {
return binder
}
private lateinit var serviceConnection: ForegroundServiceConnection
}
接下来,创建一个接口,定义前台服务可用的方法,如下所示:
interface ForegroundServiceConnection {
fun getRepositorySingleton () : RepositoryClass
}
现在,回到您添加绑定的活动,并实现接口方法。
fun getRepositorySingleton () : RepositoryClass {
return repo
}
在前台服务中,创建setcallback方法,它将接收activity/app作为参数,并保存对它的引用,如下所示:
fun setCallbacks(app: MainActivity) {
serviceConnection = app
// Now you have access to the MainActivity
val repo = serviceConnection.getRepositorySingleton()
// Done
}
如果您试图在此块之外使用serviceConnection,请记住检查空值,因为它可能尚未创建。
享受吧!:)