瀏覽代碼

[RN] Fix running timers in the background

Turns out React Native's timers (setTimeout / setInterval) don't run while the
app is in the background: https://github.com/facebook/react-native/issues/167

This patch replaces the global timer functions with those from the
react-native-background-timer package, which work in the background.

These timers won't magically make an application work in the background, but
they will run if an application already happens to run in the background. That's
our case while in a conference, so these timers will run, allowing XMPP pings to
be sent and the conference to stay up as long as the user desires.
j8
Saúl Ibarra Corretgé 8 年之前
父節點
當前提交
36f5b0218d

+ 1
- 0
android/app/build.gradle 查看文件

@@ -139,6 +139,7 @@ if (project.hasProperty('JITSI_SIGNING')
139 139
 }
140 140
 
141 141
 dependencies {
142
+    compile project(':react-native-background-timer')
142 143
     compile project(':react-native-immersive')
143 144
     compile project(':react-native-keep-awake')
144 145
     compile project(':react-native-vector-icons')

+ 1
- 0
android/app/src/main/java/org/jitsi/meet/MainApplication.java 查看文件

@@ -29,6 +29,7 @@ public class MainApplication extends Application implements ReactApplication {
29 29
                 new com.corbt.keepawake.KCKeepAwakePackage(),
30 30
                 new com.facebook.react.shell.MainReactPackage(),
31 31
                 new com.oblador.vectoricons.VectorIconsPackage(),
32
+                new com.ocetnik.timer.BackgroundTimerPackage(),
32 33
                 new com.oney.WebRTCModule.WebRTCModulePackage(),
33 34
                 new com.rnimmersive.RNImmersivePackage(),
34 35
                 new org.jitsi.meet.audiomode.AudioModePackage()

+ 2
- 0
android/settings.gradle 查看文件

@@ -1,6 +1,8 @@
1 1
 rootProject.name = 'jitsi-meet-react'
2 2
 
3 3
 include ':app'
4
+include ':react-native-background-timer'
5
+project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
4 6
 include ':react-native-immersive'
5 7
 project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
6 8
 include ':react-native-keep-awake'

+ 12
- 2
ios/jitsi-meet-react.xcodeproj/project.pbxproj 查看文件

@@ -5,7 +5,6 @@
5 5
 	};
6 6
 	objectVersion = 46;
7 7
 	objects = {
8
-
9 8
 /* Begin PBXBuildFile section */
10 9
 		002AF788986B412780935607 /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B96AF9B6FBC0453798399985 /* FontAwesome.ttf */; };
11 10
 		00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
@@ -41,6 +40,7 @@
41 40
 		BF9643921C34FBF100B0BBDF /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BF9643911C34FBF100B0BBDF /* libsqlite3.tbd */; };
42 41
 		BF9643941C34FBF900B0BBDF /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BF9643931C34FBF900B0BBDF /* libstdc++.tbd */; };
43 42
 		BFC745141CB829B300673F38 /* libRCTWebRTC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BFC745131CB829A700673F38 /* libRCTWebRTC.a */; };
43
+		7FAD39BE09A84D6AB0ABACA8 /* libRNBackgroundTimer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27A0018BBB2C4FD5A4F9CE71 /* libRNBackgroundTimer.a */; };
44 44
 /* End PBXBuildFile section */
45 45
 
46 46
 /* Begin PBXContainerItemProxy section */
@@ -297,6 +297,8 @@
297 297
 		BF9643911C34FBF100B0BBDF /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
298 298
 		BF9643931C34FBF900B0BBDF /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; };
299 299
 		BFC7450D1CB829A700673F38 /* RCTWebRTC.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebRTC.xcodeproj; path = "../node_modules/react-native-webrtc/ios/RCTWebRTC.xcodeproj"; sourceTree = "<group>"; };
300
+		0965153BB98645B4A8B6AA10 /* RNBackgroundTimer.xcodeproj */ = {isa = PBXFileReference; name = "RNBackgroundTimer.xcodeproj"; path = "../node_modules/react-native-background-timer/ios/RNBackgroundTimer.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
301
+		27A0018BBB2C4FD5A4F9CE71 /* libRNBackgroundTimer.a */ = {isa = PBXFileReference; name = "libRNBackgroundTimer.a"; path = "libRNBackgroundTimer.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
300 302
 /* End PBXFileReference section */
301 303
 
302 304
 /* Begin PBXFrameworksBuildPhase section */
@@ -329,6 +331,7 @@
329 331
 				139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
330 332
 				3847F11906B4479A9162628F /* libRNVectorIcons.a in Frameworks */,
331 333
 				901FE90FA5744B5B94DCDC41 /* libKCKeepAwake.a in Frameworks */,
334
+				7FAD39BE09A84D6AB0ABACA8 /* libRNBackgroundTimer.a in Frameworks */,
332 335
 			);
333 336
 			runOnlyForDeploymentPostprocessing = 0;
334 337
 		};
