Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatibility with Custom React Native Integration with Existing Android Apps (Crash on launch) #2719

Open
1 of 3 tasks
wfolini opened this issue Dec 9, 2021 · 27 comments
Labels
Bug bug-bash-jan22 Issues visited during Bug Bash Jan 2022 Platform: Android This issue is specific to Android 🏠 Reanimated 2 Repro provided A reproduction with a snippet of code, snack or repo is provided

Comments

@wfolini
Copy link
Contributor

wfolini commented Dec 9, 2021

Description

The last v2.3.0 version introduced an issue that affects Android apps that have a custom React Native integration (see integration-with-existing-apps)

Currently, there is no documentation about how to integrate react-native-reanimated for those kinds of apps. I managed to make it work doing what I show in the code example section, on the main React Native activity.

I was not having any kind of issue with this integration using v2.2.4. After I updated to v2.3.0 I started facing this issue. (See crash on launch capture below)

I also checked where the issue comes from, and as the capture shows, it seems like that it was introduced here.
https://github.com/software-mansion/react-native-reanimated/blob/main/android/src/main/java/com/swmansion/reanimated/ReanimatedPackage.java#L70

It can be seen there that is trying to cast to a ReactApplication when instead the ReactInstanceManager builder in this case handles the application context just as Application
https://github.com/facebook/react-native/blob/main/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java#L155

Expected behavior

Android app should run correctly.

Actual behavior & steps to reproduce

Android app is crashing on launch.
image

Snack or minimal code example

import com.swmansion.reanimated.ReanimatedJSIModulePackage
....
public class MyReactActivity extends Activity implements DefaultHardwareBackBtnHandler {
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication()) // <= Crashing because of this
                .setCurrentActivity(this)
                .setBundleAssetName("index.android.bundle")
                .setJSIModulesPackage(new ReanimatedJSIModulePackage()) // <- Adding reanimated here
                .addPackages(packages)
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
       ...
    }
    ...
}

Example for reproducing this issue

https://github.com/WFolini/custom-rn-with-reanimated

Package versions

  • React Native: 64.2
  • React Native Reanimated: 2.3.0
  • NodeJS: 16.8.0
  • Java & Gradle: 1.8.0_292 & 6.8.3

Affected platforms

  • Android
  • iOS
  • Web
@github-actions
Copy link

github-actions bot commented Dec 9, 2021

Issue validator

The issue is valid!

@hstorz
Copy link

hstorz commented Dec 10, 2021

My app is also crashing on Android launch since the update to 2.3.0 from 2.2.4.
I got following Nullpointer from logcat:

12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.swmansion.reanimated.layoutReanimation.g.r(ReanimatedNativeHierarchyManager.java:1)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.facebook.react.uimanager.z0$m.execute(UIViewOperationQueue.java:1)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.facebook.react.uimanager.z0$a.run(UIViewOperationQueue.java:19)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.facebook.react.uimanager.z0.U(UIViewOperationQueue.java:10)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.facebook.react.uimanager.z0.s(UIViewOperationQueue.java:1)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.facebook.react.uimanager.z0$j.c(UIViewOperationQueue.java:6)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.facebook.react.uimanager.f.a(GuardedFrameCallback.java:1)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.facebook.react.modules.core.g$d.a(ReactChoreographer.java:7)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.facebook.react.modules.core.a$a$a.doFrame(ChoreographerCompat.java:1)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1008)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at android.view.Choreographer.doCallbacks(Choreographer.java:809)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at android.view.Choreographer.doFrame(Choreographer.java:740)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:995)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at android.os.Handler.handleCallback(Handler.java:938)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at android.os.Handler.dispatchMessage(Handler.java:99)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at android.os.Looper.loop(Looper.java:246)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at android.app.ActivityThread.main(ActivityThread.java:8633)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at java.lang.reflect.Method.invoke(Native Method)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)	
12-10 10:14:21.940	usap64	24924	-	E	AndroidRuntime	 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)	

@DrawGu
Copy link

DrawGu commented Dec 15, 2021

I also encountered the same issue.

@t3chcrazy
Copy link

t3chcrazy commented Dec 15, 2021

@hstorz do you have Proguard enabled in your app, I remember facing the same issue and I solved it by adding this rule in my proguard-rules.pro, -keep class com.swmansion.reanimated.** { *; }. Original issue link: #2727

@hstorz
Copy link

hstorz commented Dec 15, 2021

@t3chcrazy thanks for the reply. I use Proguard but only with this line: -keep class com.facebook.react.turbomodule.** { *; } that is mentioned in the reanimated docu. Will try it with your suggestion.

@hstorz
Copy link

hstorz commented Dec 15, 2021

