首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为前台服务和片段制作存储库单例?

如何为前台服务和片段制作存储库单例?
EN

Stack Overflow用户
提问于 2022-07-07 11:06:01
回答 1查看 129关注 0票数 0

我有一个必须是单例的Repository(context: Context)类(接受上下文)。

在正常情况下,这是容易做到的。但是在我的应用程序中,我有一个Foreground Service,即使应用程序从最近的应用中被删除,它也会运行。

我必须使用Repository对象,在这个Foreground Service内部,以及在应用程序中的其他Fragments中。

Repository 单例的最佳方法是什么?

目前,我正在使用dagger-hiltService类中注入Repository。我不知道这是否是正确的做法。

下面是代码示例:

MainApplication.kt

代码语言:javascript
复制
@HiltAndroidApp
class MainApplication: Application() {}

HiltModule.kt

代码语言:javascript
复制
@Module
@InstallIn(SingletonComponent::class)
object HiltModule {

    @Singleton
    @Provides
    fun getDataStore(@ApplicationContext mContext: Context) = Repository(mContext)
}

ForegroundService.kt

代码语言:javascript
复制
@AndroidEntryPoint
class ForegroundService : Service() {

    @Inject
    lateinit var dataRepo: Repository
}
EN

回答 1

Stack Overflow用户

发布于 2022-07-23 00:28:31

我对Hilt一无所知,但是如果您不介意前面的构造函数注入,就可以使用绑定服务。您可以在您的活动和前台服务之间设置一个绑定,然后在服务处于活动状态并注册了自己之后,传入您的共享存储库实例。据我所知,这是在活动和服务之间进行通信的推荐方法。

我认为这也将有助于您在评论中提到的生命周期问题。我在前台服务上使用这种方法,它的生命周期与我的MainActivity不同,活动被破坏,服务在后台继续运行,没有问题。它还启动备份,并与前台进程同步,没有问题。Hilt可能无意中导致生命周期问题。

编辑:刚碰到这个comment

公共Android解决方案不能跨进程工作。如果您选择拥有2+进程(例如,UI进程和前台服务流程),则不能使用Hilt将相同的对象注入两个进程。

代码语言:javascript
复制
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
        }
    }
}

您还需要在服务中实现绑定:

代码语言:javascript
复制
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

}

接下来,创建一个接口,定义您希望前台服务可用的方法,如下所示:

代码语言:javascript
复制
interface ForegroundServiceConnection {

    fun getRepositorySingleton () : RepositoryClass 

}

现在,回到您添加绑定的活动,并实现接口方法。

代码语言:javascript
复制
fun getRepositorySingleton () : RepositoryClass {
    return repo
}

在前台服务中,创建将接收活动/应用程序作为参数的setCallbacks方法,并保存对它的引用,如下所示:

代码语言:javascript
复制
fun setCallbacks(app: MainActivity) {
    serviceConnection = app
    // Now you have access to the MainActivity
    val repo = serviceConnection.getRepositorySingleton()
    // Done
}

请记住,如果尝试在此块之外使用serviceConnection,请检查空值,它可能尚未创建。

享受!:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72896713

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档