React-native: "SoLoader.init() not yet called" when integrating react-native into existing android-app

Created on 8 Aug 2019  路  12Comments  路  Source: facebook/react-native

React Native version:

System:
    OS: macOS High Sierra 10.13.6
    CPU: (4) x64 Intel(R) Core(TM) i5-2400S CPU @ 2.50GHz
    Memory: 107.27 MB / 14.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 10.16.1 - /usr/local/bin/node
    Yarn: 1.17.3 - /usr/local/bin/yarn
    npm: 6.10.3 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
    Android SDK:
      API Levels: 23, 25, 26, 27, 28
      Build Tools: 23.0.1, 26.0.1, 26.0.3, 27.0.3, 28.0.3
      System Images: android-27 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom
  IDEs:
    Android Studio: 3.4 AI-183.6156.11.34.5692245
    Xcode: 10.1/10B61 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.8.6 => 16.8.6
    react-native: 0.60.4 => 0.60.4
  npmGlobalPackages:
    react-native-cli: 2.0.1

Steps To Reproduce

  1. create react-native-app
  2. create android-app
  3. follow the official guide of react native to integrate react-native-app into existing android-app: https://facebook.github.io/react-native/docs/integration-with-existing-apps.html
  4. start android-app and open react-native-app

At this point, the react-native-app should open, not crashing.

I get this error-msg:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapplication, PID: 9668
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication/com.example.myapplication.MainActivity}: java.lang.RuntimeException: SoLoader.init() not yet called
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.lang.RuntimeException: SoLoader.init() not yet called
        at com.facebook.soloader.SoLoader.assertInitialized(SoLoader.java:781)
        at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:505)
        at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:484)
        at com.facebook.react.ReactInstanceManagerBuilder.getDefaultJSExecutorFactory(ReactInstanceManagerBuilder.java:304)
        at com.facebook.react.ReactInstanceManagerBuilder.build(ReactInstanceManagerBuilder.java:279)
        at com.example.myapplication.MainActivity.onCreate(MainActivity.java:45)
        at android.app.Activity.performCreate(Activity.java:7009)
        at android.app.Activity.performCreate(Activity.java:7000)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)聽
        at android.app.ActivityThread.-wrap11(Unknown Source:0)聽
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)聽
        at android.os.Handler.dispatchMessage(Handler.java:106)聽
        at android.os.Looper.loop(Looper.java:164)聽
        at android.app.ActivityThread.main(ActivityThread.java:6494)聽
        at java.lang.reflect.Method.invoke(Native Method)聽
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)聽
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)聽

Bug Android

Most helpful comment

You need to override the onCreate function and call SoLoader.init(this, /* native exopackage */ false);

See this example

All 12 comments

You need to override the onCreate function and call SoLoader.init(this, /* native exopackage */ false);

See this example

After doing that I get this error:

E/SoLoader: couldn't find DSO to load: libhermes.so
E/AndroidRuntime: FATAL EXCEPTION: create_react_context
    Process: com.example.myapplication, PID: 15436
    java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so
        at com.facebook.soloader.SoLoader.doLoadLibraryBySoName(SoLoader.java:738)
        at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:591)
        at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:529)
        at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:484)
        at com.facebook.hermes.reactexecutor.HermesExecutor.<clinit>(HermesExecutor.java:20)
        at com.facebook.hermes.reactexecutor.HermesExecutorFactory.create(HermesExecutorFactory.java:27)
        at com.facebook.react.ReactInstanceManager$5.run(ReactInstanceManager.java:949)
        at java.lang.Thread.run(Thread.java:764)

And if I implement _hermes_, I get this error-msg:

