different Database library with same methods in different flavours Best Practice?

I have two different falvours in my Androdi app that should use different SQL implementations. One use:

android.database.sqlite.SQLiteDatabase

and second:

net.sqlcipher.database.SQLiteDatabase

I have methods like that:

getAll(SQLiteDatabase conn)

How should I solve this situation to avoid copy&paste? What is the best pratcice? I have few ideas: first one (the worst with a lot of copypaste) is to provide different methods :

 getAll(android.database.sqlite.SQLiteDatabase conn)
 getAll(net.sqlcipher.database.SQLiteDatabase conn)

second is to wrap this class with some other in every flavour importing proper database(aggregation, composition as SQLiteDatabase is final):

import android.database.sqlite.SQLiteDatabase;
public class SQLliteDatabaseFlavoured   {
     SQLiteDatabase sqLiteDatabase;
}

With usage:

getAll(SQLliteDatabaseFlavoured.SQLiteDatabase conn)

Answers


You can use the gradle buildVariant if you are using Android Studio

flavor1 -> packagename: com.example.flavor1 
flavor2 -> packagename: com.example.flavor2

using this in your gradle script:

filter{
    String line -> line.replaceAll("<complete line of regular expression>",
                                   "<complete line of modified expression>")
}

How to replace a string for a buildvariant with gradle in android studio?

If not and you are worried about your app footprint or you want ensure that the cipher library is only included when needed, then you should go with your Option #2 so that the compiler will remove the unused libraries. Option 1 will always include both libraries, which is unnecessary. Also, Option #2 gives you more flexibility if you ever change implementations (another sqlite product comes along).

From a "best practices" standpoint, you should consider maintenance and debugging. Your first option guarantees that you will know exactly which library caused a problem. Otherwise it must be very clear which flavor is being used or you are always provided a full stacktrace when you receive a bug report. If you assume that both libraries are implemented in exactly the same way, then you have a testing nightmare doing either of the above if all you get is an error with a line number or less information. Even with a full stacktrace, it may be difficult to debug issues and certainly not obvious to new people on the project. Also, from a best practices standpoint, ideally you would not change out this type of dependency at all. But I understand that may not be possible.


ok I finally found solution based on @Jim's answer. Big Thanks!

It's not the cleanest but it wokrs. I create two tasks to copy files

task copyNoEncryption << { 
//copy to temp folder
copy {
    from("src/com/sql")
    into("src/temp/sql")
}
//copy back to correct folder and replace string's
copy {
    from("src/temp/sql")
    into("src/com/sql")

    filter {
 //you have to remember that first argument is REGEX and second is normal String
        String line ->
            line.replaceAll("before REGEX",
                    "after STRING")
    }
}
//delete temp folder
delete("src/temp")
}

and second task working analogously

task copyEncryption << {
//same body but reverse string swap 
//REMEMBER in replaceAll 1st arg is REGEX and second is String
}

now I'm adding execution this task before respectively flavor

android.buildTypes.all{ theBuildType ->
tasks.whenTaskAdded{ theTask ->
    if(theTask.name == "generateFlavorWithoutEncryptionr${theBuildType.name.capitalize()}Sources"){
        theTask.dependsOn "copyNoEncryption"
    }
    else if(theTask.name == "generateFlavourWithEncryption${theBuildType.name.capitalize()}Sources"){
        theTask.dependsOn "copyEncryption"
    }
}
}

Now every time when I'm building flavor I have correct libraries. Hope that someday this will help someone.


Need Your Help

Android Lollipop 5.0 Notification Icon Small, Large Bitmap

android notifications icons

I wanted to create a question on how to create notification icons for an app. Then answer it.