fix: Android headless JS timeout (#33044)
Summary: Fixes https://github.com/facebook/react-native/issues/33043 and thereby https://github.com/invertase/react-native-firebase/issues/3955. The issue arised because when there currently is no available React context, `HeadlessJsTaskService` will create a new one in background and start the task using `onReactContextInitialized` of `ReactInstanceManager.addReactInstanceEventListener`.7ef14af81f/ReactAndroid/src/main/java/com/facebook/react/HeadlessJsTaskService.java (L94-L113)
The `TimingModule` however is initialized asynchronously, meaning the headless JS is started before its initialization. That's an issue because the `TimingModule` is only run when there is JS code executing (meaning if the application is running or there is a headless task running) - this is checked by registering a `HeadlessJsTaskEventListener` on the `HeadlessJsTaskContext` in `TimingModule.initialize()`.7ef14af81f/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java (L69-L75)
However this event listener is never invoked because the task was started before `TimingModule.initialize()` is called -> `TimingModule.onHeadlessJsTaskStart(...)` is not called and the timer never resumes. In order to fix this we can just invoke `HeadlessJsTaskEventListener.onHeadlessJsTaskStart(...)` for all currently running tasks when a new listener is added to `HeadlessJsTaskContext`. This call then needs to be `synchronized` as otherwise there's a race condition with `HeadlessJsTaskContext.finishTask(...)` where `onHeadlessJsTaskFinish(...)` could be called before `onHeadlessJsTaskStart(...)`. See the diff for the exact changes. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [Android] [Fix] - Fixed `TimingModule` related functions for headless JS tasks, eg. `setTimeout` Pull Request resolved: https://github.com/facebook/react-native/pull/33044 Test Plan: I did a local build with the changes and tested the provided example code from https://github.com/facebook/react-native/issues/33043 there. Reviewed By: sshic Differential Revision: D34006573 Pulled By: dmitryrykun fbshipit-source-id: d6a821bbd6476ba278c1d8895edb4a0ba16d889e
This commit is contained in:
Родитель
65abc361bf
Коммит
dac56ce077
|
@ -61,9 +61,15 @@ public class HeadlessJsTaskContext {
|
|||
mReactContext = new WeakReference<ReactContext>(reactContext);
|
||||
}
|
||||
|
||||
/** Register a task lifecycle event listener. */
|
||||
public void addTaskEventListener(HeadlessJsTaskEventListener listener) {
|
||||
/**
|
||||
* Register a task lifecycle event listener. Synchronized in order to prevent race conditions with
|
||||
* finishTask, as the listener will be invoked for already running tasks.
|
||||
*/
|
||||
public synchronized void addTaskEventListener(HeadlessJsTaskEventListener listener) {
|
||||
mHeadlessJsTaskEventListeners.add(listener);
|
||||
for (Integer activeTaskId : mActiveTasks) {
|
||||
listener.onHeadlessJsTaskStart(activeTaskId);
|
||||
}
|
||||
}
|
||||
|
||||
/** Unregister a task lifecycle event listener. */
|
||||
|
|
Загрузка…
Ссылка в новой задаче