【问题标题】:Insert 3000 rows into Room Database but Method too large将 3000 行插入房间数据库但方法太大
【发布时间】:2020-12-29 10:50:42
【问题描述】:

我正在尝试预填充数据库,我生成了插入数据,但是 当我运行该应用程序时,它会出现此构建错误:

Caused by: org.jetbrains.org.objectweb.asm.MethodTooLargeException: Method too large:

我有一个这样的函数:

RoomDatabase.Callback(){

    override fun onCreate(db: SupportSQLiteDatabase) {
        super.onCreate(db)
        
        val pDao = database.get().pDao()
        val pLangDao = database.get().pLangDao()

        applicationScope.launch {
            
            insertPWithPLangEnglish_1_10(pDao, pLangDao)
           
        }

    }
}


private suspend fun insertPWithPLangEnglish_1_10(pDao: PDao, pLangDao: PLangDao){
    var insId = pDao.insert(P(pcId = 1))
    pLangDao.insert(PLang(pItemId = insId.toInt(), title = "herbert", locale = "en_US", langCode = "en"))
    insId = pDao.insert(P(pcId = 1))
    pLangDao.insert(PLang(pItemId = insId.toInt(), title = "others", locale = "en_US", langCode = "en"))
    
    ... and so on about 3000 more lines
}

知道如何解决这个问题吗?

P类如下:

@Entity(tableName = "p")
@Parcelize
data class P (
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "pid")
    val pId: Int = 0,

    @ColumnInfo(name = "pc_id")
    val pcId: Int,
    val created: Long = System.currentTimeMillis()

) : Parcelable {
}

PLang 类如下:

@Entity(tableName = "p_lang")
@Parcelize
data class PLang (
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "p_lang_id")
    val pLangId: Int = 0,

    @ColumnInfo(name = "p_item_id")
    val pItemId: Int,
    val locale: String = "",
    @ColumnInfo(name = "lang_code")
    val langCode: String,
    val title: String,
    val description: String = ""

) : Parcelable {

}

现在我在 Workers 的帮助下尝试另一种方法,并从 json 文件中获取种子数据库。

【问题讨论】:

  • 您能发布您的 P 和 PLang 课程吗?它们有什么关系?
  • 感谢@Michael 我找到了另一种方法,在 Workers 的帮助下从 json 文件中播种数据库。有点棘手,目前无法开始工作,但我希望这将是做到这一点的方法
  • @luca_999 我发布了课程

标签: android sqlite kotlin persistence android-room


【解决方案1】:

很明显,Kotlin 编译器在抱怨,因为你的方法太长了,你应该优化它。

为此,您可以创建一个包含所有 PLang 对象的全局列表:

val pLangList = listOf(
    PLang(title = "herbert", locale = "en_US", langCode = "en"),
    PLang(title = "others", locale = "en_US", langCode = "en"),
    ...
)

注意我没有设置pItemId属性,其实你也应该改变你的PLang类,给它分配一个默认值方便:

@Entity(tableName = "p_lang")
@Parcelize
data class PLang (
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "p_lang_id")
    val pLangId: Int = 0,

    @ColumnInfo(name = "p_item_id")
    val pItemId: Int = -1,              // <--- Added default value here
    val locale: String = "",
    @ColumnInfo(name = "lang_code")
    val langCode: String,
    val title: String,
    val description: String = ""

) : Parcelable {

}

现在您可以循环遍历列表并添加每个项目,只需 3 行代码,而不是 ~3000 行:

private suspend fun insertPWithPLangEnglish_1_10(pDao: PDao, pLangDao: PLangDao)
{
    for (pLang in pLangList) 
    {
        val insId = pDao.insert(P(pcId = 1))
        pLangDao.insert(PLang(pItemId = insId.toInt(), title = pLang.title, locale = pLang.locale, langCode = pLang.langCode))
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    • 2020-06-02
    • 1970-01-01
    相关资源
    最近更新 更多