Replace AsyncTask with Executor in ParseComment.

This commit is contained in:
Alex Ning 2021-06-24 18:53:35 +08:00
parent 7067a20696
commit 05338b5a47
6 changed files with 111 additions and 150 deletions

View File

@ -6,6 +6,7 @@ import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.Spanned;
import android.text.util.Linkify;
import android.view.Menu;
@ -31,6 +32,8 @@ import org.commonmark.ext.gfm.tables.TableBlock;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
@ -98,6 +101,8 @@ public class CommentActivity extends BaseActivity {
SharedPreferences mCurrentAccountSharedPreferences;
@Inject
CustomThemeWrapper mCustomThemeWrapper;
@Inject
Executor mExecutor;
private String mAccessToken;
private String parentFullname;
private int parentDepth;
@ -308,9 +313,8 @@ public class CommentActivity extends BaseActivity {
Snackbar sendingSnackbar = Snackbar.make(coordinatorLayout, R.string.sending_comment, Snackbar.LENGTH_INDEFINITE);
sendingSnackbar.show();
SendComment.sendComment(commentEditText.getText().toString(), parentFullname, parentDepth,
getResources().getConfiguration().locale, mOauthRetrofit,
mAccessToken,
SendComment.sendComment(mExecutor, new Handler(), commentEditText.getText().toString(),
parentFullname, parentDepth, mOauthRetrofit, mAccessToken,
new SendComment.SendCommentListener() {
@Override
public void sendCommentSuccess(Comment comment) {

View File

@ -7,6 +7,7 @@ import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
@ -35,6 +36,7 @@ import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar;
import java.util.ArrayList;
import java.util.Locale;
import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -82,6 +84,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
private AppCompatActivity mActivity;
private ViewPostDetailFragment mFragment;
private Executor mExecutor;
private Retrofit mRetrofit;
private Retrofit mOauthRetrofit;
private Markwon mCommentMarkwon;
@ -138,7 +141,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
public CommentsRecyclerViewAdapter(AppCompatActivity activity, ViewPostDetailFragment fragment,
CustomThemeWrapper customThemeWrapper,
Retrofit retrofit, Retrofit oauthRetrofit,
Executor executor, Retrofit retrofit, Retrofit oauthRetrofit,
String accessToken, String accountName,
Post post, Locale locale, String singleCommentId,
boolean isSingleCommentThreadMode,
@ -146,6 +149,7 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
CommentRecyclerViewAdapterCallback commentRecyclerViewAdapterCallback) {
mActivity = activity;
mFragment = fragment;
mExecutor = executor;
mRetrofit = retrofit;
mOauthRetrofit = oauthRetrofit;
mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor();
@ -558,10 +562,10 @@ public class CommentsRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerVi
((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading);
Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit;
FetchComment.fetchMoreComment(retrofit, mAccessToken, parentComment.getMoreChildrenFullnames(),
FetchComment.fetchMoreComment(mExecutor, new Handler(), retrofit, mAccessToken,
parentComment.getMoreChildrenFullnames(),
parentComment.getMoreChildrenStartingIndex(), parentComment.getDepth() + 1,
mExpandChildren, mLocale,
new FetchComment.FetchMoreCommentListener() {
mExpandChildren, new FetchComment.FetchMoreCommentListener() {
@Override
public void onFetchMoreCommentSuccess(ArrayList<Comment> expandedComments,
int childrenStartingIndex) {

View File

@ -1,10 +1,13 @@
package ml.docilealligator.infinityforreddit.comment;
import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.Locale;
import java.util.concurrent.Executor;
import ml.docilealligator.infinityforreddit.apis.RedditAPI;
import ml.docilealligator.infinityforreddit.utils.APIUtils;
@ -14,7 +17,8 @@ import retrofit2.Response;
import retrofit2.Retrofit;
public class FetchComment {
public static void fetchComments(Retrofit retrofit, @Nullable String accessToken, String article,
public static void fetchComments(Executor executor, Handler handler, Retrofit retrofit,
@Nullable String accessToken, String article,
String commentId, String sortType, String contextNumber, boolean expandChildren,
Locale locale, FetchCommentListener fetchCommentListener) {
RedditAPI api = retrofit.create(RedditAPI.class);
@ -38,8 +42,8 @@ public class FetchComment {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
ParseComment.parseComment(response.body(), new ArrayList<>(),
locale, expandChildren, new ParseComment.ParseCommentListener() {
ParseComment.parseComment(executor, handler, response.body(), new ArrayList<>(),
expandChildren, new ParseComment.ParseCommentListener() {
@Override
public void onParseCommentSuccess(ArrayList<Comment> expandedComments,
String parentId, ArrayList<String> moreChildrenFullnames) {
@ -64,9 +68,10 @@ public class FetchComment {
});
}
public static void fetchMoreComment(Retrofit retrofit, @Nullable String accessToken,
public static void fetchMoreComment(Executor executor, Handler handler, Retrofit retrofit,
@Nullable String accessToken,
ArrayList<String> allChildren, int startingIndex,
int depth, boolean expandChildren, Locale locale,
int depth, boolean expandChildren,
FetchMoreCommentListener fetchMoreCommentListener) {
if (allChildren == null) {
return;
@ -98,7 +103,7 @@ public class FetchComment {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale,
ParseComment.parseMoreComment(executor, handler, response.body(), new ArrayList<>(),
depth, expandChildren, new ParseComment.ParseCommentListener() {
@Override
public void onParseCommentSuccess(ArrayList<Comment> expandedComments,

View File

@ -1,6 +1,6 @@
package ml.docilealligator.infinityforreddit.comment;
import android.os.AsyncTask;
import android.os.Handler;
import android.text.Html;
import androidx.annotation.Nullable;
@ -10,7 +10,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Locale;
import java.util.concurrent.Executor;
import ml.docilealligator.infinityforreddit.utils.JSONUtils;
import ml.docilealligator.infinityforreddit.utils.Utils;
@ -20,39 +20,83 @@ import static ml.docilealligator.infinityforreddit.comment.Comment.VOTE_TYPE_NO_
import static ml.docilealligator.infinityforreddit.comment.Comment.VOTE_TYPE_UPVOTE;
public class ParseComment {
public static void parseComment(String response, ArrayList<Comment> commentData, Locale locale,
boolean expandChildren, ParseCommentListener parseCommentListener) {
public static void parseComment(Executor executor, Handler handler, String response,
ArrayList<Comment> commentData, boolean expandChildren,
ParseCommentListener parseCommentListener) {
executor.execute(() -> {
try {
JSONArray childrenArray = new JSONArray(response);
String parentId = childrenArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY)
.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.NAME_KEY);
childrenArray = childrenArray.getJSONObject(1).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
new ParseCommentAsyncTask(childrenArray, commentData, locale, parentId, 0, expandChildren, parseCommentListener).execute();
} catch (JSONException e) {
e.printStackTrace();
parseCommentListener.onParseCommentFailed();
}
ArrayList<Comment> expandedNewComments = new ArrayList<>();
ArrayList<String> moreChildrenFullnames = new ArrayList<>();
ArrayList<Comment> newComments = new ArrayList<>();
parseCommentRecursion(childrenArray, newComments, moreChildrenFullnames, 0);
expandChildren(newComments, expandedNewComments, expandChildren);
if (expandChildren) {
commentData.addAll(expandedNewComments);
} else {
commentData.addAll(newComments);
}
static void parseMoreComment(String response, ArrayList<Comment> commentData, Locale locale,
int depth, boolean expandChildren, ParseCommentListener parseCommentListener) {
handler.post(() -> parseCommentListener.onParseCommentSuccess(commentData, parentId, moreChildrenFullnames));
} catch (JSONException e) {
e.printStackTrace();
handler.post(parseCommentListener::onParseCommentFailed);
}
});
}
static void parseMoreComment(Executor executor, Handler handler, String response,
ArrayList<Comment> commentData, int depth, boolean expandChildren,
ParseCommentListener parseCommentListener) {
executor.execute(() -> {
try {
JSONArray childrenArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
new ParseCommentAsyncTask(childrenArray, commentData, locale, null, depth, expandChildren, parseCommentListener).execute();
} catch (JSONException e) {
e.printStackTrace();
parseCommentListener.onParseCommentFailed();
}
ArrayList<Comment> newComments = new ArrayList<>();
ArrayList<Comment> expandedNewComments = new ArrayList<>();
ArrayList<String> moreChildrenFullnames = new ArrayList<>();
parseCommentRecursion(childrenArray, newComments, moreChildrenFullnames, depth);
expandChildren(newComments, expandedNewComments, expandChildren);
if (expandChildren) {
commentData.addAll(expandedNewComments);
} else {
commentData.addAll(newComments);
}
static void parseSentComment(String response, int depth, Locale locale,
handler.post(() -> parseCommentListener.onParseCommentSuccess(commentData, null, moreChildrenFullnames));
} catch (JSONException e) {
e.printStackTrace();
handler.post(parseCommentListener::onParseCommentFailed);
}
});
}
static void parseSentComment(Executor executor, Handler handler, String response, int depth,
ParseSentCommentListener parseSentCommentListener) {
new ParseSentCommentAsyncTask(response, depth, locale, parseSentCommentListener).execute();
executor.execute(() -> {
try {
JSONObject sentCommentData = new JSONObject(response);
Comment comment = parseSingleComment(sentCommentData, depth);
handler.post(() -> parseSentCommentListener.onParseSentCommentSuccess(comment));
} catch (JSONException e) {
e.printStackTrace();
String errorMessage = parseSentCommentErrorMessage(response);
handler.post(() -> parseSentCommentListener.onParseSentCommentFailed(errorMessage));
}
});
}
private static void parseCommentRecursion(JSONArray comments, ArrayList<Comment> newCommentData,
ArrayList<String> moreChildrenFullnames, int depth, Locale locale) throws JSONException {
ArrayList<String> moreChildrenFullnames, int depth) throws JSONException {
int actualCommentLength;
if (comments.length() == 0) {
@ -88,8 +132,7 @@ public class ParseComment {
.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
ArrayList<Comment> children = new ArrayList<>();
ArrayList<String> nextMoreChildrenFullnames = new ArrayList<>();
parseCommentRecursion(childrenArray, children, nextMoreChildrenFullnames, singleComment.getDepth(),
locale);
parseCommentRecursion(childrenArray, children, nextMoreChildrenFullnames, singleComment.getDepth());
singleComment.addChildren(children);
singleComment.setMoreChildrenFullnames(nextMoreChildrenFullnames);
}
@ -230,101 +273,4 @@ public class ParseComment {
void onParseSentCommentFailed(@Nullable String errorMessage);
}
private static class ParseCommentAsyncTask extends AsyncTask<Void, Void, Void> {
private JSONArray commentsJSONArray;
private ArrayList<Comment> comments;
private ArrayList<Comment> newComments;
private ArrayList<Comment> expandedNewComments;
private ArrayList<String> moreChildrenFullnames;
private Locale locale;
private String parentId;
private int depth;
private boolean expandChildren;
private ParseCommentListener parseCommentListener;
private boolean parseFailed;
ParseCommentAsyncTask(JSONArray commentsJSONArray, ArrayList<Comment> comments, Locale locale,
@Nullable String parentId, int depth, boolean expandChildren,
ParseCommentListener parseCommentListener) {
this.commentsJSONArray = commentsJSONArray;
this.comments = comments;
newComments = new ArrayList<>();
expandedNewComments = new ArrayList<>();
moreChildrenFullnames = new ArrayList<>();
this.locale = locale;
this.parentId = parentId;
this.depth = depth;
this.expandChildren = expandChildren;
parseFailed = false;
this.parseCommentListener = parseCommentListener;
}
@Override
protected Void doInBackground(Void... voids) {
try {
parseCommentRecursion(commentsJSONArray, newComments, moreChildrenFullnames, depth, locale);
expandChildren(newComments, expandedNewComments, expandChildren);
} catch (JSONException e) {
parseFailed = true;
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
if (!parseFailed) {
if (expandChildren) {
comments.addAll(expandedNewComments);
} else {
comments.addAll(newComments);
}
parseCommentListener.onParseCommentSuccess(comments, parentId, moreChildrenFullnames);
} else {
parseCommentListener.onParseCommentFailed();
}
}
}
private static class ParseSentCommentAsyncTask extends AsyncTask<Void, Void, Void> {
private String response;
private int depth;
private Locale locale;
private ParseSentCommentListener parseSentCommentListener;
private boolean parseFailed;
private String errorMessage;
private Comment comment;
ParseSentCommentAsyncTask(String response, int depth, Locale locale, ParseSentCommentListener parseSentCommentListener) {
this.response = response;
this.depth = depth;
this.locale = locale;
this.parseSentCommentListener = parseSentCommentListener;
parseFailed = false;
}
@Override
protected Void doInBackground(Void... voids) {
try {
JSONObject sentCommentData = new JSONObject(response);
comment = parseSingleComment(sentCommentData, depth);
} catch (JSONException e) {
e.printStackTrace();
errorMessage = parseSentCommentErrorMessage(response);
parseFailed = true;
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (parseFailed) {
parseSentCommentListener.onParseSentCommentFailed(errorMessage);
} else {
parseSentCommentListener.onParseSentCommentSuccess(comment);
}
}
}
}

View File

@ -1,11 +1,13 @@
package ml.docilealligator.infinityforreddit.comment;
import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Executor;
import ml.docilealligator.infinityforreddit.apis.RedditAPI;
import ml.docilealligator.infinityforreddit.utils.APIUtils;
@ -15,9 +17,9 @@ import retrofit2.Response;
import retrofit2.Retrofit;
public class SendComment {
public static void sendComment(String commentMarkdown, String thingFullname, int parentDepth,
Locale locale, Retrofit oauthRetrofit, String accessToken,
public static void sendComment(Executor executor, Handler handler, String commentMarkdown,
String thingFullname, int parentDepth,
Retrofit oauthRetrofit, String accessToken,
SendCommentListener sendCommentListener) {
Map<String, String> headers = APIUtils.getOAuthHeader(accessToken);
Map<String, String> params = new HashMap<>();
@ -30,7 +32,7 @@ public class SendComment {
@Override
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
if (response.isSuccessful()) {
ParseComment.parseSentComment(response.body(), parentDepth, locale, new ParseComment.ParseSentCommentListener() {
ParseComment.parseSentComment(executor, handler, response.body(), parentDepth, new ParseComment.ParseSentCommentListener() {
@Override
public void onParseSentCommentSuccess(Comment comment) {
sendCommentListener.sendCommentSuccess(comment);

View File

@ -542,7 +542,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
}
});
mCommentsAdapter = new CommentsRecyclerViewAdapter(activity,
this, mCustomThemeWrapper, mRetrofit, mOauthRetrofit,
this, mCustomThemeWrapper, mExecutor, mRetrofit, mOauthRetrofit,
mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId,
isSingleCommentThreadMode, mSharedPreferences,
new CommentsRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() {
@ -1124,8 +1124,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
});
mCommentsAdapter = new CommentsRecyclerViewAdapter(activity,
ViewPostDetailFragment.this, mCustomThemeWrapper, mRetrofit, mOauthRetrofit,
mAccessToken, mAccountName, mPost, mLocale,
ViewPostDetailFragment.this, mCustomThemeWrapper, mExecutor,
mRetrofit, mOauthRetrofit, mAccessToken, mAccountName, mPost, mLocale,
mSingleCommentId, isSingleCommentThreadMode, mSharedPreferences,
new CommentsRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() {
@Override
@ -1152,7 +1152,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
if (mRespectSubredditRecommendedSortType) {
fetchCommentsRespectRecommendedSort(false);
} else {
ParseComment.parseComment(response.body(), new ArrayList<>(), mLocale,
ParseComment.parseComment(mExecutor, new Handler(), response.body(), new ArrayList<>(),
mExpandChildren, new ParseComment.ParseCommentListener() {
@Override
public void onParseCommentSuccess(ArrayList<Comment> expandedComments, String parentId, ArrayList<String> moreChildrenFullnames) {
@ -1280,7 +1280,7 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
}
Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit;
FetchComment.fetchComments(retrofit, mAccessToken, mPost.getId(), commentId, sortType,
FetchComment.fetchComments(mExecutor, new Handler(), retrofit, mAccessToken, mPost.getId(), commentId, sortType,
mContextNumber, mExpandChildren, mLocale, new FetchComment.FetchCommentListener() {
@Override
public void onFetchCommentSuccess(ArrayList<Comment> expandedComments,
@ -1382,8 +1382,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic
isLoadingMoreChildren = true;
Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit;
FetchComment.fetchMoreComment(retrofit, mAccessToken, children, mChildrenStartingIndex,
0, mExpandChildren, mLocale, new FetchComment.FetchMoreCommentListener() {
FetchComment.fetchMoreComment(mExecutor, new Handler(), retrofit, mAccessToken, children, mChildrenStartingIndex,
0, mExpandChildren, new FetchComment.FetchMoreCommentListener() {
@Override
public void onFetchMoreCommentSuccess(ArrayList<Comment> expandedComments, int childrenStartingIndex) {
hasMoreChildren = childrenStartingIndex < children.size();