どのように自動リフレッシュ領域のAndroidの内部マネージャ
20278 ワード
Realm Androidのアプリで使用されるSQLのようなクエリの構文で埋め込まれたデータベースです.
その主な機能対他のデータベースは、あなたの携帯アプリのコード内のRealmオブジェクトがライブです.Realmオブジェクトを変更すると、アプリケーション全体のすべてのコピーが即座に更新され、Realm Change Listeners、Flow、RxJavaなどでオブジェクトの変更を再表示できます.
Realmのメカニズムは、あなたのRealmインスタンスが
Realmを使う必要のある典型的な背景スレッドはAndroid WorkManager 労働者手動でRealmインスタンスを手動で更新することができます
この問題を解決するために、私はWorkManagerワーカーズの中でRealmインスタンスを自動更新するために以下のテクニックを使用しました. 仲間を作る 使用する
最後にフック
利益!延長する フルソースコード:
その主な機能対他のデータベースは、あなたの携帯アプリのコード内のRealmオブジェクトがライブです.Realmオブジェクトを変更すると、アプリケーション全体のすべてのコピーが即座に更新され、Realm Change Listeners、Flow、RxJavaなどでオブジェクトの変更を再表示できます.
背景スレッドの問題
Realmのメカニズムは、あなたのRealmインスタンスが
Looper
thread , つまり、あなたActivity
and Fragment
クラス( UIスレッド).しかし、非UIバックグラウンドスレッドからRealmにアクセスする必要があるかもしれませんし、それらのインスタンスは自動更新されず、memory leak problems .Realmを使う必要のある典型的な背景スレッドはAndroid WorkManager 労働者手動でRealmインスタンスを手動で更新することができます
WorkManager
労働者は、私の経験では、これはほとんど手動でのリフレッシュ遅延のために動作しません(メモリリークと大きなrealmファイルの問題についての上のリンクを参照してくださいあなたのバックグラウンド領域が後ろに遅れ始めているときに発生する問題).Realmをバックグラウンドスレッドで正しく使う方法
この問題を解決するために、私はWorkManagerワーカーズの中でRealmインスタンスを自動更新するために以下のテクニックを使用しました.
HandlerThread
バックグラウンド作業を実行するスレッドの場合は、ルーパーと Handler
それに.これがLooper
ここであなたの領域のインスタンスが住んでいます.RealmHandlerThread‘s
handler.post
排他的にすべてのあなたの領域の操作を実行します.このようにして、realmインスタンスは自動的にリフレッシュします.class RealmHandlerThread(name: String) : HandlerThread(name) {
@Volatile private var handler: Handler? = null
@Volatile private var realm: Realm? = null
fun startAndWaitUntilReady() {
start()
// HandlerThread's getLooper() blocks until it has a value
handler = Handler(looper)
handler?.post { realm = Realm.getDefaultInstance() }
}
private fun beforeQuit(onFinished: () -> Any): Boolean {
if (looper == null) {
return false
}
handler?.post {
realm?.close()
onFinished()
}
return true
}
override fun quit(): Boolean {
return beforeQuit { super.quit() }
}
override fun quitSafely(): Boolean {
return beforeQuit { super.quitSafely() }
}
}
handler.post
非同期なので、あなたの領域を同期的に使用することができますWorkManager Worker
コード、ブリッジを非同期と同期の世界 suspendCoroutine
.class RealmHandlerThread(name: String) : HandlerThread(name) {
...
suspend fun <T> executeWithRealm(realmFun: (Realm) -> T): T {
return suspendCoroutine { continuation ->
handler!!.post {
try {
continuation.resume(realmFun(realm!!))
} catch (err: Exception) {
continuation.resumeWithException(err)
}
}
}
}
...
}
RealmHandlerThread
に CoroutineWorker
.abstract class RealmCoroutineWorker(
name: String,
context: Context,
workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {
private val realmThread = RealmHandlerThread(name)
abstract fun doWork(realm: Realm): Result
final override suspend fun doWork(): Result {
return withContext(Dispatchers.IO) {
try {
realmThread.startAndWaitUntilReady()
realmThread.executeWithRealm { realm -> doWork(realm) }
} catch (err: Exception) {
Result.failure()
} finally {
realmThread.quit()
}
}
}
}
利益!延長する
RealmCoroutineWorker
得るWorkManager Worker
これは、自動リフレッシュ領域インスタンスへの同期アクセスを楽しんでいます.import android.content.Context
import android.os.Handler
import android.os.HandlerThread
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import io.realm.Realm
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
abstract class RealmCoroutineWorker(
name: String,
context: Context,
workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {
private val realmThread = RealmHandlerThread(name)
abstract fun doWork(realm: Realm): Result
final override suspend fun doWork(): Result {
return withContext(Dispatchers.IO) {
try {
realmThread.startAndWaitUntilReady()
realmThread.executeWithRealm { realm -> doWork(realm) }
} catch (err: Exception) {
Result.failure()
} finally {
realmThread.quit()
}
}
}
}
class RealmHandlerThread(name: String) : HandlerThread(name) {
@Volatile private var handler: Handler? = null
@Volatile private var realm: Realm? = null
fun startAndWaitUntilReady() {
start()
// HandlerThread's getLooper() blocks until it has a value
handler = Handler(looper)
handler?.post { realm = Realm.getDefaultInstance() }
}
suspend fun <T> executeWithRealm(realmFun: (Realm) -> T): T {
return suspendCoroutine { continuation ->
handler!!.post {
try {
continuation.resume(realmFun(realm!!))
} catch (err: Exception) {
continuation.resumeWithException(err)
}
}
}
}
private fun beforeQuit(onFinished: () -> Any): Boolean {
if (looper == null) {
return false
}
handler?.post {
realm?.close()
onFinished()
}
return true
}
override fun quit(): Boolean {
return beforeQuit { super.quit() }
}
override fun quitSafely(): Boolean {
return beforeQuit { super.quitSafely() }
}
}
前掲の記事https://pixelsandrobots.xyz/android/realm-auto-refresh-android-workmanagerReference
この問題について(どのように自動リフレッシュ領域のAndroidの内部マネージャ), 我々は、より多くの情報をここで見つけました https://dev.to/sudokai/how-to-auto-refresh-realm-inside-android-workmanager-35nbテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol