从assets文件夹复制数据库会创建一个空数据库

时间:2018-03-05 20:05:44

标签: android kotlin

我在将现有数据库从assets文件夹复制到数据库文件夹时遇到问题。原始数据库是5.9MB,但是使用下面的代码,它创建了一个带有android_metadata表的12KB数据库,该表已经存在于我的数据库中。

以下是代码:

class Database(private val ctx: Context = App.instance) : ManagedSQLiteOpenHelper(ctx, DB_NAME, null, DB_VERSION), AnkoLogger {
    companion object {
        val instance by lazy { Database() }
        private const val DB_NAME = "dex.db"
        private const val DB_VERSION = 1
    }

    override fun onCreate(db: SQLiteDatabase) {
        if (!ctx.getDatabasePath(DB_NAME).exists()) {
            info("Creating database ${db.path}.")
            copyDatabase()
        }
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        if (newVersion > oldVersion) {
            info("Updating database ${db.path} from version $oldVersion to version $newVersion.")
            copyDatabase()
        }
    }

    private fun copyDatabase() {
        info("Copying database to data folder.")
        ctx.assets.open(DB_NAME).buffered().use { input ->
            FileOutputStream(ctx.getDatabasePath(DB_NAME)).use { out ->
                input.copyTo(out)
            }
        }
    }
}

使用Android Studio中的设备文件资源管理器手动复制数据库并使用Anko SQLite查询数据库工作正常,但使用上面的代码,查询任何表都会导致no such table错误。

1 个答案:

答案 0 :(得分:-1)

为AssetDBOpenHelper创建一个类。尝试以下方法。它对我来说很好。

class AssetDBOpenHelper(private val context: Context) {    
companion object {    
    private val DB_NAME = "asset_db_name.db"
}

fun openDatabase(): SQLiteDatabase {
    val dbFile = context.getDatabasePath(DB_NAME)    

    if (!dbFile.exists()) {
        try {
           val checkDB = context.openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE,null)
            checkDB?.close()
            copyDatabase(dbFile)
        } catch (e: IOException) {
            throw RuntimeException("error", e)
        }    
    }
    return SQLiteDatabase.openDatabase(dbFile.path, null, SQLiteDatabase.OPEN_READWRITE)
}

@SuppressLint("WrongConstant")
private fun copyDatabase(dbFile: File) {
    val `is` = context.assets.open(DB_NAME)
    val os = FileOutputStream(dbFile)    
    val buffer = ByteArray(1024)
    while (`is`.read(buffer) > 0) {
        os.write(buffer)
    }    
    os.flush()
    os.close()
    `is`.close()
}

然后在您的活动中打开或创建数据库

val adb = AssetDatabaseOpenHelper(this)
adb.openDatabase()