如何做出库单例和片断的前台服务吗?



我有一个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,请记住检查空值,因为它可能尚未创建。

享受吧!:)

最新更新