E/AndroidRuntime: FATAL EXCEPTION: create_react_context
    Process: com.example.myapplication, PID: 16004
    java.lang.RuntimeException: Unable to load script. Make sure you're either running a Metro server (run 'react-native start') or that your bundle 'index.android.bundle' is packaged correctly for release.
        at com.facebook.react.bridge.CatalystInstanceImpl.jniLoadScriptFromAssets(Native Method)
        at com.facebook.react.bridge.CatalystInstanceImpl.loadScriptFromAssets(CatalystInstanceImpl.java:220)
        at com.facebook.react.bridge.JSBundleLoader$1.loadScript(JSBundleLoader.java:31)
        at com.facebook.react.bridge.CatalystInstanceImpl.runJSBundle(CatalystInstanceImpl.java:249)
        at com.facebook.react.ReactInstanceManager.createReactContext(ReactInstanceManager.java:1155)
        at com.facebook.react.ReactInstanceManager.access$900(ReactInstanceManager.java:124)
        at com.facebook.react.ReactInstanceManager$5.run(ReactInstanceManager.java:948)
        at java.lang.Thread.run(Thread.java:764)

I started my metro-bundler, but there is no difference.
My activity's function onCreate looks like this:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!Settings.canDrawOverlays(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                        Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
            }
        }

        SoLoader.init(this, /**/ false);
        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setCurrentActivity(this)
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        // The string here (e.g. "MyReactNativeApp") has to match
        // the string in AppRegistry.registerComponent() in index.js
        mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);

        setContentView(mReactRootView);
    }

And my app build.gradle looks like this:

apply plugin: 'com.android.application'

project.ext.react = [
        entryFile: "index.js",
        enableHermes: true,  // clean and rebuild if changing
]

def enableHermes = project.ext.react.get("enableHermes", false);

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    packagingOptions {
        pickFirst '**/armeabi-v7a/libc++_shared.so'
        pickFirst '**/x86/libc++_shared.so'
        pickFirst '**/arm64-v8a/libc++_shared.so'
        pickFirst '**/x86_64/libc++_shared.so'
        pickFirst '**/x86/libjsc.so'
        pickFirst '**/armeabi-v7a/libjsc.so'
    }
}

dependencies {
    implementation 'androidx.appcompat:appcompat:1.0.0'
    implementation "com.facebook.react:react-native:+"
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    if (enableHermes) {
        def hermesPath = "../../androidxlooking/node_modules/hermesvm/android/";
        debugImplementation files(hermesPath + "hermes-debug.aar")
        releaseImplementation files(hermesPath + "hermes-release.aar")
    } else {
        implementation jscFlavor
    }
}

@tbergq

Yeah, I think there is a an open issue for that, check this #25923

You are right, I close this issue, thanks @tbergq

I fixed my problem editing this line in my app/build.gradle:
I have a monorepository, so my path was different. I had to define the path in this line to find my metro-bundler:
project.ext.react = [ entryFile: "index.js", root: "YOUR_PATH_TO_YOUR_INDEX", enableHermes: true, // clean and rebuild if changing ]

Did that also solve the java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so?

yes, if you integrate _hermes_ in your app/build.gradle, it solves the problem @tbergq

Hmm, ok. I also suffered both these problems. It was the suggestion of guys from our android team to put the SoLoader.init in the onCreate function, though it felt weird, it solved that crash, but brought me the UnsatisfiedLinkError.

I am quite certain that my path to root is set correctly, but I probably also need to remove the init from onCreate and find the real source of that error in my case.

I fixed my problem editing this line in my app/build.gradle:
I have a monorepository, so my path was different. I had to define the path in this line to find my metro-bundler:

project.ext.react = [
        entryFile: "index.js",
        root: "YOUR_PATH_TO_YOUR_INDEX",
        enableHermes: true,  // clean and rebuild if changing
]

What path enter here root: "YOUR_PATH_TO_YOUR_INDEX",can you for example?

I fixed the error by adding this override to my MainApplication.java:

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

I have enabled hermes and even changed the root folder name accordingly but still I am unable to load script, its not able to locate index.js

After add SoLoader.init(this, /* native exopackage */ false);
I got this, someone know what can be ?
image

Was this page helpful?
0 / 5 - 0 ratings