Skip to content

Instantly share code, notes, and snippets.

@am3n
Created July 11, 2019 08:32
Show Gist options
  • Save am3n/7c9f5cfb54eb11d15cdda5083f6f42d6 to your computer and use it in GitHub Desktop.
Save am3n/7c9f5cfb54eb11d15cdda5083f6f42d6 to your computer and use it in GitHub Desktop.
Android Room Generic DAO + LiveData.observeOnce(..)
package com.example.db.dao
import android.annotation.SuppressLint
import android.os.AsyncTask
import android.os.Process
import android.os.Process.THREAD_PRIORITY_BACKGROUND
import android.util.Log
import java.util.ArrayList
import androidx.lifecycle.Observer
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Update
@SuppressLint("StaticFieldLeak")
@Dao
abstract class BaseDao<T> {
companion object {
const val priority = Thread.MAX_PRIORITY
}
// --------------------- insert --------------------------
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insertSync(entity: T): Long?
@JvmOverloads
fun insertAsync(entity: T, observer: Observer<Long>? = null) {
object : AsyncTask<T, Void, Long>() {
override fun doInBackground(vararg entity: T): Long? {
Thread.currentThread().priority = priority
return insertSync(entity[0])
}
override fun onPostExecute(aLong: Long?) {
observer?.onChanged(aLong)
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, entity)
}
@Insert(onConflict = OnConflictStrategy.IGNORE)
abstract fun insertAllSync(entities: MutableList<T>): MutableList<Long>
@JvmOverloads
fun insertAllAsync(entities: MutableList<T>, observer: Observer<MutableList<Long>>? = null) {
object : AsyncTask<MutableList<T>, Void, MutableList<Long>>() {
override fun doInBackground(vararg entities: MutableList<T>): MutableList<Long> {
Thread.currentThread().priority = priority
return insertAllSync(entities[0])
}
override fun onPostExecute(longList: MutableList<Long>) {
observer?.onChanged(longList)
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, entities)
}
// ------------------- update ----------------------------
@Update
abstract fun updateSync(entity: T): Int
@JvmOverloads
fun updateAsync(entity: T, observer: Observer<Boolean>? = null) {
object : AsyncTask<T, Void, Boolean>() {
override fun doInBackground(vararg entity: T): Boolean? {
Thread.currentThread().priority = priority
return updateSync(entity[0]) == 1
}
override fun onPostExecute(bool: Boolean?) {
observer?.onChanged(bool)
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, entity)
}
@Update
abstract fun updateAllSync(entity: MutableList<T>): Int
@JvmOverloads
fun updateAllAsync(entity: MutableList<T>, observer: Observer<Boolean>? = null) {
object : AsyncTask<MutableList<T>, Void, Boolean>() {
override fun doInBackground(vararg entity: MutableList<T>): Boolean? {
Thread.currentThread().priority = priority
return updateAllSync(entity[0]) > 0
}
override fun onPostExecute(bool: Boolean?) {
observer?.onChanged(bool)
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, entity)
}
// -------------- update or insert ------------------------
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun updateOrInsertSync(entity: T): Long?
@JvmOverloads
fun updateOrInsertAsync(entity: T, observer: Observer<Long>? = null) {
object : AsyncTask<T, Void, Long>() {
override fun doInBackground(vararg entity: T): Long? {
Thread.currentThread().priority = priority
return updateOrInsertSync(entity[0])
}
override fun onPostExecute(aLong: Long?) {
observer?.onChanged(aLong)
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, entity)
}
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun updateOrInsertAllSync(entity: MutableList<T>): MutableList<Long>?
@JvmOverloads
fun updateOrInsertAllAsync(entity: MutableList<T>, observer: Observer<MutableList<Long>>? = null) {
object : AsyncTask<MutableList<T>, Void, MutableList<Long>>() {
override fun doInBackground(vararg entity: MutableList<T>): MutableList<Long>? {
Thread.currentThread().priority = priority
return updateOrInsertAllSync(entity[0])
}
override fun onPostExecute(longList: MutableList<Long>?) {
observer?.onChanged(longList)
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, entity)
}
// ------------------- delete ------------------------------
@Delete
abstract fun deleteSync(entity: T): Int
@JvmOverloads
fun deleteAsync(entity: T, observer: Observer<Boolean>? = null) {
object : AsyncTask<T, Void, Boolean>() {
override fun doInBackground(vararg entity: T): Boolean? {
Thread.currentThread().priority = priority
return deleteSync(entity[0]) == 1
}
override fun onPostExecute(bool: Boolean?) {
observer?.onChanged(bool)
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, entity)
}
@Delete
abstract fun deleteAllSync(entities: MutableList<T>): Int
@JvmOverloads
fun deleteAllAsync(entities: MutableList<T>, observer: Observer<DeletionResult>? = null) {
object : AsyncTask<MutableList<T>, Void, DeletionResult>() {
override fun doInBackground(vararg entities: MutableList<T>): DeletionResult {
Thread.currentThread().priority = priority
val d = deleteAllSync(entities[0])
return when {
d==entities[0].size -> DeletionResult.COMPLETE
d>0 -> DeletionResult.SOME_NOT_REMOVED
else -> DeletionResult.FAILED
}
}
override fun onPostExecute(bool: DeletionResult) {
observer?.onChanged(bool)
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, entities)
}
//-----------------------------------------------
enum class DeletionResult {
FAILED,
SOME_NOT_REMOVED,
COMPLETE
}
}
package com.example.db.dao
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner?, observer: Observer<T>) {
observe(lifecycleOwner!!, object : Observer<T> {
override fun onChanged(t: T?) {
observer.onChanged(t)
removeObserver(this)
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment