首页 > 解决方案 > Android:如何在后台每5分钟调用一次应用程序类中的函数

问题描述

我想Service在我的应用程序中开始刷新。我想要实现的是每 5 分钟进行一次 API 调用,即使用户锁定了他的屏幕以更新数据,尤其是通过使用 API 调用中的新数据重新创建通知来更新可见通知。

我试图将我的逻辑移动到我将在其中初始化Job的Application 类GlobalScope,它将无限期地运行,直到我取消它Job。如果我将延迟设置为 10 或 30 秒,则此解决方案有效。即使我的应用程序在后台,它也能正常工作。但是如果我将延迟设置为更长的时间(在这种情况下我需要),比如 5-10 分钟,它会突然停止。我的理解是,当长时间不活动时,这个 Job 会消失或 Application 类被破坏。

我想创建将与我的应用程序类通信并在服务中初始化此作业以调用应用程序类函数来刷新通知的服务。但我不能在服务中使用参数。

有什么方法可以链接应用程序类和服务吗?

如果 App 被杀死,我不需要运行这个 refreshAPI。

示例(这是在 Application 类中运行的 - 想要将其移动到 Service 并从 Service 类调用 app.callRefreshAPI()):

var refresher: Job? = null
private var refreshRate = 300000L
fun createNotificationRefresher(){
    refresher = GlobalScope.launch {
        while (isActive){
            callRefreshAPI()
            delay(refreshRate)
        }
    }
}

更新: CountDownTimer 解决方案(不工作):

var refresher: CountDownTimer? = null
private var refreshRate = 300000L //5min
private var refresherDuration = 780000L //12min
fun initNotificationRefresher(){
    refresher = object : CountDownTimer(refresherDuration, refreshRate) {
        override fun onTick(millisUntilFinished: Long) {
            callRefreshAPI()
        }
        override fun onFinish() {
            initNotificationRefresher()
        }
    }.start()
}

更新 2:当手机屏幕锁定且操作系统处于睡眠模式时,计时器/作业/工作人员不工作。这意味着无法在后台后台操作中使用计时器。我必须使用在 Application 类(不是!AndroidManifest)中注册的 BroadcastReceiver 并收听 SCREEN_ON 操作。然后节省用户解锁手机的时间,并检查在更新通知的屏幕锁定和在这种情况下通过调用 GlobalScope 中的 API 刷新通知之间是否至少有 5-10 分钟。

我希望这对其他人有帮助。如果应用程序在后台并且用户仍在与手机交互(检查其他应用程序、浏览内容等),则作业/计时器将起作用。

标签: androidkotlinandroid-servicekotlin-coroutines

解决方案


尽管每 5 分钟调用一次 API 并不是完成任务的最优化方式。周期性作业的最小值为 15 分钟。您可以使用

Ever Note Android Job Library。

private void schedulePeriodicJob() {
    int jobId = new JobRequest.Builder(DemoSyncJob.TAG)
            .setPeriodic(TimeUnit.MINUTES.toMillis(15), TimeUnit.MINUTES.toMillis(5))
            .build()
            .schedule();
}

推荐阅读