android|在kotlin中使用room(Room Persistence Library)和遇到的坑

  • 有关room介绍请看这里
【android|在kotlin中使用room(Room Persistence Library)和遇到的坑】下面进入正题,如何在kotlin中使用room; 大致与java还是一样的,但是会有几处坑会在文中说道; 在文尾会总结
  • 第一步一定要在app 目录下的 builde.gradle加入下面这个插件
apply plugin: 'kotlin-kapt'//使用生成文件 kapt { generateStubs = true }

1.创建Entity
@Entity(tableName = "story") @TypeConverters(Converters::class) data class StoryEntity constructor( @PrimaryKey @SerializedName("id") var id: Int) {constructor() : this(0)@ColumnInfo(name = "images") @SerializedName("images") var images: Array? = null@ColumnInfo(name = "title") @SerializedName("title") var title: String? = null@ColumnInfo(name = "date") var date: Long = 0@ColumnInfo(name = "read") var read: Int = 0@ColumnInfo(name = "like") var like: Int = 0@ColumnInfo(name = "collection") var collection: Int = 0/** * HTML-Body */ @ColumnInfo(name = "body") var body: String? = null/** * 图片作者 */ @ColumnInfo(name = "image_source") var image_source: String? = null/** * 详情头部image */ @ColumnInfo(name = "image") var image: String? = null/** * 时间-文字 */ @ColumnInfo(name = "date_string") var dateString: String = ""override fun toString(): String { return "StoryEntity(id=$id, images=${Arrays.toString(images)}," + " title=$title," + " date=$date," + " read=$read," + " like=$like," + " collection=$collection," + " body=$body," + " image_source=$image_source," + " image=$image," + " dateString='$dateString')" } }

* 这里会遇到【坑1】 Entity类需要定义一个空 构造函数
因为sql中不能插入数组这样类型数据,就需要使用到了类型转换器了,这里使用了TypeConverters
关于写类型转换器类会与java不同
/** * Created by JokAr on 2017/6/30. */ class Converters { @TypeConverter open fun arrayToString(array: Array): String { if (array == null || array.size === 0) { return "" }val builder = StringBuilder(array[0]) for (i in 1..array.size - 1) { builder.append(",").append(array[i]) } return builder.toString() }@TypeConverter open fun StringToArray(value: String): Array? { return if (TextUtils.isEmpty(value)) null else value.split(",").toTypedArray()} }


  • 这里会遇到【坑2】,看教程里类型转换器是使用的静态方法的,但是在ktolin若你想使用object 类是不行的,使用普通的class类就可以了;否则生成文件里会报错

2.创建Dao
/** * Created by JokAr on 2017/6/30. */ @Dao interface StoryDao {/** * 插入story */ @Insert fun insert(stories: ArrayList)/** * 根据时间获取story */ @Query("SELECT * FROM story WHERE date = :date ") fun getStoryByDate(date: Long): List/** * 获取所有收藏的story */ @Query("SELECT * FROM story WHERE collection = 1 ") fun getAllCollectedStory(): List/** * 更新story */ @Update fun updateStory(story: StoryEntity)/** * 根据id获取story */ @Query("SELECT * FROM story where id = :id ") fun selectStory(id: Int): StoryEntity }


  • 这里会遇到【坑3】, 方法返回类型不能用ArrayList 他会识别不了,用List就好了
  • 补充一个 这里会遇到【坑4】: insert 的返回值 不能是 Long _impl 生成的是 long 和 kotlin 的Long 类型对不上, 可以用 List 解决这种尴尬;
    “`
    fun insertEntity(vararg entity: UserDBEntity): List
“`
3.创建Database
@Database(entities = arrayOf(StoryEntity::class, TopStoryEntity::class), version = 1) abstract class AppDataBase : RoomDatabase() {abstract fun storyDao(): StoryDao }

4.创建单例模式使用
class AppDataBaseHelper constructor(context: Context) {val appDataBase = Room.databaseBuilder(context, AppDataBase::class.java, "daily").build()!!companion object { @Volatile var INSTANCE: AppDataBaseHelper? = nullfun getInstance(context: Context): AppDataBaseHelper { if (INSTANCE == null) { synchronized(AppDataBaseHelper::class) { if (INSTANCE == null) { INSTANCE = AppDataBaseHelper(context.applicationContext) } } } return INSTANCE!! } }/** * 插入topStory */ fun insertTopStory(topStories: ArrayList) { appDataBase.topStoryDao().insert(topStories) }/** * 根据时间获取story */ fun getStoryByDate(date: Long): ArrayList { return appDataBase.storyDao().getStoryByDate(date) as ArrayList }/** * 根据id获取story */ fun getStory(id: Int): StoryEntity{ return appDataBase.storyDao().selectStory(id) }/** * 更新story; 必须在非主线程中进行 */ fun updateStory(story: StoryEntity) { appDataBase.storyDao().updateStory(story) } }

5.坑总结
  • 【坑1】 Entity类需要定义一个空 构造函数
  • 【坑2】类型转换器使用object 类是不行的,使用普通的class类就可以了;否则生成文件里会报错
  • 【坑3】Dao方法返回类型不能用ArrayList 他会识别不了,用List就好了
  • 【坑4】 insert 的返回值 不能是 Long _impl 生成的是 long 和 kotlin 的Long 类型对不上, 可以用 List 解决
*暂时就遇到这么多坑,若再遇到其他会补充上的;
若想看具体的使用方法,可以参考我的这个项目

    推荐阅读