@hstorz do you have Proguard enabled in your app, I remember facing the same issue and I solved it by adding this rule in my proguard-rules.pro, -keep class com.swmansion.reanimated.** { *; }. Original issue link: #2727

This fixed it for me. Tried with reanimated 1.3.1 on android release build. Thanks again!

@halaei
Copy link

halaei commented Dec 15, 2021

Adding -keep to Proguard didn't fixed it for me. I downgraded to 2.2.4.

@wfolini
Copy link
Contributor Author

wfolini commented Jan 6, 2022

This doesn't have anything to do with Proguard. It's an issue that exists whenever the android app uses ReactInstanceManager to build the React Native activity.

@tswicegood
Copy link

@wfolini do you have any additional info or related tickets you could include? Been seeing issues like this and have had a hard time tracking it down.

@wfolini
Copy link
Contributor Author

wfolini commented Jan 6, 2022

@tswicegood Here's a repo with a small android app to reproduce this issue
https://github.com/WFolini/custom-rn-with-reanimated

@github-actions github-actions bot added Platform: Android This issue is specific to Android Repro provided A reproduction with a snippet of code, snack or repo is provided Missing info The user didn't precise the problem enough and removed Missing info The user didn't precise the problem enough labels Jan 6, 2022
@dreson4
Copy link

dreson4 commented Jan 24, 2022

You'll have to edit your Application file and implement ReactApplication class.
Here is mine

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost =
      new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          return packages;
        }

        @Override
        protected String getJSMainModuleName() {
          return "index";
        }


      };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
  }

  /**
   * Loads Flipper in React Native templates. Call this in the onCreate method with something like
   * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
   *
   * @param context
   * @param reactInstanceManager
   */
  private static void initializeFlipper(
      Context context, ReactInstanceManager reactInstanceManager) {
    if (BuildConfig.DEBUG) {
      try {
        /*
         We use reflection here to pick up the class that initializes Flipper,
        since Flipper library is not available in release mode
        */
        Class<?> aClass = Class.forName("com.easywallet");
        aClass
            .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
            .invoke(null, context, reactInstanceManager);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (NoSuchMethodException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
    }
  }
}


And link it in your AndroidManifest.xml file

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.kiliwallet">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
      android:name=".MainApplication".    <- add this, name corresponds to the class name of Applicatoin
      ....other stuff here
       >
                 <other activities here>
    </application>
</manifest>

@jakub-gonet jakub-gonet added the bug-bash-jan22 Issues visited during Bug Bash Jan 2022 label Jan 28, 2022
@saghul
Copy link

saghul commented Feb 9, 2022

Rn can be used to build libraries too. It might not be desirable / possible for certain apps to implement ReactApplication.

piaskowyk pushed a commit that referenced this issue Feb 11, 2022
## Description
This PR adds a getter for `ReactInstanceManager`. The motivation for this PR is to fix issues #2719 and #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
fluiddot added a commit to WordPress/gutenberg that referenced this issue Feb 22, 2022
The downgrade is necessary in order to prevent a known issue in Reanimated (software-mansion/react-native-reanimated#2719).
fluiddot added a commit to WordPress/gutenberg that referenced this issue Mar 3, 2022
* Bump react-native-gesture-handler to 2.2.0

* Bump react-native-reanimated to 2.4.1

* Update babel config to support reanimated lib

* Update Android demo app to support new lib versions

* Add patch for react-native-gesture-handler

* Add patch for react-native-reanimated

Hermes engine has to be manually set because the library is not able to detect it automatically.

* Update iOS demo app to support new lib versions - It includes changing the Gutenberg class from NSObject to UIResponder

* Add Reanimated library to WPAndroid glue code

* Downgrade react-native-reanimated to 2.2.4

The downgrade is necessary in order to prevent a known issue in Reanimated (software-mansion/react-native-reanimated#2719).

* Use absolute path for reanimated babel plugin

Using the absolute path is required for Reanimated plugin when generating the JS bundle outside Gutenberg, like we do in Gutenberg Mobile.

* Update Jest setup to support Reanimated2

* Add google repository to react-native-bridge build

This is required to support the react-native-gesture-handler package.

* Point dependencies to their forked repository

* Update package-lock.json

* Remove react-native-reanimated patch

* Update react-native-editor Podfile.lock

* Update package-lock.json

* Silence react-native-gesture-handler warning

* Update package-lock.json

* Update gesture handler and reanimated package versions

* Bump react-native-gesture-handler to 2.2.0-wp-2

* Revert adding google repository to react-native-bridge build

* Update react-native-editor changelog

* Update Podfile.lock

* Bump react-native-gesture-handler to 2.2.0-wp-3

Co-authored-by: Gerardo <[email protected]>
fluiddot pushed a commit to wordpress-mobile/react-native-reanimated that referenced this issue Mar 10, 2022
## 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
@Legion2
Copy link

Legion2 commented Dec 5, 2022

We build a library which exposes UI as RN Fragments, we not control the activity and application and can not force users of the fragment to implement ReactApplication.

@duannianwww
Copy link

I also encountered the same issue,How to fix this error?

@ratz6
Copy link

ratz6 commented Jan 1, 2023

It works if we change our mainApplication file accordingly, but how do we achieve this by only changing our Activity file ?
@wfolini how'd you go ahead with it ?

@wfolini
Copy link
Contributor Author

wfolini commented Mar 9, 2023

In #2863 I explain the way that you can make it work by applying a different mechanism to infer the ReactInstanceManager instance needed for react-native-reanimated.
Have you guys tried it?

In this example code below, on getReactInstanceManager method, you guys have to implement by yourself the MainActivity.getReactInstanceManager(), or simply just return mReactInstanceManager

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();
       
        ...
    }
...
}

@AlanSl
Copy link

AlanSl commented May 12, 2023

@wfolini Thanks for this. Do you know what should replace the .setJSIModulesPackage(new ReanimatedJSIModulePackage()) part in React Native Reanimated 3.x with Fabric, now that ReanimatedJSIModulePackage has been removed?

I'm trying to adapt this to work in a React Fragment in a custom integration with new architecture enabled, and it gives this error, which I think is another new instance of this underlying issue (Reanimated doing some brittle under the hood auto-apply magic that assumes the default React Native android native app is being used):

com.facebook.react.uimanager.ReanimatedUIManager cannot be cast to com.facebook.react.fabric.FabricUIManager

@AlanSl
Copy link

AlanSl commented May 15, 2023

What worked for me here was, copying from the Reanimated / Fabric example repo - in particular, its MainActivity) which seems to include some changes since React Native 0.71 that are expected/essential but not mentioned in the out-of-date React Native app integration documentation?

