Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:如何在后台每5分钟调用应用程序类内部的函数_Android_Kotlin_Android Service_Kotlin Coroutines - Fatal编程技术网

Android:如何在后台每5分钟调用应用程序类内部的函数

Android:如何在后台每5分钟调用应用程序类内部的函数,android,kotlin,android-service,kotlin-coroutines,Android,Kotlin,Android Service,Kotlin Coroutines,我想在我的应用程序中启动刷新服务。我想要实现的是每5分钟进行一次API调用,即使用户锁定屏幕以更新数据,尤其是通过使用API调用中的新数据重新创建通知来更新可见的通知 我试图将逻辑移动到应用程序类,在该类中,我将在全局范围内初始化作业,该作业将无限期运行,直到我取消此作业。如果我将延迟设置为10秒或30秒,此解决方案有效。即使我的应用程序在后台也能正常工作。但如果我将延迟设置为更长的时间(在本例中我需要这个时间),比如5-10分钟,它会突然停止。我的理解是,当长时间处于非活动状态时,此作业将停止

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

我试图将逻辑移动到应用程序类,在该类中,我将在
全局范围内初始化
作业
,该作业将无限期运行,直到我取消此
作业
。如果我将延迟设置为10秒或30秒,此解决方案有效。即使我的应用程序在后台也能正常工作。但如果我将延迟设置为更长的时间(在本例中我需要这个时间),比如5-10分钟,它会突然停止。我的理解是,当长时间处于非活动状态时,此作业将停止或应用程序类被破坏

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

有没有办法将应用程序类和服务链接起来

如果应用程序被终止,我不需要运行此refreshAPI

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

更新:倒计时解决方案(不工作):

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


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

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

爪哇

科特林


你可以用倒计时。创建一个IntentService类并为API调用运行该服务

爪哇

科特林


尽管每5分钟调用一次API并不是完成任务的最佳方式。 对于定期作业,最小值为15分钟。 你可以用

图书馆

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

尽管每5分钟调用一次API并不是完成任务的最佳方式。 对于定期作业,最小值为15分钟。 你可以用

图书馆

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

为什么不试试WorkManager来完成重复性任务呢?它将运行您的应用程序是在前台还是在后台?您可以使用其他方法,例如EventBus,将服务结果传达给您的应用程序。安全和容易!如何将应用程序类对象作为构造函数参数发送到我的工人类?我必须在应用程序类中运行callRefeshAPI。我只想设置运行它的时间间隔。PeriodicWorkRequest.Builder只允许我将class::java对象添加到构造函数中,而不是整个Worker对象PeriodicWorkRequest的间隔为15分钟。这对于我的刷新来说太长了。如果您只想在应用程序位于前台时运行刷新任务,刷新完成后,您可以使用OneTimeRequest并再次重新安排任务。并且不传递应用程序对象。使用EventBus的事件机制触发任务。为什么不尝试WorkManager执行重复性任务?它将运行您的应用程序是在前台还是在后台?您可以使用其他方法,例如EventBus,将服务结果传达给您的应用程序。安全和容易!如何将应用程序类对象作为构造函数参数发送到我的工人类?我必须在应用程序类中运行callRefeshAPI。我只想设置运行它的时间间隔。PeriodicWorkRequest.Builder只允许我将class::java对象添加到构造函数中,而不是整个Worker对象PeriodicWorkRequest的间隔为15分钟。这对于我的刷新来说太长了。如果您只想在应用程序位于前台时运行刷新任务,刷新完成后,您可以使用OneTimeRequest并再次重新安排任务。并且不传递应用程序对象。使用EventBus的事件机制触发任务。如果手机屏幕被锁定,则此操作不起作用。甚至连一次刷新都没有,日志中也没有称onTick为代码的内容。每12分钟重新创建一次倒计时。若我在应用程序中运行了5分钟,刷新就起作用了,防止我的设备进入睡眠状态,并在我猜问题与协同程序和作业类似后自动锁定屏幕。倒计时器在后台不起作用。实际上,我必须使用AlarmManager强制设备每5分钟唤醒一次,因为如果设备处于睡眠模式,Android会停止所有后台任务。这就是推送通知的工作原理,也是在将来某个时间触发的本地通知。如果手机屏幕被锁定,则此功能不起作用。甚至连一次刷新都没有,日志中也没有称onTick为代码的内容。每12分钟重新创建一次倒计时。若我在应用程序中运行了5分钟,刷新就起作用了,防止我的设备进入睡眠状态,并在我猜问题与协同程序和作业类似后自动锁定屏幕。倒计时器在后台不起作用。实际上,我必须使用AlarmManager强制设备每5分钟唤醒一次,因为如果设备处于睡眠模式,Android会停止所有后台任务。这就是推送通知的工作原理,也是在将来某个时间触发本地通知的方式
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();
}
 fun repeatCall() {

        object : CountDownTimer(50000, 1000) {

            override fun onTick(millisUntilFinished: Long) {

            }

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

        }.start()

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