Skip to content

Commit

Permalink
Create slider accessibility delegate in createViewInstance (#31942)
Browse files Browse the repository at this point in the history
Summary:
Recent change in #31865 made it so if `ReactSliderManager` is created on the react context creation thread it will crash with the following error. This happens because `ReactAccessibilityDelegate` tries to create a handler on a thread without a looper.

This seems to happen because react-native-reanimated tries to get the UIManager module during its initialization which will cause view managers to be created and explains why the crash probably does not happens in RNTester or using only RN bundled modules.

```
08-03 14:44:56.318 21206 21360 E AndroidRuntime: FATAL EXCEPTION: create_react_context
08-03 14:44:56.318 21206 21360 E AndroidRuntime: Process: com.th3rdwave, PID: 21206
08-03 14:44:56.318 21206 21360 E AndroidRuntime: java.lang.ExceptionInInitializerError
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.shell.MainReactPackage.createViewManagers(MainReactPackage.java:166)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.ReactInstanceManager.getOrCreateViewManagers(ReactInstanceManager.java:882)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.CoreModulesPackage.createUIManager(CoreModulesPackage.java:137)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.CoreModulesPackage.getModule(CoreModulesPackage.java:102)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.TurboReactPackage$ModuleHolderProvider.get(TurboReactPackage.java:159)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.TurboReactPackage$ModuleHolderProvider.get(TurboReactPackage.java:147)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.bridge.ModuleHolder.create(ModuleHolder.java:191)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.bridge.ModuleHolder.getModule(ModuleHolder.java:156)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.bridge.NativeModuleRegistry.getModule(NativeModuleRegistry.java:153)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule(CatalystInstanceImpl.java:486)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule(CatalystInstanceImpl.java:462)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.bridge.ReactContext.getNativeModule(ReactContext.java:176)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.swmansion.reanimated.NodesManager.<init>(NodesManager.java:153)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.swmansion.reanimated.ReanimatedModule.getNodesManager(ReanimatedModule.java:101)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.swmansion.reanimated.ReanimatedJSIModulePackage.getJSIModules(ReanimatedJSIModulePackage.java:17)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.th3rdwave.MainApplication$1$1.getJSIModules(MainApplication.java:135)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.ReactInstanceManager.createReactContext(ReactInstanceManager.java:1329)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.ReactInstanceManager.access$1100(ReactInstanceManager.java:136)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.ReactInstanceManager$5.run(ReactInstanceManager.java:1058)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:923)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: Caused by: java.lang.RuntimeException: Can't create handler inside thread Thread[create_react_context,5,main] that has not called Looper.prepare()
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at android.os.Handler.<init>(Handler.java:227)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at android.os.Handler.<init>(Handler.java:129)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.uimanager.ReactAccessibilityDelegate$1.<init>(ReactAccessibilityDelegate.java:185)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.uimanager.ReactAccessibilityDelegate.<init>(ReactAccessibilityDelegate.java:184)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.views.slider.ReactSliderManager$ReactSliderAccessibilityDelegate.<init>(ReactSliderManager.java:281)
08-03 14:44:56.318 21206 21360 E AndroidRuntime: 	at com.facebook.react.views.slider.ReactSliderManager.<clinit>(ReactSliderManager.java:301)
```

To fix it I changed the delegate creation to be done in `createViewInstance` which will be called on main thread. This is also more in line with how other accessibility delegates are created for other view managers. Since Slider is probably not used a lot, creating more delegate instance won't be an issue.

Another alternative could be to initialize a Looper on the thread that creates the react context, but it seems more involved and probably not needed.

## Changelog

[Android] [Fixed] - Create slider accessibility delegate in createViewInstance

Pull Request resolved: #31942

Test Plan: Reproduced the crash in an app and made sure this patch fixes it.

Reviewed By: JoshuaGross

Differential Revision: D30167451

Pulled By: p-sun

fbshipit-source-id: 5327130064db52ac0086e1ae5541a1b3e3954f15
  • Loading branch information
janicduplessis authored and facebook-github-bot committed Aug 7, 2021
1 parent e35a963 commit 91cac20
Showing 1 changed file with 3 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public Class getShadowNodeClass() {
@Override
protected ReactSlider createViewInstance(ThemedReactContext context) {
final ReactSlider slider = new ReactSlider(context, null, STYLE);
ViewCompat.setAccessibilityDelegate(slider, sAccessibilityDelegate);
ViewCompat.setAccessibilityDelegate(slider, new ReactSliderAccessibilityDelegate());
return slider;
}

Expand Down Expand Up @@ -278,8 +278,8 @@ protected ViewManagerDelegate<ReactSlider> getDelegate() {
return mDelegate;
}

protected static class ReactSliderAccessibilityDelegate extends ReactAccessibilityDelegate {
private static boolean isSliderAction(int action) {
protected class ReactSliderAccessibilityDelegate extends ReactAccessibilityDelegate {
private boolean isSliderAction(int action) {
return (action == AccessibilityActionCompat.ACTION_SCROLL_FORWARD.getId())
|| (action == AccessibilityActionCompat.ACTION_SCROLL_BACKWARD.getId())
|| (action == AccessibilityActionCompat.ACTION_SET_PROGRESS.getId());
Expand All @@ -297,7 +297,4 @@ public boolean performAccessibilityAction(View host, int action, Bundle args) {
return rv;
}
};

protected static ReactSliderAccessibilityDelegate sAccessibilityDelegate =
new ReactSliderAccessibilityDelegate();
}

0 comments on commit 91cac20

Please sign in to comment.