【译】react-native-background-job [react-native]

(免责声明:本译文未参考任何其他文章,如有与其他译版雷同部分,纯属巧合)
(声明:中文版权归作者zbc所有,转载请注明出处)
翻译原文地址(来自 Github)


当你的 app 在后台时安排你的 JavaScript 代码进行工作,或者够胆量的话你也可以尝试当 app 正在前台运行时进行此操作。
即使是该 app 已经被关闭了,此项进程依旧在运行。默认情况下,该进程在重启程序后也会保持存在。
本类库依赖于 React-Native 中目前只支持 Android 平台的 HeadlessJS
原生端代码它使用的是 Firebase JobDispatcher 或者 AlarmManager.

  • Firebase JobDispatcher (默认):工作不能被确切地安排并且取决于 Android api 不同时期的版本。 FirebaseJobDispatcher 是安排后台任务最省电且向后兼容的方式。

  • AlarmManager 通过把“exact”设置为“true”:简单的属性实现,仅测试用。只在意
    按时处理任务,其他参数均被忽略。重启程序后任务也不复存在。

要求:


  • React-Native 0.36+
  • Android api 16+

已经支持的平台


  • Android
    想要IOS版本?到官网去投票使其开发IOS版:产品之痛

起步


$ yarn add react-native-background-job

或者

$ npm install react-native-background-job --save

大多数的自动安装

$ react-native link react-native-background-job

手动安装

  • Android

1.打开文件,位置: android/app/src/main/java/[...]/MainApplication.java

  • 添加引用层代码
import com.pilloxa.backgroundjob.BackgroundJobPackage;
  • 添加新的初始化对象 new BackgroundJobPackage()getPackages() 方法里。

2.将以下代码添加到 android/settings.gradle 文件:

include ':react-native-background-job'
project(':react-native-background-job').projectDir = new File(rootProject.projectDir,   '../node_modules/react-native-background-job/android')

3.添加以下代码至依赖模块文件 android/app/build.gradle 并确保 minSdkVersion 是 21。

compile project(':react-native-background-job')

用法


进程必须在 React-Native 每次启动时注册,可以通过 register 方法。因为 HeadlessJS 没有安装任何 components,所以 register 方法必须在定义任意类之外运行。(参见 example/index.android.js,此网址位于github)

注册一个 job 并不意味着此 job 已经被安排,而只是告诉 React-Native 此 job 已经与这个 jobKey 绑定。此 job 接下来将要被安排使用你安排的方法。默认情况下,当你的app正在前台运行时,此 job 不会被激活。这是因为此 job 运行于 JavaScript 线程,并且如果你在 app 正运行于前台时启用此 job 将可能会冻结你的 app 动作。通过设置 allowExecutionInForeground 为“true”可以允许你这么做。我们推荐你不要这样使用,但如果是快速作业的话也许可以如此。

一个完整的例子 example/index.android.js

API


目录列表

【register】

注册一个 job 以启动想要运行的函数。
这个函数必须在每次 React-Native 初始化时运行,并且必须运行在全局环境而不是在任何组件内部的生命周期函数。见示例项目。只注册 job 不会使之运行。它必须被安排后续执行。

参数
<object>

  • obj.jobKey string 此 job 的唯一标识
  • obj.job function 将要运行的 Js 方法(代码)。

Examples

import BackgroundJob from 'react-native-background-job';

const backgroundJob = {
 jobKey: "myJob",
 job: () => console.log("Running in background")
};

BackgroundJob.register(backgroundJob);
【schedule】

安排一个新 job。
因为在每次 React-Native 初始化时,register 都被运行了一次,因此 schedule 应该仅运行一次。