The crucial one for me was adding this (this is my Kotlin adaptation of the linked example's Java plus a few tweaks to make it fit):

    protected open fun createReactActivityDelegate(): ReactActivityDelegate? {
        return DefaultReactActivityDelegate(
            this as ReactActivity, // My activity class more complex than `extends ReactActivity` so needed `as`
            "my-main-component-name",  // Taken from the "name" field in `app.json` in react native app root dir
            DefaultNewArchitectureEntryPoint.fabricEnabled,
            DefaultNewArchitectureEntryPoint.concurrentReactEnabled
        )
    }

This makes builds work, but I'm then getting errors caused by components missing stateNode so I suspect there's something else essential too.

@Eli-Nathan
Copy link

I couldn't get this solution to work. Since ReanimatedJSIModulePackage has been deprecated, I tried to implement the solution posted above without the .setJSIModulesPackage but the error still remains:

MyApplication cannot be cast to com.facebook.react.ReactApplication

I'm trying with react-native-reanimated v3.4.1 and react-native v0.68.5

Any more advice?

@Latropos
Copy link
Contributor

@wfolini
I was unable to build the app from reproduction, however you've merged your PR #2863 with claim in the description that this problem gets fixed there. So I probably can close it as completed

@poprapas
Copy link

but i still this issues
Error: Exception in HostFunction: java.lang.ClassCastException: com.facebook.react.uimanager.ReanimatedUIManager cannot be cast to com.facebook.react.fabric.FabricUIManager, js engine: hermes

platform os == android error, but ios work

how to fix?
my mainActivity.kt
package myproject

import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate

class MainActivity : ReactActivity() {

/**

  • Returns the name of the main component registered from JavaScript. This is used to schedule
  • rendering of the component.
    */
    override fun getMainComponentName(): String = "InsightX"

/**

  • Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
  • which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
    */
    override fun createReactActivityDelegate(): ReactActivityDelegate =
    DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
    }

help me, please

@ko-devHong
Copy link

@Latropos Why isn't the solution to this part written in the document?

@ko-devHong
Copy link

@wfolini v3 module ReanimatedJSIModulePackage has been deprecated

@hi-zp
Copy link

hi-zp commented Apr 1, 2024

same issue on RN 0.73.6 reanimated 3.8.1

@hi-zp
Copy link

hi-zp commented Apr 1, 2024

@ko-devHong i temporary fixed this, here is my code:

    private ReactInstanceManager mReactInstanceManager;

    protected CustomReactNativeHost(Application application) {
        super(application);
    }

    @Override
    public ReactInstanceManager getReactInstanceManager() {
        if (this.mReactInstanceManager == null) {
            ReactMarker.logMarker(ReactMarkerConstants.INIT_REACT_RUNTIME_START);
            ReactMarker.logMarker(ReactMarkerConstants.GET_REACT_INSTANCE_MANAGER_START);
            this.mReactInstanceManager = this.createReactInstanceManager();
            ReactMarker.logMarker(ReactMarkerConstants.GET_REACT_INSTANCE_MANAGER_END);
        }

        return this.mReactInstanceManager;
    }

    @Override
    public boolean hasInstance() {
        return this.mReactInstanceManager != null;
    }

    @Override
    public void clear() {
        if (this.mReactInstanceManager != null) {
            this.mReactInstanceManager.destroy();
            this.mReactInstanceManager = null;
        }
    }
    
    @Override
    public boolean getUseDeveloperSupport() {
        return false;
    }

    @Override
    protected List<ReactPackage> getPackages() {
        return null;
    }
}

