title: How to solve "libmain.so not found" while using Unity as a library in Android application with latest AndroidX Versions out of ReactNative
body: <p>We have a ReactNative application that has integrated <strong>Unity</strong> based on <a href="https://github.com/f111fei/react-native-unity-view" rel="noreferrer">react-native-unity-view</a> successfully as a library for quite a long time. However, after most recent updates on ReactNative regarding AndroidX and latest SDK-changes, we're running into the issue <strong>"libmain.so not found"</strong>. This exception happens on the very first attempt to display a Unity-View.</p>
  
  <p><em>There is a similar <a href="https://stackoverflow.com/questions/58751549/unable-to-load-libmain-so-in-android-studio-and-unity-as-library">issue</a> on SO, please don't mark as duplicate as our approach might be different and particulary since we give many many more details here.</em></p>
  
  <p>There is a running and still working example on GitHub (based on ReactNative 0.57): <a href="https://github.com/f111fei/react-native-unity-demo" rel="noreferrer">https://github.com/f111fei/react-native-unity-demo</a>.
  As long as this project is based on ReactNative 0.57 and its appropriate gradle-settings, everything works fine.
  But as soon as we upgrade to the latest ReactNative version (and even 0.60 for example), which gives us an android-folder that is very different against to the older one), the issue happens with a crash of the application. <em>(We also tried to set up everything from scratch to exclude the possibility that this issue was due to upgrades. With RN 0.57 everything still works fine, with RN 0.60 and above not)</em></p>
  
  <p>The exception is as follows:</p>
  
  <pre><code>E Unity   : Failed to load 'libmain.so', the application will terminate.
  D AndroidRuntime: Shutting down VM
  E AndroidRuntime: FATAL EXCEPTION: main
  E AndroidRuntime: Process: com.rnunitydemo, PID: 16887
  E AndroidRuntime: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.rnunitydemo-bKGyotdcwjVnBxuR9zLE4Q==/base.apk"],nativeLibraryDirectories=[/data/app/com.rnunitydemo-bKGyotdcwjVnBxuR9zLE4Q==/lib/arm64, /data/app/com.rnunitydemo-bKGyotdcwjVnBxuR9zLE4Q==/base.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]] couldn't find "libmain.so"
  </code></pre>
  
  <p>First I'm going to list the android-folder and gradle-files from most recent version, where the crash happens. After that, I will list the files where everything works fine:</p>
  
  <h1>Not working (newer) Version</h1>
  
  <p><strong>./android/build.gradle:</strong></p>
  
  <pre><code>buildscript {
      ext {
          buildToolsVersion = "28.0.3"
          minSdkVersion = 16
          compileSdkVersion = 28
          targetSdkVersion = 28
      }
      repositories {
          google()
          jcenter()
      }
      dependencies {
          classpath("com.android.tools.build:gradle:3.4.2")
      }
  }
  
  allprojects {
      repositories {
          mavenLocal()
          maven {
              // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
              url("$rootDir/../node_modules/react-native/android")
          }
          maven {
              // Android JSC is installed from npm
              url("$rootDir/../node_modules/jsc-android/dist")
          }
  
          google()
          jcenter()
          maven { url 'https://jitpack.io' }
      }
  }
  </code></pre>
  
  <p><strong>./android/settings.gradle:</strong></p>
  
  <pre><code>rootProject.name = 'rnunitydemo'
  
  apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
  
  include ":UnityExport"
  project(":UnityExport").projectDir = file("./UnityExport")
  
  
  include ':app'
  </code></pre>
  
  <p><strong>./android/app/build.gradle:</strong></p>
  
  <pre><code>apply plugin: "com.android.application"
  
  import com.android.build.OutputFile
  
  project.ext.react = [
      entryFile: "index.js",
      enableHermes: false,  // clean and rebuild if changing
  ]
  
  apply from: "../../node_modules/react-native/react.gradle"
  
  def enableSeparateBuildPerCPUArchitecture = false
  
  def enableProguardInReleaseBuilds = false
  
  def jscFlavor = 'org.webkit:android-jsc:+'
  
  def enableHermes = project.ext.react.get("enableHermes", false);
  
  android {
      compileSdkVersion rootProject.ext.compileSdkVersion
  
      compileOptions {
          sourceCompatibility JavaVersion.VERSION_1_8
          targetCompatibility JavaVersion.VERSION_1_8
      }
  
      defaultConfig {
          applicationId "com.rnunitydemo"
          minSdkVersion rootProject.ext.minSdkVersion
          targetSdkVersion rootProject.ext.targetSdkVersion
          versionCode 1
          versionName "1.0"
      }
      splits {
          abi {
              reset()
              enable enableSeparateBuildPerCPUArchitecture
              universalApk false  // If true, also generate a universal APK
              include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
          }
      }
      signingConfigs {
          debug {
              storeFile file('debug.keystore')
              storePassword 'android'
              keyAlias 'androiddebugkey'
              keyPassword 'android'
          }
      }
      buildTypes {
          debug {
              signingConfig signingConfigs.debug
          }
          release {
              signingConfig signingConfigs.debug
              minifyEnabled enableProguardInReleaseBuilds
              proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
          }
      }
      // applicationVariants are e.g. debug, release
      applicationVariants.all { variant -&gt;
          variant.outputs.each { output -&gt;
              // For each separate APK per architecture, set a unique version code as described here:
              // https://developer.android.com/studio/build/configure-apk-splits.html
              def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
              def abi = output.getFilter(OutputFile.ABI)
              if (abi != null) {  // null for the universal-debug, universal-release variants
                  output.versionCodeOverride =
                          versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
              }
  
          }
      }
  }
  
  dependencies {
      implementation fileTree(dir: "libs", include: ["*.jar"])
      implementation "com.facebook.react:react-native:+"  // From node_modules
  
      if (enableHermes) {
          def hermesPath = "../../node_modules/hermes-engine/android/";
          debugImplementation files(hermesPath + "hermes-debug.aar")
          releaseImplementation files(hermesPath + "hermes-release.aar")
      } else {
          implementation jscFlavor
      }
  }
  
  task copyDownloadableDepsToLibs(type: Copy) {
      from configurations.compile
      into 'libs'
  }
  
  apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
  </code></pre>
  
  <p><strong>./android/UnityExport/build.gradle:</strong></p>
  
  <pre><code>// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
  
  buildscript {
      repositories {
          google()
          jcenter()
      }
  
      dependencies {
          classpath("com.android.tools.build:gradle:3.4.2")
      }
  }
  
  allprojects {
      repositories {
          google()
          jcenter()
          flatDir {
              dirs 'libs'
          }
      }
  }
  
  apply plugin: 'com.android.library'
  
  
  dependencies {
      api fileTree(include: ['*.jar'], dir: 'libs')
  }
  
  android {
      compileSdkVersion 28
      buildToolsVersion '28.0.2'
  
      compileOptions {
          sourceCompatibility JavaVersion.VERSION_1_8
          targetCompatibility JavaVersion.VERSION_1_8
      }
  
      defaultConfig {
          minSdkVersion 16
          targetSdkVersion 28
          ndk {
              abiFilters 'armeabi-v7a', 'x86'
          }
          multiDexEnabled true
          versionCode 1
          versionName '0.1'
      }
  
      lintOptions {
          abortOnError false
      }
  
      aaptOptions {
          noCompress = ['.unity3d', '.ress', '.resource', '.obb']
          ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~"
      }
  
      buildTypes {
          debug {
              minifyEnabled false
              useProguard false
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'
              signingConfig signingConfigs.debug
              jniDebuggable true
          }
          release {
              minifyEnabled false
              useProguard false
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'
              signingConfig signingConfigs.debug
          }
      }
  
      packagingOptions {
          doNotStrip '*/armeabi-v7a/*.so'
          doNotStrip '*/x86/*.so'
      }
  
  
  }
  </code></pre>
  
  <p>All these files above lead to a crash ("libmain.so not found") as soon as Unity will be launched.</p>
  
  <h1>Working (older) Version</h1>
  
  <p>In our previous version, as it can be found <a href="https://github.com/itinance/react-native-unity-demo" rel="noreferrer">on GitHub</a>, everything went fine:</p>
  
  <p><strong>./android/build.gradle:</strong></p>
  
  <pre><code>buildscript {
      ext {
          buildToolsVersion = "27.0.3"
          minSdkVersion = 16
          compileSdkVersion = 27
          targetSdkVersion = 26
          supportLibVersion = "27.1.1"
      }
      repositories {
          jcenter()
          google()
      }
      dependencies {
          classpath 'com.android.tools.build:gradle:3.1.4'
      }
  }
  
  allprojects {
      repositories {
          mavenLocal()
          jcenter()
          google()
          maven {
              // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
              url "$rootDir/../node_modules/react-native/android"
          }
          flatDir {
              dirs project(':UnityExport').file('libs')
          }
      }
  }
  
  task wrapper(type: Wrapper) {
      gradleVersion = '4.4'
      distributionUrl = distributionUrl.replace("bin", "all")
  }
  </code></pre>
  
  <p><strong>./android/settings.gradle:</strong></p>
  
  <pre><code>rootProject.name = 'rnunitydemo'
  include ':react-native-unity-view'
  project(':react-native-unity-view').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-unity-view/android')
  
  include ":UnityExport"
  project(":UnityExport").projectDir = file("./UnityExport")
  
  include ':app'
  </code></pre>
  
  <p><strong>./android/app/build.gradle:</strong></p>
  
  <pre><code>apply plugin: "com.android.application"
  
  import com.android.build.OutputFile
  
  project.ext.react = [
      entryFile: "index.js"
  ]
  
  apply from: "../../node_modules/react-native/react.gradle"
  
  def enableSeparateBuildPerCPUArchitecture = false
  
  /**
   * Run Proguard to shrink the Java bytecode in release builds.
   */
  def enableProguardInReleaseBuilds = false
  
  android {
      compileSdkVersion rootProject.ext.compileSdkVersion
      buildToolsVersion rootProject.ext.buildToolsVersion
  
      defaultConfig {
          applicationId "com.rnunitydemo"
          minSdkVersion rootProject.ext.minSdkVersion
          targetSdkVersion rootProject.ext.targetSdkVersion
          versionCode 1
          versionName "1.0"
          ndk {
              abiFilters "armeabi-v7a", "x86"
          }
      }
  
      lintOptions {
          checkReleaseBuilds false
          // Or, if you prefer, you can continue to check for errors in release builds,
          // but continue the build even when errors are found:
          abortOnError false
      }
  
      splits {
          abi {
              reset()
              enable enableSeparateBuildPerCPUArchitecture
              universalApk false  // If true, also generate a universal APK
              include "armeabi-v7a", "x86"
          }
      }
  
      signingConfigs {
          release {
              // storeFile file(MYAPP_RELEASE_STORE_FILE)
              // storePassword MYAPP_RELEASE_STORE_PASSWORD
              // keyAlias MYAPP_RELEASE_KEY_ALIAS
              // keyPassword MYAPP_RELEASE_KEY_PASSWORD
          }
      }
  
      buildTypes {
          debug {
              manifestPlaceholders = [
                  "DEBUGGABLE": "true"
              ]
          }
          release {
              manifestPlaceholders = [
                  "DEBUGGABLE": "false"
              ]
              minifyEnabled enableProguardInReleaseBuilds
              proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
              signingConfig signingConfigs.release
          }
      }
      // applicationVariants are e.g. debug, release
      applicationVariants.all { variant -&gt;
          variant.outputs.each { output -&gt;
              // For each separate APK per architecture, set a unique version code as described here:
              // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
              def versionCodes = ["armeabi-v7a":1, "x86":2]
              def abi = output.getFilter(OutputFile.ABI)
              if (abi != null) {  // null for the universal-debug, universal-release variants
                  output.versionCodeOverride =
                          versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
              }
          }
      }
  }
  
  dependencies {
      compile project(':react-native-unity-view')
      implementation fileTree(dir: "libs", include: ["*.jar"])
      implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
      implementation "com.facebook.react:react-native:+"  // From node_modules
  }
  
  // Run this once to be able to run the application with BUCK
  // puts all compile dependencies into folder libs for BUCK to use
  task copyDownloadableDepsToLibs(type: Copy) {
      from configurations.compile
      into 'libs'
  }
  </code></pre>
  
  <p><strong>./android/UnityExport/build.gradle:</strong></p>
  
  <pre><code>(same as above)
  </code></pre>
  
  <p>There are some other reports according to this issue in the <a href="https://forum.unity.com/threads/integration-unity-as-a-library-in-native-android-app.685240/" rel="noreferrer">official Unity2D-Forums</a>, but without any working solution. According to a <a href="https://forum.unity.com/threads/integration-unity-as-a-library-in-native-android-app.685240/#post-5177588" rel="noreferrer">comment</a> we are aware of using the very same <strong>abiFilter</strong>-Setting in both <strong>build.gradle</strong>-Files (this from our app and the build-gradle from UnityExport), but it didn't solve the issue either.</p>
  
  <p>Can someone help please?</p>
  
  <p>** Update **</p>
  
  <p>System information of development machine:</p>
  
  <pre><code>System:
      OS: macOS Mojave 10.14.6
      CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
      Memory: 112.35 MB / 32.00 GB
      Shell: 5.0.11 - /usr/local/bin/bash
  
    SDKs:
      iOS SDK:
        Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
      Android SDK:
        API Levels: 23, 25, 26, 27, 28, 29
        Build Tools: 23.0.1, 25.0.0, 25.0.1, 25.0.2, 26.0.1, 27.0.3, 28.0.3, 29.0.0, 29.0.2
        System Images: android-29 | Google APIs Intel x86 Atom
        Android NDK: 20.0.5594570
    IDEs:
      Android Studio: 3.5 AI-191.8026.42.35.5900203
      Xcode: 11.2.1/11B500 - /usr/bin/xcodebuild
    Binaries:
      Node: 10.17.0 - /usr/local/opt/node@10/bin/node
      Yarn: 1.16.0 - /usr/local/bin/yarn
      npm: 6.11.3 - /usr/local/opt/node@10/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    npmPackages:
      react: 16.9.0 =&gt; 16.9.0
      react-native: 0.61.4 =&gt; 0.61.4
    npmGlobalPackages:
      react-native-cli: 2.0.1
  </code></pre>