【问题标题】:different Database library with same methods in different flavours Best Practice?不同风格的不同数据库具有相同方法的最佳实践?
【发布时间】:2016-02-20 05:53:45
【问题描述】:

我的 Androdi 应用程序中有两个不同的 falvours,它们应该使用不同的 SQL 实现。一种用途:

android.database.sqlite.SQLiteDatabase

第二个:

net.sqlcipher.database.SQLiteDatabase

我有这样的方法:

getAll(SQLiteDatabase conn)

我应该如何解决这种情况以避免复制和粘贴?最好的做法是什么? 我有几个想法: 第一个(最糟糕的是有很多复制粘贴)是提供不同的方法:

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

其次是在导入适当的数据库(聚合、组合,因为 SQLiteDatabase 是最终的):

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

有用法:

getAll(SQLliteDatabaseFlavoured.SQLiteDatabase conn)

【问题讨论】:

    标签: java android sqlite sqlcipher-android


    【解决方案1】:

    如果你使用 Android Studio,你可以使用 gradle buildVariant

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

    在你的 gradle 脚本中使用它:

    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?

    如果不是,并且您担心您的应用程序占用空间,或者您想确保仅在需要时包含密码库,那么您应该使用选项 #2,以便编译器删除未使用的库。选项 1 将始终包含两个库,这是不必要的。此外,如果您更改实现(另一个 SQLite 产品出现),选项 #2 会为您提供更大的灵活性。

    从“最佳实践”的角度来看,您应该考虑维护和调试。您的第一个选项保证您将确切知道哪个库导致了问题。否则,必须非常清楚正在使用哪种风格,否则当您收到错误报告时始终会提供完整的堆栈跟踪。如果您假设两个库都以完全相同的方式实现,那么如果您得到的只是行号或更少信息的错误,那么您将面临执行上述任何一项的测试噩梦。即使有完整的堆栈跟踪,调试问题也可能很困难,而且对于项目的新人来说肯定不是很明显。此外,从最佳实践的角度来看,理想情况下,您根本不会更改这种类型的依赖关系。但我知道这可能是不可能的。

    【讨论】:

    • 我正在使用 Android Studio 和 Gradle 系统。有了这个替换解决方案,如果我很好理解,我必须对每个使用 SQLiteDatabase 的文件使用 gradle 复制方法?
    • gradle 应该搜索和替换项目中包字符串的每个实例(不是 aar 或 jar)。除了 gradle 脚本的风味变体之外,您不必在任何地方指定它
    • 应该是这个样子吗? flavour1{} flavour2{ copy{ from('/src/flavour1/java/com/sql') into '/src/flavour2/java/com/sql' filter{ String line -&gt; line.replaceAll("net.sqlcipher.database.", "android.database.sqlite.") } } }
    • 在这个解决方案中,我必须从某个地方复制文件,并且我需要记住只在基本位置更改这些文件。这可能会在未来带来很多麻烦,或者我在这里不明白:(
    • 您不是在复制文件。您只是在更改导入语句。要分级,这只是预编译字符串更改。
    【解决方案2】:

    好的,我终于根据@Jim 的回答找到了解决方案。非常感谢!

    这不是最干净的,但它可以工作。 我创建了两个任务来复制文件

    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")
    }
    

    第二个任务类似

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

    现在我分别在风味之前添加执行此任务

    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"
        }
    }
    }
    

    现在,每当我构建风味时,我都有正确的库。 希望有一天这会对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-22
      • 2023-01-18
      • 1970-01-01
      • 2015-04-19
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多