简体   繁体   English

如何在反应原生的特定时间安排后台工作

[英]How to schedule background job at specific time in react native

I want to execute some Task T at specific time in a day in background in react native. 我想在背景中的一天中的特定时间执行一些任务T。 I see that it is possible in android as of now using Headless JS . 我发现在Android中有可能使用Headless JS I found that this library implemented this https://github.com/vikeri/react-native-background-job and allows you to execute stuff in background. 我发现这个库实现了这个https://github.com/vikeri/react-native-background-job并允许你在后台执行东西。

This is not completely what I am looking, it doesn't allows you to schedule a task T at specific time. 这不完全是我所期待的,它不允许您在特定时间安排任务T. Does anyone know any work around for this ? 有谁知道这方面的任何工作?

I have checked this thread Execute code at specific time in react native where I didn't find a solution of my issue. 我已检查此线程执行代码在特定时间反应原生我没有找到我的问题的解决方案。

I came across a similar issue, unfortunately, you can't specify something similar to CRON action in RN. 我遇到了类似的问题,不幸的是,你不能在RN中指定类似于CRON动作的东西。

My solution to that problem is to use this library https://github.com/ocetnik/react-native-background-timer and calculate the difference between current time and time that the task is scheduled for. 我对该问题的解决方案是使用此库https://github.com/ocetnik/react-native-background-timer并计算任务计划的当前时间和时间之间的差异。

The calculated time should be in ms, so you can use it with provided function setTimeout : 计算的时间应该以ms为单位,因此您可以将其与提供的函数setTimeout

// Start a timer that runs once after X milliseconds
const timeoutId = BackgroundTimer.setTimeout(() => {
  // this will be executed once after 10 seconds
  // even when app is the the background
  console.log('tac');
}, 10000);

Example: 例:

Let's say you want to schedule task for tomorrow at 16th, in componentDidMount you can calculate time between now and scheduled date. 假设你想在明天16日安排任务,在componentDidMount你可以计算从现在到预定日期之间的时间。 Let's use moment for that: 让我们用这个moment

componentDidMount(){
  const scheduledDate = 
   moment().add(1,'d').set({hour:16,minute:0,second:0,millisecond:0})
  const diffTime = scheduledDate.diff(moment())
  this.timeoutId = BackgroundTimer.setTimeout(() => {
    console.log('tac');
  }, diffTime);
}

componentWillUnmount(){
 BackgroundTimer.clearTimeout(this.timeoutId);
}

Note that this solution is vulnerable to a user changing the time on his phone. 请注意,此解决方案容易受到用户更改手机时间的影响。 The perfect solution would be to use some external service to fetch time. 完美的解决方案是使用一些外部服务来获取时间。

Second note, the app needs to be at least in the background for this to work. 第二个注意事项,应用程序至少需要在后台才能实现。

JavaScript code runs in foreground with only one thread. JavaScript代码在前台运行,只有一个线程。 If you need scheduled background task, you need to implement native modules, as described in RN document: 如果您需要预定的后台任务,则需要实现本机模块,如RN文档中所述:

https://facebook.github.io/react-native/docs/native-modules-ios.html https://facebook.github.io/react-native/docs/native-modules-ios.html

https://facebook.github.io/react-native/docs/native-modules-android.html https://facebook.github.io/react-native/docs/native-modules-android.html

Of course, all the platform restrictions (especially iOS) apply. 当然,所有平台限制(尤其是iOS)都适用。

Create class and add this in your class 创建类并在您的类中添加它

public static final long NOTIFY_INTERVAL = 10 * 1000; // 30 minutes

@Override
    public void onCreate() {
        // cancel if already existed
        if (mTimer != null) {
            mTimer.cancel();
        } else {
            // recreate new
            mTimer = new Timer();
        }
        // schedule task
        mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
    }

class TimeDisplayTimerTask extends TimerTask {
        @Override
        public void run() {
            // run on another thread
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    // code
                }
            });
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM