是时候更新手里的武器了—Jetpack架构组件简析( 六 )

@Entitydata class User(@PrimaryKey(autoGenerate = true) val id: Int,val name: String)4)Dao , 数据操作
【是时候更新手里的武器了—Jetpack架构组件简析】@Daointerface UserDao {@Query("SELECT * FROM User")fun getAllUser(): DataSource.Factory<Int, User>@Query("SELECT * FROM User")fun getAllUser2(): LiveData<List<User>>@Query("SELECT * from user")fun getAllUser3(): Flowable<List<User>>@Insertfun insert(users: List<User>)}然后就可以进行数据库操作了 , 很简单吧 。
Paging

分页库可帮助您一次加载和显示一小块数据 。按需载入部分数据会减少网络带宽和系统资源的使用量 。
所以Paging就是一个分页库 , 主要用于Recycleview列表展示 。下面我就结合Room说说Paging的用法 。使用Paging主要注意两个类:PagedList和PagedListAdapter 。1)PagedList用于加载应用数据块 , 绑定数据列表 , 设置数据页等 。结合上述Room的Demo我继续写了一个UserModel进行数据管理:
class UserModel(app: Application) : AndroidViewModel(app) {val dao = UserDb.get(app).userDao()var idNum = 1companion object {private const val PAGE_SIZE = 10}//初始化PagedListval users = LivePagedListBuilder(dao.getAllUser(), PagedList.Config.Builder().setPageSize(PAGE_SIZE).setEnablePlaceholders(true).build()).build()//插入用户fun insert() = ioThread {dao.insert(newTenUser())}//获取新的10个用户fun newTenUser(): ArrayList<User> {var newUsers = ArrayList<User>()for (index in 1..10) {newUsers.add(User(0, "bob${++idNum}"))}return newUsers}}2)PagedListAdapter使用Recycleview必要要用到adatper , 所以这里需要绑定一个继承自PagedListAdapter的adapter:
class UserAdapter : PagedListAdapter<User, UserAdapter.UserViewHolder>(diffCallback) {override fun onBindViewHolder(holder: UserViewHolder, position: Int) {holder.bindTo(getItem(position))}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder =UserViewHolder(parent)companion object {private val diffCallback = object : DiffUtil.ItemCallback<User>() {override fun areItemsTheSame(oldItem: User, newItem: User): Boolean =oldItem.id == newItem.idoverride fun areContentsTheSame(oldItem: User, newItem: User): Boolean =oldItem == newItem}}class UserViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)) {private val tv1 = itemView.findViewById<TextView>(R.id.name)var user: User? = nullfun bindTo(user: User?) {this.user = usertv1.text = user?.name}}}这里还用到了DiffUtil.ItemCallback 类 , 用于比较数据 , 进行数据更新用 。
ok , 数据源 , adapter都设置好了 , 接下来就是监听数据 , 刷新数据就可以了
// 监听users数据 , 数据改变调用submitList方法viewModel.users.observe(this, Observer(adapter::submitList))对 , 就是这么一句 , 监听PagedList , 并且在它改变的时候调用PagedListAdapter的submitList方法 。这分层够爽吧 , 其实这也就是paging或者说jetpack给我们项目带来的优势 , 层层解耦 , adapter都不用维护list数据源了 。
ViewModel
ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据 。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存 。
终于说到ViewModel了 , 其实之前的demo都用了好多遍了 , ViewModel主要是从界面控制器逻辑中分离出视图数据 , 为什么要这么做呢?主要为了解决两大问题:
  • 以前Activity中如果被系统销毁或者需要重新创建的时候 , 页面临时性数据都会丢失 , 需要通过onSaveInstanceState() 方法保存 , onCreate方法中读取 。而且数据量一大就更加不方便了 。
  • 在Activity中 , 难免有些异步调用 , 所以就会容易导致界面销毁时候 , 这些调用还存在 。那就会发生内存泄漏或者直接崩溃 。
所以ViewModel诞生了 , 还是解耦 , 我把数据单独拿出来管理 , 还加上生命周期 , 那不就可以解决这些问题了吗 。而且当所有者 Activity 完全销毁之后 , ViewModel会调用其onCleared()方法 , 以便清理资源 。
接下来举个 , 看看ViewModel具体是怎么使用的:
def lifecycle_version = "2.2.0"// ViewModelimplementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"class SharedViewModel : ViewModel() {var userData = https://www.isolves.com/it/cxkf/jiagou/2020-08-02/MutableLiveData


推荐阅读