Skip to content

Commit 76d68e9

Browse files
Refactor: Replace deprecated realmInstance with withRealmAsync
Replaced the deprecated synchronous `realmInstance` getter with the asynchronous `withRealmAsync` or `withRealm` in `DashboardActivity`, `BaseRecyclerFragment`, and `BaseResourceFragment`. This change moves database access off the main thread, mitigating the risk of ANRs. - Refactored `DashboardActivity` to use `withRealmAsync` for notification creation. - Audited and refactored `BaseRecyclerFragment` and `BaseResourceFragment` to eliminate direct `realmInstance` access, favoring `withRealm` within coroutines. - Added `@Deprecated` annotation to `realmInstance` in `DatabaseService` to guide developers towards safer alternatives. - Ensured `StrictMode` is enabled to detect disk reads in debug builds.
1 parent 83a17ba commit 76d68e9

File tree

4 files changed

+182
-230
lines changed

4 files changed

+182
-230
lines changed

app/src/main/java/org/ole/planet/myplanet/base/BaseRecyclerFragment.kt

Lines changed: 82 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,18 @@ abstract class BaseRecyclerFragment<LI> : BaseRecyclerParentFragment<Any?>(), On
8181
tvMessage = v.findViewById(R.id.tv_message)
8282
selectedItems = mutableListOf()
8383
list = mutableListOf()
84-
mRealm = databaseService.realmInstance
8584
model = profileDbHandler.userModel
8685
val adapter = getAdapter()
8786
recyclerView.adapter = adapter
87+
8888
if (isMyCourseLib && adapter.itemCount != 0 && courseLib == "courses") {
8989
resources?.let { showDownloadDialog(it) }
9090
} else if (isMyCourseLib && courseLib == null && !isSurvey) {
9191
viewLifecycleOwner.lifecycleScope.launch {
92-
showDownloadDialog(getLibraryList(mRealm))
92+
val libraryList = databaseService.withRealm { realm ->
93+
getLibraryList(realm)
94+
}
95+
showDownloadDialog(libraryList)
9396
}
9497
}
9598
return v
@@ -107,7 +110,7 @@ abstract class BaseRecyclerFragment<LI> : BaseRecyclerParentFragment<Any?>(), On
107110
}
108111

109112
fun addToMyList() {
110-
if (!isRealmInitialized() || isAddInProgress) return
113+
if (isAddInProgress) return
111114

112115
val itemsToAdd = selectedItems?.toList() ?: emptyList()
113116
if (itemsToAdd.isEmpty()) return
@@ -181,26 +184,23 @@ abstract class BaseRecyclerFragment<LI> : BaseRecyclerParentFragment<Any?>(), On
181184
}
182185

