Headless JS(后台任务)
Headless JS 是一种使用 js 在后台执行任务的方法。它可以用来在后台同步数据、处理推送通知或是播放音乐等等。
#
JS 端的 API首先我们要通过AppRegistry
来注册一个异步函数,这个函数我们称之为“任务”。注册方式类似在 index.js 中注册 RN 应用:
然后创建 require 中引用的SomeTaskName.js
文件:
你可以在任务中处理任何事情(网络请求、定时器等等),但唯独不要涉及用户界面!在任务完成后(例如在 promise 中调用 resolve),RN 会进入一个“暂停”模式,直到有新任务需要执行或者是应用回到前台。
#
Java 端的 API没错,我们还需要一些原生代码,但是请放心并不麻烦。首先需要像下面这样继承HeadlessJsTaskService
,然后覆盖getTaskConfig
方法的实现:
然后记得把服务添加到AndroidManifest
文件里:
好了,现在当你启动服务时(例如一个周期性的任务或是响应一些系统事件/广播),JS 任务就会开始执行。例如:
#
重试By default, the headless JS task will not perform any retries. In order to do so, you need to create a HeadlessJsRetryPolicy
and throw a specfic Error
.
LinearCountingRetryPolicy
is an implementation of HeadlessJsRetryPolicy
that allows you to specify a maximum number of retries with a fixed delay between each attempt. If that does not suit your needs then you can easily implement your own HeadlessJsRetryPolicy
. These policies can simply be passed as an extra argument to the HeadlessJsTaskConfig
constructor, e.g.
A retry attempt will only be made when a specific Error
is thrown. Inside a headless JS task, you can import the error and throw it when a retry attempt is required.
Example:
If you wish all errors to cause a retry attempt, you will need to catch them and throw the above error.
#
注意事项- The function passed to
setTimeout
does not always behave as expected. Instead the function is called only when the application is launched again. If you just need to wait, use the retry functionality.
- 默认情况下,如果应用正在前台运行时尝试执行任务,那么应用会崩溃。这是为了防止开发者在任务中处理太多逻辑而拖慢用户界面。如果你必须要这么做,那么可以设置第四个参数为
false
来更改这一限制。 - 如果你是通过
BroadcastReceiver
来启动的服务,那么谨记在从onReceive()
返回之前要调用HeadlessJsTaskService.acquireWakeLockNow()
。
#
示例我们可以使用 Java API 来开启一个 service。. First you need to decide when the service should be started and implement your solution accordingly. Here is a simple example that reacts to network connection change.
Following lines shows part of Android manifest file for registering broadcast receiver.
Broadcast receiver then handles intent that was broadcasted in onReceive function. This is a great place to check whether your app is on foreground or not. If app is not on foreground we can prepare our intent to be started, with no information or additional information bundled using putExtra
(keep in mind bundle can handle only parcelable values). In the end service is started and wakelock is acquired.