参数
<object>

  • obj.jobKey string 那个在注册 job 时使用的 key,并且将在接下来退出时使用。
  • obj.timeout number 不管任务是否完成,都应终止响应的时间量(ms)(可配置,默认:2000
  • obj.period number 运行此 job 的频率(ms),其具体数字是不确定的,Android 可能会为了节省电量而修改这个设置。注意:对于 Android 平台,此值将大于等于 900,0000(15min)(可配置项,默认:900,0000)
  • obj.persist boolean 重启应用时此 job 是否应继续保持。(可配置项,默认:true
  • obj.override boolean 当前 job 是否应被已存在的相同 key 的其他 job 替换。(可配置项,默认:true
  • obj.networkType number 只针对特殊网络需要(可配置项,默认:NETWORK_TYPE_NONE
  • obj.requiresCharging boolean 仅在设备充电时运行, (不支持 pre Android N 设备) 文档(可配置项, 默认false)
  • obj.requiresDeviceIdle boolean 仅在设备空闲时使用, (不支持 pre Android N 设备) 文档(可配置项, 默认false)
  • obj.exact boolean 计划在定义的时间段内精准触发 job。注意:这项操作没有任何省电做法 (可配置项, 默认 false)
  • obj.allowWhileIdle boolean 允许 job 在睡眠时处理任务. (可配置项, 默认false)
  • obj.allowExecutionInForeground boolean 即便是 app 正在前台运行时依然允许 job 执行任务,请仅在小进程时使用 (配置, 默认false)
  • obj.notificationText string 对于 Android SDK 版本大于 26, 通知文本应该是什么 (可配置项, 默认"Running in background...")
  • obj.notificationTitle string 对于 Android SDK 版本大于 26, 通知标题应该是什么 (可配置项, 默认"Background job")

Examples

import BackgroundJob from 'react-native-background-job';

const backgroundJob = {
 jobKey: "myJob",
 job: () => console.log("Running in background")
};

BackgroundJob.register(backgroundJob);

var backgroundSchedule = {
 jobKey: "myJob",
}

BackgroundJob.schedule(backgroundSchedule);
【cancel】

退出特定 job。

参数
<object>

  • obj.jobKey string job 唯一标识。

Examples

import BackgroundJob from 'react-native-background-job';

BackgroundJob.cancel({jobKey: 'myJob'});
【cancelAll】

退出所有 job。

Examples

import BackgroundJob from 'react-native-background-job';

BackgroundJob.cancelAll();
【setGlobalWarnings】

设置全局警报等级。

参数

  • warn **[boolean]

Examples

import BackgroundJob from 'react-native-background-job';

BackgroundJob.setGlobalWarnings(false);
【isAppIgnoringBatteryOptimization】

检测 app 是否针对电池进行优化,在睡眠时使用,返回 boolean 值。

参数

  • callback Callback 在从 Android 模块收到结果后,携带参数被调用。
    Examples
import BackgroundJob from 'react-native-background-job';

BackgroundJob.isAppIgnoringBatteryOptimization((error,ignoringOptimization)=>{});

问题聚焦


1.No task registered for key myJob(对于 key myJob 不存在注册的任务)

确保你是在全局环境调用的register函数(也就是说不是在任何组件的生命周期函数内部使用,如 render(),componentDidMount()等). 由于在 Headless 模式下不会被渲染,如果你在那些位置使用的话,它将不会在后台环境运行,因此导致库中找不到该执行哪一个函数任务。
查看示例项目

2.当我在后台运行 Headless 任务时 AppState.currentState 是 "active" 。

这是一个 React Native 本身的问题,你可以选择直接调用NativeModules.AppState.getCurrentAppState 代替之。

3.即便是是我指定了 requiresCharging, requiresDeviceIdle或者 networkType,我的 job 也总是在后台运行。

这是一个 Android 的问题,看来对 Android N 设备而言,当你对其有周期间隔限制的同时不能再对这些配置做限制。

其他详细信息


包含了检查 app 是否为“耗电型 app” 的方法。#62
Android SDK 在高于23版本之后,Doze 默认是被使用的,目的是为了当手机被闲置几个小时的情况下,可以暂时关闭后台任务以节省电量。

但是,一些 app 可能会要求后台任务始终执行,忽略 doze 并且不考虑省电优化方案(这意味着每当使用此 app 时都要以更大的电池消耗以换取性能和表现)。那些要求在较短周期内持续与服务器同步数据的 app 就是此类 app 的典型例子。

所以对于开发人员来讲,检测 app 是否为 “省电型 App ”是很好的举动。因为如此做法,可以通知用户此 app 不是每次使用时都能如所预期的那样工作,除非用户手动将此 app 手动地移出“省电列表”(省电列表可以在 “设置”==>“电池”=>“选项(右上角)”=>“省电方案”并选择“所有 app”)。就为了某一个 app 而修改此项设定。

为了实现上述的检测功能,做了明确改进,包含进了一个用于检测(是否省电)的方法(isAppIgnoringBatteryOptimization)它可以检测 app 是否为耗电型 app ,如果是“耗电型”,返回 true,是“省电型”则返回 false。

安排一个耗电型任务的逻辑也已经被添加,这取决于用户是否手动将其“省电列表”

赞助商

------------------- 结束线 -----------------------

本文翻译结合笔者开发经验,如有错误,欢迎留言指正、探讨。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,306评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,657评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,928评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,688评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,105评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,024评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,159评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,937评论 0 212
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,689评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,851评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,325评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,651评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,364评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,192评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,985评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,154评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,955评论 2 279

推荐阅读更多精彩内容