7
votes

NOTE: I'm being provided those libraries, I can't make other ones for other architectures.

I'm currently porting an Android app to react-native that uses native libraries, but I only have the armeabi ones available. No problem so far with the original project, since armeabi is supported by all the x86/x86_64/armeabi-v7a/arm64-v8a devices.

Then when I generate a new project from react-native and include those armeabi files, while running the apk some libraries are not found. When I unzip the apk generated by the original project I can find the folder: lib/armeabi with all the libraries, so no problem. Now when I unzip my apk generated by react-native I have 2 folders: lib/armeabi-v7a and lib/x86 and some libraries are missing.

Here is my gradle configuration with react-native:

apply from: "../../node_modules/react-native/react.gradle"

/**
 * Set this to true to create two separate APKs instead of one:
 *   - An APK that only works on ARM devices
 *   - An APK that only works on x86 devices
 * The advantage is the size of the APK is reduced by about 4MB.
 * Upload all the APKs to the Play Store and people will download
 * the correct one based on the CPU architecture of their device.
 */
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Run Proguard to shrink the Java bytecode in release builds.
 */
def enableProguardInReleaseBuilds = false

android {
    compileSdkVersion 23
    buildToolsVersion '23.0.3'

    defaultConfig {
        applicationId "com.poc"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
    }

    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86"
        }
    }

    buildTypes {
        release {
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }

        veryVerbose {

        }
    }

    signingConfigs {
        releaseConfig {
        }

        buildTypes {
            release {
                debuggable true
                jniDebuggable false
                signingConfig signingConfigs.releaseConfig
            }
        }
    }

    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // 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 fileTree(dir: "libs", include: ["*.jar"])

    // Player library
    veryVerboseCompile fileTree(dir: 'veryVerboseLibs', include: ['*.jar'])
    debugCompile fileTree(dir: 'releaseLibs', include: ['*.jar'])
    releaseCompile fileTree(dir: 'releaseLibs', include: ['*.jar'])

    // Google
    compile "com.android.support:appcompat-v7:23.0.1"

    // Square
    compile 'com.jakewharton:butterknife:8.2.1'
    apt 'com.jakewharton:butterknife-compiler:8.2.1'

    // From node_modules
    compile "com.facebook.react:react-native:+"
}

Seems like react-native auto-generate some configuration regarding architectures, a bit new to me, I would need to tell gradle to build for armeabi and include all those libraries into a lib/armeabi folder in my final apk.

And basically what I get from logcat and running the apk is:

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.siminntvpoc-2/base.apk"],nativeLibraryDirectories=[/data/app/com.siminntvpoc-2/lib/x86, /data/app/com.siminntvpoc-2/base.apk!/lib/x86, /vendor/lib, /system/lib]]] couldn't find "libViewRightWebClient.so"
2
So your app is building fine? This error you must have gotten only in emulator not in actual device. Is that the case ?Ashish Rawat
Also take into account that react native doesn't support 3rd party 64bit libraries and cannot mix+match 32 and 64bit libraries (as of August 2017)Arnold Schrijver

2 Answers

4
votes

You have to specify what kind of architecture you want in application.mk.

To support all architecture use this attribute APP_ABI := all in application.mk file

here is document https://developer.android.com/ndk/guides/application_mk.html

2
votes

if you use the Experimental Gradle Build

add this to build.gradle

abiFilters.addAll([
            "armeabi-v7a",
            "arm64-v8a",
            "x86",
            "x86_64"
    ])

else

APP_ABI:=all in Application.mk

More