@@ -489,6 +492,7 @@
489 492
 				139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
490 493
 				146833FF1AC3E56700842450 /* React.xcodeproj */,
491 494
 				22418656B14845609F953A42 /* RNVectorIcons.xcodeproj */,
495
+				0965153BB98645B4A8B6AA10 /* RNBackgroundTimer.xcodeproj */,
492 496
 			);
493 497
 			name = Libraries;
494 498
 			sourceTree = "<group>";
@@ -576,7 +580,7 @@
576 580
 		83CBB9F71A601CBA00E9B192 /* Project object */ = {
577 581
 			isa = PBXProject;
578 582
 			attributes = {
579
-				LastUpgradeCheck = 0820;
583
+				LastUpgradeCheck = 820;
580 584
 				ORGANIZATIONNAME = Facebook;
581 585
 				TargetAttributes = {
582 586
 					13B07F861A680F5B00A75B9A = {
@@ -954,6 +958,7 @@
954 958
 					"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**",
955 959
 					"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
956 960
 					"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
961
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
957 962
 				);
958 963
 				INFOPLIST_FILE = app/Info.plist;
959 964
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@@ -961,6 +966,7 @@
961 966
 				LIBRARY_SEARCH_PATHS = (
962 967
 					"$(inherited)",
963 968
 					"$(SRCROOT)/../node_modules/react-native-webrtc/**",
969
+					"\"$(SRCROOT)/jitsi-meet-react\"",
964 970
 				);
965 971
 				OTHER_LDFLAGS = (
966 972
 					"$(inherited)",
@@ -990,6 +996,7 @@
990 996
 					"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**",
991 997
 					"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
992 998
 					"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
999
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
993 1000
 				);
994 1001
 				INFOPLIST_FILE = app/Info.plist;
995 1002
 				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@@ -997,6 +1004,7 @@
997 1004
 				LIBRARY_SEARCH_PATHS = (
998 1005
 					"$(inherited)",
999 1006
 					"$(SRCROOT)/../node_modules/react-native-webrtc/**",
1007
+					"\"$(SRCROOT)/jitsi-meet-react\"",
1000 1008
 				);
1001 1009
 				OTHER_LDFLAGS = (
1002 1010
 					"$(inherited)",
@@ -1052,6 +1060,7 @@
1052 1060
 					"$(SRCROOT)/../node_modules/react-native/React/**",
1053 1061
 					"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
1054 1062
 					"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
1063
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
1055 1064
 				);
1056 1065
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
1057 1066
 				MTL_ENABLE_DEBUG_INFO = YES;
@@ -1097,6 +1106,7 @@
1097 1106
 					"$(SRCROOT)/../node_modules/react-native/React/**",
1098 1107
 					"$(SRCROOT)/../node_modules/react-native-keep-awake/ios",
1099 1108
 					"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
1109
+					"$(SRCROOT)/../node_modules/react-native-background-timer/ios",
1100 1110
 				);
1101 1111
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
1102 1112
 				MTL_ENABLE_DEBUG_INFO = NO;

+ 1
- 0
package.json 查看文件

@@ -35,6 +35,7 @@
35 35
     "react": "15.4.2",
36 36
     "react-dom": "15.4.2",
37 37
     "react-native": "0.41.2",
38
+    "react-native-background-timer": "^1.0.0",
38 39
     "react-native-immersive": "0.0.4",
39 40
     "react-native-keep-awake": "^2.0.2",
40 41
     "react-native-prompt": "^1.0.0",

+ 16
- 0
react/features/base/lib-jitsi-meet/native/polyfills-browser.js 查看文件

@@ -1,3 +1,5 @@
1
+import BackgroundTimer from 'react-native-background-timer';
2
+
1 3
 /**
2 4
  * Gets the first common prototype of two specified Objects (treating the
3 5
  * objects themselves as prototypes as well).
@@ -313,4 +315,18 @@ function _visitNode(node, callback) {
313 315
         }
314 316
     }
315 317
 
318
+    // Timers
319
+    //
320
+    // React Native's timers won't run while the app is in the background,
321
+    // this is a known limitation. Replace them with a background-friendly
322
+    // alternative.
323
+    //
324
+    // Required by:
325
+    // - lib-jitsi-meet
326
+    // - Strophe
327
+    global.setTimeout = window.setTimeout = BackgroundTimer.setTimeout;
328
+    global.clearTimeout = window.clearTimeout = BackgroundTimer.clearTimeout;
329
+    global.setInterval = window.setInterval = BackgroundTimer.setInterval;
330
+    global.clearInterval = window.clearInterval = BackgroundTimer.clearInterval;
331
+
316 332
 })(global || window || this); // eslint-disable-line no-invalid-this

Loading…
取消
儲存