183186
fun deleteSelected(deleteProgress: Boolean) {
184-
selectedItems?.forEach { item ->
187+
viewLifecycleOwner.lifecycleScope.launch {
185188
try {
186-
if (!mRealm.isInTransaction) {
187-
mRealm.beginTransaction()
188-
}
189-
val `object` = item as RealmObject
190-
deleteCourseProgress(deleteProgress, `object`)
191-
removeFromShelf(`object`)
192-
if (mRealm.isInTransaction) {
193-
mRealm.commitTransaction()
189+
databaseService.withRealm { realm ->
190+
realm.executeTransaction {
191+
selectedItems?.forEach { item ->
192+
val `object` = item as RealmObject
193+
deleteCourseProgress(deleteProgress, `object`)
194+
removeFromShelf(`object`)
195+
}
196+
}
194197
}
198+
recyclerView.adapter = getAdapter()
199+
showNoData(tvMessage, getAdapter().itemCount, "")
195200
} catch (e: Exception) {
196-
if (mRealm.isInTransaction) {
197-
mRealm.cancelTransaction()
198-
}
199-
throw e
201+
e.printStackTrace()
200202
}
201203
}
202-
recyclerView.adapter = getAdapter()
203-
showNoData(tvMessage, getAdapter().itemCount, "")
204204
}
205205

206206
fun countSelected(): Int {
@@ -209,31 +209,42 @@ abstract class BaseRecyclerFragment<LI> : BaseRecyclerParentFragment<Any?>(), On
209209

210210
private fun deleteCourseProgress(deleteProgress: Boolean, `object`: RealmObject) {
211211
if (deleteProgress && `object` is RealmMyCourse) {
212-
mRealm.where(RealmCourseProgress::class.java).equalTo("courseId", `object`.courseId).findAll().deleteAllFromRealm()
213-
val examList: List<RealmStepExam> = mRealm.where(RealmStepExam::class.java).equalTo("courseId", `object`.courseId).findAll()
214-
for (exam in examList) {
215-
mRealm.where(RealmSubmission::class.java).equalTo("parentId", exam.id)
216-
.notEqualTo("type", "survey").equalTo("uploaded", false).findAll()
217-
.deleteAllFromRealm()
212+
databaseService.withRealm { realm ->
213+
realm.where(RealmCourseProgress::class.java).equalTo("courseId", `object`.courseId)
214+
.findAll().deleteAllFromRealm()
215+
val examList: List<RealmStepExam> =
216+
realm.where(RealmStepExam::class.java).equalTo("courseId", `object`.courseId)
217+
.findAll()
218+
for (exam in examList) {
219+
realm.where(RealmSubmission::class.java).equalTo("parentId", exam.id)
220+
.notEqualTo("type", "survey").equalTo("uploaded", false).findAll()
221+
.deleteAllFromRealm()
222+
}
218223
}
219224
}
220225
}
221226

222-
private fun checkAndAddToList(course: RealmMyCourse?, courses: MutableList<RealmMyCourse>, tags: List<RealmTag>) {
227+
private fun checkAndAddToList(
228+
realm: Realm,
229+
course: RealmMyCourse?,
230+
courses: MutableList<RealmMyCourse>,
231+
tags: List<RealmTag>
232+
) {
223233
for (tg in tags) {
224-
val count = mRealm.where(RealmTag::class.java).equalTo("db", "courses").equalTo("tagId", tg.id)
234+
val count = realm.where(RealmTag::class.java).equalTo("db", "courses")
235+
.equalTo("tagId", tg.id)
225236
.equalTo("linkId", course?.courseId).count()
226237
if (count > 0 && !courses.contains(course)) {
227238
course?.let { courses.add(it) }
228239
}
229240
}
230241
}
231242

232-
private fun <LI : RealmModel> getData(s: String, c: Class<LI>): List<LI> {
233-
if (s.isEmpty()) return mRealm.where(c).findAll()
243+
private fun <LI : RealmModel> getData(realm: Realm, s: String, c: Class<LI>): List<LI> {
244+
if (s.isEmpty()) return realm.where(c).findAll()
234245

235246
val queryParts = s.split(" ").filterNot { it.isEmpty() }
236-
val data: RealmResults<LI> = mRealm.where(c).findAll()
247+
val data: RealmResults<LI> = realm.where(c).findAll()
237248
val normalizedQuery = normalizeText(s)
238249
val startsWithQuery = mutableListOf<LI>()
239250
val containsQuery = mutableListOf<LI>()
@@ -258,25 +269,26 @@ abstract class BaseRecyclerFragment<LI> : BaseRecyclerParentFragment<Any?>(), On
258269
}
259270

260271
fun filterLibraryByTag(s: String, tags: List<RealmTag>): List<RealmMyLibrary> {
261-
val normalizedSearchTerm = normalizeText(s)
262-
var list = getData(s, RealmMyLibrary::class.java)
263-
list = if (isMyCourseLib) {
264-
getMyLibraryByUserId(model?.id, list)
265-
} else {
266-
getOurLibrary(model?.id, list)
267-
}
272+
return databaseService.withRealm { realm ->
273+
val normalizedSearchTerm = normalizeText(s)
274+
var list = getData(realm, s, RealmMyLibrary::class.java)
275+
list = if (isMyCourseLib) {
276+
getMyLibraryByUserId(model?.id, list)
277+
} else {
278+
getOurLibrary(model?.id, list)
279+
}
268280

269-
val libraries = if (tags.isNotEmpty()) {
270-
val filteredLibraries = mutableListOf<RealmMyLibrary>()
271-
for (library in list) {
272-
filter(tags, library, filteredLibraries)
281+
val libraries = if (tags.isNotEmpty()) {
282+
val filteredLibraries = mutableListOf<RealmMyLibrary>()
283+
for (library in list) {
284+
filter(realm, tags, library, filteredLibraries)
285+
}
286+
filteredLibraries
287+
} else {
288+
list
273289
}
274-
filteredLibraries
275-
} else {
276-
list
290+
libraries
277291
}
278-
279-
return libraries
280292
}
281293

282294
fun normalizeText(str: String): String {
@@ -285,32 +297,39 @@ abstract class BaseRecyclerFragment<LI> : BaseRecyclerParentFragment<Any?>(), On
285297
}
286298

287299
fun filterCourseByTag(s: String, tags: List<RealmTag>): List<RealmMyCourse> {
288-
if (tags.isEmpty() && s.isEmpty()) {
289-
return applyCourseFilter(filterRealmMyCourseList(getList(RealmMyCourse::class.java)))
290-
}
291-
var list = getData(s, RealmMyCourse::class.java)
292-
list = if (isMyCourseLib) {
293-
getMyCourseByUserId(model?.id, list)
294-
} else {
295-
getAllCourses(model?.id, list)
296-
}
297-
if (tags.isEmpty()) {
298-
return list
299-
}
300-
val courses = RealmList<RealmMyCourse>()
301-
list.forEach { course ->
302-
checkAndAddToList(course, courses, tags)
300+
return databaseService.withRealm { realm ->
301+
if (tags.isEmpty() && s.isEmpty()) {
302+
return@withRealm applyCourseFilter(filterRealmMyCourseList(getList(RealmMyCourse::class.java)))
303+
}
304+
var list = getData(realm, s, RealmMyCourse::class.java)
305+
list = if (isMyCourseLib) {
306+
getMyCourseByUserId(model?.id, list)
307+
} else {
308+
getAllCourses(model?.id, list)
309+
}
310+
if (tags.isEmpty()) {
311+
return@withRealm list
312+
}
313+
val courses = RealmList<RealmMyCourse>()
314+
list.forEach { course ->
315+
checkAndAddToList(realm, course, courses, tags)
316+
}
317+
applyCourseFilter(courses)
303318
}
304-
return applyCourseFilter(courses)
305319
}
306320

307321
private fun filterRealmMyCourseList(items: List<Any?>): List<RealmMyCourse> {
308322
return items.filterIsInstance<RealmMyCourse>()
309323
}
310324

311-
private fun filter(tags: List<RealmTag>, library: RealmMyLibrary?, libraries: MutableList<RealmMyLibrary>) {
325+
private fun filter(
326+
realm: Realm,
327+
tags: List<RealmTag>,
328+
library: RealmMyLibrary?,
329+
libraries: MutableList<RealmMyLibrary>
330+
) {
312331
for (tg in tags) {
313-
val count = mRealm.where(RealmTag::class.java).equalTo("db", "resources")
332+
val count = realm.where(RealmTag::class.java).equalTo("db", "resources")
314333
.equalTo("tagId", tg.id).equalTo("linkId", library?.id).count()
315334
if (count > 0 && !libraries.contains(library)) {
316335
library?.let { libraries.add(it) }
@@ -348,32 +367,6 @@ abstract class BaseRecyclerFragment<LI> : BaseRecyclerParentFragment<Any?>(), On
348367
return sub && lev && lan && med
349368
}
350369

351-
override fun onDestroy() {
352-
cleanupRealm()
353-
super.onDestroy()
354-
}
355-
356-
private fun cleanupRealm() {
357-
if (isRealmInitialized()) {
358-
try {
359-
mRealm.removeAllChangeListeners()
360-
361-
if (mRealm.isInTransaction) {
362-
try {
363-
mRealm.commitTransaction()
364-
} catch (e: Exception) {
365-
mRealm.cancelTransaction()
366-
}
367-
}
368-
} catch (e: Exception) {
369-
e.printStackTrace()
370-
} finally {
371-
if (!mRealm.isClosed) {
372-
mRealm.close()
373-
}
374-
}
375-
}
376-
}
377370

378371
override fun onDetach() {
379372
super.onDetach()

0 commit comments

Comments
 (0)