Skip to content

Commit

Permalink
Add reactInstanceManager getter (software-mansion#2863)
Browse files Browse the repository at this point in the history
## Description
This PR adds a getter for `ReactInstanceManager`. The motivation for this PR is to fix issues software-mansion#2719 and software-mansion#2801

Those Android apps whose application class does not implement `ReactApplication` or simply have a different mechanism for storing a `ReactInstanceManager`, currently they have an incompatibility with `react-native-reanimated` ending in a crash when launching the app, as the issues indicates.
Normally, those apps are where [React Native is integrated with existing Android apps](https://reactnative.dev/docs/integration-with-existing-apps)

So, introducing this getter allows us to override this getter and implement a custom way to return the `ReactInstanceManager` to be used by `react-native-reanimated`.

<!--
Description and motivation for this PR.

Inlude Fixes #<number> if this is fixing some issue.

Fixes # .
-->

## Changes
- Added `getReactInstanceManager` method for android.
<!--
Please describe things you've changed here, make a **high level** overview, if change is simple you can omit this section.

For example:

- Added `foo` method which add bouncing animation
- Updated `about.md` docs
- Added caching in CI builds

-->

<!--

## Screenshots / GIFs

Here you can add screenshots / GIFs documenting your change.

You can add before / after section if you're changing some behavior.

### Before

### After

-->

## Test code and steps to reproduce
This is an example of how to use and override this getter. It is necessary to manually link `react-native-reanimated` before to be able to do it.
```java

public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {

    private static ReactInstanceManager mReactInstanceManager;
    ...

    @OverRide
    protected void onCreate(Bundle savedInstanceState) {
       ...
        List<ReactPackage> packages = new PackageList(getApplication()).getPackages();

        // Adding manually Reanimated package here, with overriding getReactInstanceManager method
         packages.add(new ReanimatedPackage() {
            @OverRide
            public ReactInstanceManager getReactInstanceManager(ReactApplicationContext reactContext) {
               // Implement here your way to get the ReactInstanceManager
               return MainActivity.getReactInstanceManager();
            }
         });

        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setCurrentActivity(this)
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .setJSIModulesPackage(new ReanimatedJSIModulePackage()) // Adding ReanimatedJSIModulePackage here
                .addPackages(packages)
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
       
        ...
    }
...
}
```
<!--
Please include code that can be used to test this change and short description how this example should work.
This snippet should be as minimal as possible and ready to be pasted into editor (don't exclude exports or remove "not important" parts of reproduction example)
-->

## Checklist

- [x] Included code example that can be used to test this change
- [ ] Updated TS types
- [ ] Added TS types tests
- [ ] Added unit / integration tests
- [ ] Updated documentation
- [ ] Ensured that CI passes
  • Loading branch information
wfolini authored and fluiddot committed Mar 10, 2022
1 parent e3cffea commit c9eaeb6
Showing 1 changed file with 15 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ public Map<String, ReactModuleInfo> getReactModuleInfos() {
private UIManagerModule createUIManager(final ReactApplicationContext reactContext) {
ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_START);
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "createUIManagerModule");
final ReactInstanceManager reactInstanceManager =
((ReactApplication) reactContext.getApplicationContext())
.getReactNativeHost()
.getReactInstanceManager();
final ReactInstanceManager reactInstanceManager = getReactInstanceManager(reactContext);
int minTimeLeftInFrameForNonBatchedOperationMs = -1;
try {
return new ReanimatedUIManager(
Expand All @@ -81,4 +78,18 @@ private UIManagerModule createUIManager(final ReactApplicationContext reactConte
ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_END);
}
}

/**
* Get the {@link ReactInstanceManager} used by this app. By default, assumes {@link
* ReactApplicationContext#getApplicationContext()} is an instance of {@link ReactApplication} and
* calls {@link ReactApplication#getReactNativeHost().getReactInstanceManager()}. Override this
* method if your application class does not implement {@code ReactApplication} or you simply have
* a different mechanism for storing a {@code ReactInstanceManager}, e.g. as a static field
* somewhere.
*/
public ReactInstanceManager getReactInstanceManager(ReactApplicationContext reactContext) {
return ((ReactApplication) reactContext.getApplicationContext())
.getReactNativeHost()
.getReactInstanceManager();
}
}

0 comments on commit c9eaeb6

Please sign in to comment.