Я использую PagingLibrary
с RxJava
для загрузки данных из Room
базы данных.
В момент создания базы данных она автоматически добавляет 1000 элементов. Проблема возникает с каждым количеством элементов в базе данных, независимо от того, сколько это - 10 или 1000.
Так в чем же проблема?
После загрузки данных, когда я «пролетаю» над элементами, я вижу, что приложение явно теряет кадры. Это происходит только через первые ~ 50 предметов и после я могу летать, не теряя кадров. Это происходит только после холодного старта, я могу поменять деятельность, добавить новые предметы и нет никаких дополнительных лагов .
Это мой код:
ДАО:
@Query("SELECT * FROM tasks ")
fun getAllAlarms(): DataSource.Factory<Int, TaskEntity>
ViewModel:
override fun getTaskList(): Observable<PagedList<TaskEntity>> {
val factory = mDao.getAllAlarms()
val config = PagedList.Config.Builder()
.setEnablePlaceholders(true)
.setPageSize(5)
.setMaxSize(15)
.build()
return RxPagedListBuilder(factory, config).buildObservable()
}
Примечание: я играл со значениями PageSize и MaxSize. Я не заметил изменения производительности при игре с этими значениями.
Тогда пришло время для занятия:
private fun getAllTasks() {
mDisposable.add(
mViewModel!!.getTaskList
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doAfterNext { mViewModel!!.mProgressBarVisibility.set(View.GONE) }
.doOnSubscribe { mViewModel!!.mProgressBarVisibility.set(View.VISIBLE) }
.subscribe( mAdapter::submitList)
{ error -> Log.e("onListReceivedError", error.message, error) })
}
и адаптер :
class TaskPagedAdapter : PagedListAdapter<TaskEntity, TaskViewHolder>(DIFF_CALLBACK) {
private var mLayoutInflater: LayoutInflater? = null
var binding: ItemsAlarmsRecyclerviewBinding? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
if (mLayoutInflater == null)
mLayoutInflater = LayoutInflater.from(parent.context)
binding = DataBindingUtil
.inflate(mLayoutInflater!!, R.layout.items_alarms_recyclerview,
parent, false)
return TaskViewHolder(binding)
}
override fun onBindViewHolder(holder: TaskViewHolder, position: Int)
= holder.bindTo(getItem(position))
override fun getItemViewType(position: Int): Int = position
companion object {
private var DIFF_CALLBACK: DiffUtil.ItemCallback<TaskEntity> = object : DiffUtil.ItemCallback<TaskEntity>() {
override fun areItemsTheSame(oldItem: TaskEntity, newItem: TaskEntity): Boolean {
return oldItem === newItem
}
@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(oldItem: TaskEntity, newItem: TaskEntity): Boolean {
return oldItem == newItem
}
}
}
}
плюс ViewHolder для любопытных:
class TaskViewHolder(private val binding: ItemsAlarmsRecyclerviewBinding?) : RecyclerView.ViewHolder(binding!!.root) {
var entity: TaskEntity? = null
fun bindTo(entity: TaskEntity?) {
if (entity != null) {
this.entity = entity;
binding!!.entity = entity
}
}
}
Примечание II: я пытался сделать то же самое с LiveData, но это выглядело намного запаздывающим.
Моя "маленькая" идея связана с Observable
, так как когда он генерирует данные из базы данных, создает новые наблюдаемые, и каждый раз, когда моя активность наблюдает за новыми наблюдаемыми. Я прав?
В любом случае, у вас есть идеи, как мне решить мою проблему?