How to use Realm in a library

Viewed 1968

i'm trying to understand how to use Realm in a library that i'm making, i now understand RealmModules after a couple of days of research (if someone from Realm reads this, you should really improve on documentation about use in libraries). I've made a simple class that gives me the realm with library configuration:

object ChatRealm {
    fun getChatRealm(): Realm{
        val config = RealmConfiguration.Builder()
                .name("mtchat_realmDB")
                .schemaVersion(2)
                .deleteRealmIfMigrationNeeded()
                .modules(ChatModule())
                .build()
        return Realm.getInstance(config)
    }
}

the module is this

@RealmModule(library = true, allClasses = true)
class ChatModule {}

and in the project Application class i setup realm like this

class App: Application() {
    override fun onCreate() {
        super.onCreate()

        initRealm()
        setupRealm()
    }

    private fun initRealm() {
        Realm.init(this)
    }

    private fun setupRealm(){
        Realm.setDefaultConfiguration(
                RealmConfiguration.Builder()
                        .deleteRealmIfMigrationNeeded()
                        .modules(Realm.getDefaultModule(), ChatModule())
                        .build()
        )
    }
}

Now the trouble i'm having is that the build is failing or the app is crashing for various reasons based on how i configure the gradle files.

My :app gradle is this

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'realm-android'

repositories {
    maven { url "https://jitpack.io" }
    maven { url 'https://maven.google.com' }
    mavenCentral()
}

buildscript {
    repositories {
        jcenter()
    }
}

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.0"
    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        vectorDrawables.useSupportLibrary= true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:26.0.2'
    compile 'com.android.support:design:26.0.2'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    compile 'com.android.support:support-vector-drawable:26.0.2'
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    compile project(':mtchat')
}

and my library gradle is this

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'

repositories {
    maven { url "https://jitpack.io" }
    maven { url 'https://maven.google.com' }
    mavenCentral()
}

buildscript {
    repositories {
        jcenter()
    }
}

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.0"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
    }

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

}

dependencies {
    compile "com.android.support:appcompat-v7:$compat_version"
    compile "com.android.support:support-v4:$compat_version"
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    compile "com.android.support:cardview-v7:$compat_version"
    compile "com.android.support:recyclerview-v7:$compat_version"
    compile "com.android.support:design:$compat_version"
    compile "de.hdodenhof:circleimageview:2.1.0"
    compile 'com.github.bumptech.glide:glide:4.1.1'
    compile 'com.android.volley:volley:1.0.0'
}

and this is my project gradle

buildscript {
    ext.kotlin_version = '1.1.4-3'
    ext.compat_version = '26.0.2'

    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "io.realm:realm-gradle-plugin:3.7.2"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

and based on if i add or not the apply plugin: 'realm-android' to the :app module i get either RealmObject "X" is not part of the schema for this realm or if i add the plugin to the app gradle it fails to build the project completely.

Is there anyone that has used Realm in a library and wants to explain how, clearly and in depth, maybe this could be used as future reference

EDIT: With the above configuration i get this error when building

Execution failed for task ':app:transformClassesWithDexForDebug'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexException: Multiple dex files define Lio/realm/ChatRealmProxyInterface;

EDIT 2:

I managed to get it working by defining modules for both app and library and avoiding naming the realm models in the app the same as the ones in the library ( is this required? Or is there a way to isolate the library models so that the user can use the same names that the library models use?) Still this took me 2 days of research and i'm still unsure if I'm doing it right. It would be REALLY great if someone with more knowledge than me made a nice tutorial or something.

2 Answers
Related