public class MyApplication extends Application implements ReactApplication {
  @NonNull
  @Override
  public CustomReactNativeHost getReactNativeHost() {
    CustomReactNativeHost host = new CustomReactNativeHost(this) {
      @Override
      public boolean getUseDeveloperSupport() {
        return BuildConfig.DEBUG;
      }

      @Override
      protected List<ReactPackage> getPackages() {
        return packages;
      }

      @Nullable
      @Override
      protected DevSupportManagerFactory getDevSupportManagerFactory() {
        return super.getDevSupportManagerFactory();
      }

      @Override
      protected String getJSMainModuleName() {
        return "index";
      }

      @Nullable
      @Override
      protected JavaScriptExecutorFactory getJavaScriptExecutorFactory() {
        return new HermesExecutorFactory();
      }
    };
    return host;
  }
 。。。balabala
}

@yzhe554
Copy link

yzhe554 commented Jul 12, 2024

Please reopen the issue @Latropos The mentioned solution is with setJSIModulesPackage but it's removed in the new RNReanimated package.

@SeekingLight233
Copy link

@ko-devHong i temporary fixed this, here is my code:

    private ReactInstanceManager mReactInstanceManager;

    protected CustomReactNativeHost(Application application) {
        super(application);
    }

    @Override
    public ReactInstanceManager getReactInstanceManager() {
        if (this.mReactInstanceManager == null) {
            ReactMarker.logMarker(ReactMarkerConstants.INIT_REACT_RUNTIME_START);
            ReactMarker.logMarker(ReactMarkerConstants.GET_REACT_INSTANCE_MANAGER_START);
            this.mReactInstanceManager = this.createReactInstanceManager();
            ReactMarker.logMarker(ReactMarkerConstants.GET_REACT_INSTANCE_MANAGER_END);
        }

        return this.mReactInstanceManager;
    }

    @Override
    public boolean hasInstance() {
        return this.mReactInstanceManager != null;
    }

    @Override
    public void clear() {
        if (this.mReactInstanceManager != null) {
            this.mReactInstanceManager.destroy();
            this.mReactInstanceManager = null;
        }
    }
    
    @Override
    public boolean getUseDeveloperSupport() {
        return false;
    }

    @Override
    protected List<ReactPackage> getPackages() {
        return null;
    }
}

public class MyApplication extends Application implements ReactApplication {
  @NonNull
  @Override
  public CustomReactNativeHost getReactNativeHost() {
    CustomReactNativeHost host = new CustomReactNativeHost(this) {
      @Override
      public boolean getUseDeveloperSupport() {
        return BuildConfig.DEBUG;
      }

      @Override
      protected List<ReactPackage> getPackages() {
        return packages;
      }

      @Nullable
      @Override
      protected DevSupportManagerFactory getDevSupportManagerFactory() {
        return super.getDevSupportManagerFactory();
      }

      @Override
      protected String getJSMainModuleName() {
        return "index";
      }

      @Nullable
      @Override
      protected JavaScriptExecutorFactory getJavaScriptExecutorFactory() {
        return new HermesExecutorFactory();
      }
    };
    return host;
  }
 。。。balabala
}

Thank you bro!

We are using a hybrid app and I encountered this error when enabling Hermes on the Android side. Then I successfully resolved the issue by overriding getJavaScriptExecutorFactory when creating the Host.

class ReactHostManager private constructor() {

    //...

    private fun createHost(name: String,path: String?): ReactNativeHost {
        return CommonHost(name,path)
    }

    private inner class CommonHost(val name : String,val path: String?) : ReactNativeHost(App.instance) {

        //...
        override fun getJavaScriptExecutorFactory(): JavaScriptExecutorFactory? {
            return HermesExecutorFactory()
        }

    }


}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug bug-bash-jan22 Issues visited during Bug Bash Jan 2022 Platform: Android This issue is specific to Android 🏠 Reanimated 2 Repro provided A reproduction with a snippet of code, snack or repo is provided
Projects
None yet
Development

No branches or pull requests