首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android:如何在后台每5分钟调用一次Application类中的函数

Android:如何在后台每5分钟调用一次Application类中的函数
EN

Stack Overflow用户
提问于 2019-11-19 10:11:06
回答 2查看 2K关注 0票数 0

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

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

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

有没有办法连接应用程序类和服务?

如果应用程序被杀了,我不需要运行这个refreshAPI。

示例(这是在应用程序类中运行的-希望将其移动到Service并从服务类调用app.callRefreshAPI() ):

代码语言:javascript
复制
var refresher: Job? = null
private var refreshRate = 300000L
fun createNotificationRefresher(){
    refresher = GlobalScope.launch {
        while (isActive){
            callRefreshAPI()
            delay(refreshRate)
        }
    }
}

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

代码语言:javascript
复制
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:当手机屏幕锁定,操作系统处于睡眠模式时,计时器/作业/工作人员无法工作。这意味着没有办法在后台操作中使用计时器。我不得不使用在应用程序类中注册的BroadcastReceiver (不是!( AndroidManifest)并收听SCREEN_ON的动作。然后,在用户解锁手机时节省时间,并检查在更新通知的屏幕锁和在此条件下调用GlobalScope中的API通知之间是否至少有5-10分钟。

我希望这会对其他人有所帮助。如果应用程序处于后台,并且用户仍在与电话交互(查看其他应用程序、浏览内容等),则作业/计时器将工作。

EN

回答 2

Stack Overflow用户

发布于 2019-11-19 11:26:20

为此您可以使用CountDownTimer。并创建一个IntentService类并为API调用运行该服务。

JAVA

代码语言:javascript
复制
public void repeatCall(){

   new CountDownTimer(50000, 1000) {

        public void onTick(long millisUntilFinished) {

        }

        public void onFinish() {
           repeatCall();//again call your method
        }

    }.start();

}

//Declare timer
CountDownTimer cTimer = null;

//start timer function
void startTimer() {
    cTimer = new CountDownTimer(30000, 1000) {
        public void onTick(long millisUntilFinished) {
        }
        public void onFinish() {
        }
    };
    cTimer.start();
}


//cancel timer
void cancelTimer() {
    if(cTimer!=null)
        cTimer.cancel();
}

科特林

代码语言:javascript
复制
 fun repeatCall() {

        object : CountDownTimer(50000, 1000) {

            override fun onTick(millisUntilFinished: Long) {

            }

            override fun onFinish() {
                repeatCall()//again call your method
            }

        }.start()

    }
票数 1
EN

Stack Overflow用户

发布于 2019-11-19 11:44:18

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

请注意Android作业库就是这样做的。

代码语言:javascript
复制
private void schedulePeriodicJob() {
    int jobId = new JobRequest.Builder(DemoSyncJob.TAG)
            .setPeriodic(TimeUnit.MINUTES.toMillis(15), TimeUnit.MINUTES.toMillis(5))
            .build()
            .schedule();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58931472

复制
相关文章

相似问题

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