What is the correct way to use productFlavors with sqlcipher + ndk?


#1

As previously discussed under this thread -

SQLCipher for Android does not provide libraries for arm64-v8a, mips, mips64, and x86_64 and it was suggested that - “One solution to this when using SQLCipher for Android is to only package your other 3rd party native libraries for the platforms that SQLCipher for Android support (i.e., armeabi, armeabi-v7a, and x86).”

So I ended up using abiFilters for only 3 mentioned architecture. I am using gradle-experimental:0.7.0, and with the help of official gradle experimental documentation, I made following build.gradle -

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"

        defaultConfig {
            applicationId "com.demo.testapp"
            minSdkVersion.apiLevel 15
            targetSdkVersion.apiLevel 23
            versionCode 101
            versionName "1.0.1"
        }
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles.add(file("proguard-rules.pro"))
                signingConfig = $("android.signingConfigs.myConfig")
            }
        }
    }

    android.signingConfigs {
        create("myConfig") {
            storeFile "E:/AndroidProjects/mykeystore.jks"
            storePassword "mypassword"
            keyAlias "myalias"
            keyPassword "mypassword"
            storeType "jks"
        }
    }

    android.ndk {
        moduleName = "settings-jni"
        abiFilters.add("armeabi")
        abiFilters.add("armeabi-v7a")
        abiFilters.add("x86")
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.android.support:design:23.3.0'
    compile 'net.zetetic:android-database-sqlcipher:3.4.0@aar'
}

abiFilters, as mentioned in above gradle sample, solved my issue at least little bit. So far, from user reviews I have learnt that my app is crashing as soon as it tries to access database on at least 2 known mobiles (Xiaomi Mi 4i and Lenovo Phab Plus). Neither I nor my users are techy (infact we all are just medical doctors), so I am unable to get any crash log from them. (Any ideas?)

So, I wanted to try a different approach. I am trying to split the app into multiple architecture specific apks and one fat apk (which contains all architecture). Being a newbie myself, I couldn’t figure out the correct way, so that it can split as per sqlcipher requirements.

I tried to use splits in above mentioned gradle, but failed -

android {
    // Rest of Gradle file
        splits {
            abi {
            enable true
            reset()
            include 'armeabi', 'armeabi-v7a', 'x86'
            universalApk true
        }
    }
}

//Ensures architecture specific APKs have a higher version code
//(otherwise an x86 build would end up using the arm build, which x86 devices can run)
ext.versionCodes = [armeabi:1, 'armeabi-v7a':3, x86:6]

android.applicationVariants.all { variant ->
    // assign different version code for each output
    variant.outputs.each { output ->
        int abiVersionCode = project.ext.versionCodes.get(output.getFilter(OutputFile.ABI)) ?: 0
        output.versionCodeOverride = (abiVersionCode * 1000) + android.defaultConfig.versionCode
    }
}

I got partially successful in using productFlavors, but still couldn’t figure out the correct way -

Inside android { } block :
            create("arm") {
                ndk {
                    // You can customize the NDK configurations for each
                    // productFlavors and buildTypes.
                    abiFilters.add("armeabi-v7a")
                }
            }
            create("fat") {
                // If ndk.abiFilters is not configured, the application
                // compile and package all suppported ABI.
            }
        }

Inside model { } but outside android { } block :
components.android {
        binaries.afterEach { binary ->
            binary.mergedNdkConfig.cppFlags.add(
                    "-DVARIANT=\"" + binary.name + "\"")
        }
    }

Can anyone please help me make the correct build.gradle withproductFlavours + sqlcipher + ndk?
Thanks,


#2

There are many third-party crash libraries, you might also look into crash reporting from Analytics for Android.

We don’t create platform specific APK’s, however this suggests you might include abiFilter within your productFlavors, similar to this:

android {
  …
  flavorGroups = "abi"
   x86 {
      flavorGroup "abi"
      ndk.abiFilter "x86"
      // this is the flavor part of the version code.
      // It must be higher than the arm one for devices supporting
      // both, as x86 is preferred.
      versionCode = 3
    }
    arm {
      flavorGroup "abi"
      ndk.abiFilter "armeabi-v7a"
      versionCode = 1
    }
    …
}

#3

Thank you for your quick reply. I will look into both - the Crash analysis and flavourGroups.


#4

Thank you for this mention. I was finally able to get the Exception. It says -

net.sqlcipher.database.SQLiteException: attempt to write a readonly database: DELETE failed setting locale

The environment in which I am facing this error is -
Mobile Model : Mi 4i
Android 5.0.2
Database is already supplied with app (or downloaded from net and then located by app into External Storage). The same database is working in Android 4.2.2 (Samsung Galaxy Grand) and 6.0.1 (OnePlus), so I am sure database is NOT corrupt. I have found out the same error is faced by many others, as being discussed under this thread of GitHub.
unfortunately I don’t own this mobile, so I can’t perform any more experiment with it. But seeing others facing the same issue, there must be some work up going on. Kindly let me know, if there is a solution to this situation. I will follow the mentioned thread on GitHub too.

P.S. - I know, this message has gone off-topic as compared to title of this thread, but primary reason for productFlavor was to find out cause of app-crashing. If mods think to remove it from here or want me to open another thread for this, let me know.

Thanks,


#6

Did you ever get down to the bottom of your problem? Do you know exactly what’s causing the crash?