问题场景:例如在小红书上发布一篇图文笔记,从编辑完图片到发布成功,中间需要经过若干步骤,如何对这些中间任务进行管理?
从上图可以看出整个任务的有一下特点:
- 任务有多个状态。
- 各状态顺序执行。
- 任务可以在任意状态时,被打断。
- 任务可以从被打断的状态重入。
任务从被打断的状态重入,是整个问题的关键点,要想重入就必须保存状态信息,Android提供的数据库恰好可以解决这个问题。
使用数据库(RoomDatabase)来管理任务状态
将任务状态作为一条信息存入数据库,每次状态改变就改变这条信息。重入时,只需要直接读取数据库,就可以进行接下来的任务了。
RoomDatabase 是什么
RoomDatabase是Android Architecture Components(Android架构组件)的一部分。它是SQLite的一个抽象层,SQLite是许多Android应用程序中使用的流行的数据库管理系统。RoomDatabase提供了一个易于使用、面向对象的接口,用于在Android应用程序中使用SQLite数据库。 具体使用方法可以参考developer.android.com/training/da… 简单理解就是我们可以利用RoomDatabase来直接访问数据库,奇妙的是,RoomDatabase 返回的查询结果可以是一个LiveData ,当数据库结构更新时,可以直接响应这个liveData的observe。
下面写一下伪代码:
@Entity
data class Article(
@PrimaryKey val id: Int,
val imgPath: String,
val text: String,
val status: Int // 用来表示上传任务的状态
)
Article 类表示上传任务信息的实体类,其中status表示任务进行到了什么状态。
@Dao
interface ArticleDao {
@Insert
suspend fun insert(info: Article): Long
@Update
suspend fun update(info: Article)
@Delete
suspend fun delete(info: Article)
@Query("SELECT * FROM info ORDER BY id DESC")
fun getArticle(id: Long): LiveData<Article>
ArticleDao 是用来跟数据库进行交互的接口。
@Database(entities = [Article::class], version = 1)
abstract class ArticleDatabase : RoomDatabase() {
abstract fun articleDao(): ArticleDao
companion object {
@Volatile
private var instance: ArticleDatabase? = null
fun getInstance(context: Context): ArticleDatabase {
return instance ?: synchronized(this) {
instance ?: Room.databaseBuilder(
context.applicationContext,
ArticleDatabase::class.java,
"ArticleDatabase_database"
).fallbackToDestructiveMigration().build().also { instance = it }
}
}
}
}
ArticleDatabase 是用来生成 RoomDatabase 实例,通过 ArticleDao 定义的接口来访问数据库。
val articleDatabase = ArticleDatabase().getInstance(context).getArticle(id)
articleData.observe { article ->
when (article.status) {
1 -> {
val newArticle = processThisStatus(article) // 处理这个状态数据
articleDatabase.update(newArticle) // 更新至下一个状态
}
2 -> {/*同上*/}
3 -> {/*同上*/}
}
}
通过ArticleDatabase 拿到 LiveData,就可以在Observe中处理任务。任务的状态改变,又会响应Observe,直到任务完成后,将任务从数据库中删除。