Skip to content

Commit

Permalink
Merge pull request #20937 from wordpress-mobile/hackweek/database-anr
Browse files Browse the repository at this point in the history
[Hack Week] A generic solution for resolving the ANRs caused by accessing local database
  • Loading branch information
Antonis Lilis authored Jun 5, 2024
2 parents dc94e3e + 032d503 commit a24e5d1
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.wordpress.android.datasets

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
* Helper class to handle async tasks by using coroutines
* @see <a href="https://github.com/wordpress-mobile/WordPress-Android/pull/20937">Introduction</a>
*/
object AsyncTaskHandler {
/**
* Load data in the background and handle the result on the main thread
*/
@JvmStatic
fun <T> load(backgroundTask: () -> T, callback: AsyncTaskCallback<T>) {
CoroutineScope(Dispatchers.IO).launch {
// handle the background task
val result = backgroundTask()

withContext(Dispatchers.Main) {
// handle the result on the main thread
callback.onTaskFinished(result)
}
}
}

interface AsyncTaskCallback<T> {
fun onTaskFinished(result: T)
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.wordpress.android.R;
import org.wordpress.android.WordPress;
import org.wordpress.android.analytics.AnalyticsTracker;
import org.wordpress.android.datasets.AsyncTaskHandler;
import org.wordpress.android.datasets.ReaderPostTable;
import org.wordpress.android.datasets.ReaderTagTable;
import org.wordpress.android.fluxc.store.AccountStore;
Expand Down Expand Up @@ -371,44 +372,47 @@ private void toggleFollowButton(
return;
}

final boolean isAskingToFollow = !ReaderTagTable.isFollowedTagName(currentTag.getTagSlug());

final String slugForTracking = currentTag.getTagSlug();
AsyncTaskHandler.load(
() -> !ReaderTagTable.isFollowedTagName(currentTag.getTagSlug()),
isAskingToFollow -> {
final String slugForTracking = currentTag.getTagSlug();

ReaderActions.ActionListener listener = succeeded -> {
if (!succeeded) {
int errResId = isAskingToFollow ? R.string.reader_toast_err_adding_tag
: R.string.reader_toast_err_removing_tag;
ToastUtils.showToast(context, errResId);
} else {
if (isAskingToFollow) {
mReaderTracker.trackTag(
AnalyticsTracker.Stat.READER_TAG_FOLLOWED,
slugForTracking,
mSource
);
} else {
mReaderTracker.trackTag(
AnalyticsTracker.Stat.READER_TAG_UNFOLLOWED,
slugForTracking,
mSource
);
}
}
renderTagHeader(currentTag, tagHolder, true);
};

boolean success;
boolean isLoggedIn = mAccountStore.hasAccessToken();
if (isAskingToFollow) {
success = ReaderTagActions.addTag(mCurrentTag, listener, isLoggedIn);
} else {
success = ReaderTagActions.deleteTag(mCurrentTag, listener, isLoggedIn);
}

ReaderActions.ActionListener listener = succeeded -> {
if (!succeeded) {
int errResId = isAskingToFollow ? R.string.reader_toast_err_adding_tag
: R.string.reader_toast_err_removing_tag;
ToastUtils.showToast(context, errResId);
} else {
if (isAskingToFollow) {
mReaderTracker.trackTag(
AnalyticsTracker.Stat.READER_TAG_FOLLOWED,
slugForTracking,
mSource
);
} else {
mReaderTracker.trackTag(
AnalyticsTracker.Stat.READER_TAG_UNFOLLOWED,
slugForTracking,
mSource
);
if (isLoggedIn && success) {
renderTagHeader(currentTag, tagHolder, false);
}
}
}
renderTagHeader(currentTag, tagHolder, true);
};

boolean success;
boolean isLoggedIn = mAccountStore.hasAccessToken();
if (isAskingToFollow) {
success = ReaderTagActions.addTag(mCurrentTag, listener, isLoggedIn);
} else {
success = ReaderTagActions.deleteTag(mCurrentTag, listener, isLoggedIn);
}

if (isLoggedIn && success) {
renderTagHeader(currentTag, tagHolder, false);
}
);
}

private void renderXPost(int position, ReaderXPostViewHolder holder) {
Expand Down

0 comments on commit a24e5d1

Please sign in to comment.