user list bug fix, database fix, async fix
This commit is contained in:
parent
3ddd0e92ed
commit
ec6afb12e2
|
@ -316,7 +316,8 @@ public class TwitterV1 implements Connection {
|
|||
public Users getFollowing(long id, long cursor) throws TwitterException {
|
||||
List<String> params = new ArrayList<>();
|
||||
params.add("user_id=" + id);
|
||||
params.add("cursor=" + cursor);
|
||||
if (cursor != 0L)
|
||||
params.add("cursor=" + cursor);
|
||||
return getUsers(USERS_FOLLOWING, params);
|
||||
}
|
||||
|
||||
|
@ -325,7 +326,8 @@ public class TwitterV1 implements Connection {
|
|||
public Users getFollower(long id, long cursor) throws TwitterException {
|
||||
List<String> params = new ArrayList<>();
|
||||
params.add("user_id=" + id);
|
||||
params.add("cursor=" + cursor);
|
||||
if (cursor != 0L)
|
||||
params.add("cursor=" + cursor);
|
||||
return getUsers(USERS_FOLLOWER, params);
|
||||
}
|
||||
|
||||
|
@ -334,7 +336,8 @@ public class TwitterV1 implements Connection {
|
|||
public Users getListMember(long id, long cursor) throws TwitterException {
|
||||
List<String> params = new ArrayList<>();
|
||||
params.add("list_id=" + id);
|
||||
params.add("cursor=" + cursor);
|
||||
if (cursor != 0L)
|
||||
params.add("cursor=" + cursor);
|
||||
Users result = getUsers(USERS_LIST_MEMBER, params);
|
||||
// fix API returns zero previous_cursor when the end of the list is reached
|
||||
// override previous cursor
|
||||
|
@ -350,7 +353,8 @@ public class TwitterV1 implements Connection {
|
|||
public Users getListSubscriber(long id, long cursor) throws TwitterException {
|
||||
List<String> params = new ArrayList<>();
|
||||
params.add("list_id=" + id);
|
||||
params.add("cursor=" + cursor);
|
||||
if (cursor != 0L)
|
||||
params.add("cursor=" + cursor);
|
||||
Users result = getUsers(USERS_LIST_SUBSCRIBER, params);
|
||||
// fix API returns zero previous_cursor when the end of the list is reached
|
||||
// override previous cursor
|
||||
|
@ -365,7 +369,8 @@ public class TwitterV1 implements Connection {
|
|||
@Override
|
||||
public Users getBlockedUsers(long cursor) throws TwitterException {
|
||||
List<String> params = new ArrayList<>();
|
||||
params.add("cursor=" + cursor);
|
||||
if (cursor != 0L)
|
||||
params.add("cursor=" + cursor);
|
||||
return getUsers(USERS_BLOCKED_LIST, params);
|
||||
}
|
||||
|
||||
|
@ -373,7 +378,8 @@ public class TwitterV1 implements Connection {
|
|||
@Override
|
||||
public Users getMutedUsers(long cursor) throws TwitterException {
|
||||
List<String> params = new ArrayList<>();
|
||||
params.add("cursor=" + cursor);
|
||||
if (cursor != 0L)
|
||||
params.add("cursor=" + cursor);
|
||||
return getUsers(USERS_MUTES, params);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,21 @@ public abstract class AsyncExecutor<Parameter, Result> {
|
|||
/**
|
||||
* maximum task count to run in the background
|
||||
*/
|
||||
private static final int N_THREAD = 2;
|
||||
private static final int N_THREAD = 4;
|
||||
|
||||
private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(N_THREAD);
|
||||
/**
|
||||
* thread pool executor
|
||||
*/
|
||||
private static final ExecutorService THREAD_POOL = Executors.newFixedThreadPool(N_THREAD);
|
||||
|
||||
private Handler uiHandler = new Handler(Looper.getMainLooper());
|
||||
/**
|
||||
* handler used to send result back to activity/fragment
|
||||
*/
|
||||
private static final Handler UI_HANDLER = new Handler(Looper.getMainLooper());
|
||||
|
||||
/**
|
||||
* callback to activity/fragment
|
||||
*/
|
||||
private WeakReference<AsyncCallback<Result>> callback;
|
||||
|
||||
/**
|
||||
|
@ -43,7 +53,7 @@ public abstract class AsyncExecutor<Parameter, Result> {
|
|||
*/
|
||||
public final void execute(final Parameter parameter, @Nullable AsyncCallback<Result> callback) {
|
||||
this.callback = new WeakReference<>(callback);
|
||||
Future<?> future = EXECUTOR.submit(new Runnable() {
|
||||
Future<?> future = THREAD_POOL.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Result result = doInBackground(parameter);
|
||||
|
@ -78,7 +88,7 @@ public abstract class AsyncExecutor<Parameter, Result> {
|
|||
* @param result result of the background task
|
||||
*/
|
||||
private void onPostExecute(final Result result) {
|
||||
uiHandler.post(new Runnable() {
|
||||
UI_HANDLER.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!queue.isEmpty())
|
||||
|
|
|
@ -80,11 +80,11 @@ public class UsersLoader extends AsyncExecutor<UsersLoader.UserParam, UsersLoade
|
|||
break;
|
||||
}
|
||||
} catch (ConnectionException exception) {
|
||||
return new UserResult(null, exception);
|
||||
return new UserResult(null, param.index, exception);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new UserResult(users, null);
|
||||
return new UserResult(users, param.index, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,12 +104,13 @@ public class UsersLoader extends AsyncExecutor<UsersLoader.UserParam, UsersLoade
|
|||
public static final int REQUEST_OUT = 10;
|
||||
public static final int REQUEST_IN = 11;
|
||||
|
||||
public final int type;
|
||||
public final int type, index;
|
||||
public final String search;
|
||||
public final long id, cursor;
|
||||
|
||||
public UserParam(int type, long id, long cursor, String search) {
|
||||
public UserParam(int type, int index, long id, long cursor, String search) {
|
||||
this.type = type;
|
||||
this.index = index;
|
||||
this.id = id;
|
||||
this.cursor = cursor;
|
||||
this.search = search;
|
||||
|
@ -125,9 +126,11 @@ public class UsersLoader extends AsyncExecutor<UsersLoader.UserParam, UsersLoade
|
|||
public final Users users;
|
||||
@Nullable
|
||||
public final ConnectionException exception;
|
||||
public final int index;
|
||||
|
||||
UserResult(@Nullable Users users, @Nullable ConnectionException exception) {
|
||||
UserResult(@Nullable Users users, int index, @Nullable ConnectionException exception) {
|
||||
this.users = users;
|
||||
this.index = index;
|
||||
this.exception = exception;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,24 +37,6 @@ public class Users extends LinkedList<User> {
|
|||
return super.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if list is linked to a previous list
|
||||
*
|
||||
* @return true if list is linked
|
||||
*/
|
||||
public boolean hasPrevious() {
|
||||
return prevCursor != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if list has a successor
|
||||
*
|
||||
* @return true if list has a successor
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return nextCursor != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* get next link to a list
|
||||
*
|
||||
|
@ -64,18 +46,6 @@ public class Users extends LinkedList<User> {
|
|||
return nextCursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* replace whole list including cursors
|
||||
*
|
||||
* @param list new list
|
||||
*/
|
||||
public void replace(Users list) {
|
||||
super.clear();
|
||||
super.addAll(list);
|
||||
prevCursor = list.prevCursor;
|
||||
nextCursor = list.nextCursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* set previous cursor
|
||||
*
|
||||
|
@ -94,17 +64,37 @@ public class Users extends LinkedList<User> {
|
|||
this.nextCursor = nextCursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* replace whole list including cursors
|
||||
*
|
||||
* @param list new list
|
||||
*/
|
||||
public void replaceAll(Users list) {
|
||||
super.clear();
|
||||
super.addAll(list);
|
||||
prevCursor = list.prevCursor;
|
||||
nextCursor = list.nextCursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a sublist at the bottom of this list including next cursor
|
||||
*
|
||||
* @param list new sublist
|
||||
* @param index index of the sub list
|
||||
*/
|
||||
public void addAt(Users list, int index) {
|
||||
super.addAll(index, list);
|
||||
nextCursor = list.nextCursor;
|
||||
public boolean addAll(int index, Users list) {
|
||||
if (isEmpty()) {
|
||||
prevCursor = list.prevCursor;
|
||||
nextCursor = list.nextCursor;
|
||||
} else if (index == 0) {
|
||||
prevCursor = list.prevCursor;
|
||||
} else if (index == size() - 1) {
|
||||
nextCursor = list.nextCursor;
|
||||
}
|
||||
return super.addAll(index, list);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -383,7 +383,7 @@ public class DatabaseAdapter {
|
|||
* @param context application context
|
||||
* @return database instance
|
||||
*/
|
||||
public static DatabaseAdapter getInstance(@NonNull Context context) {
|
||||
static DatabaseAdapter getInstance(@NonNull Context context) {
|
||||
if (instance == null) {
|
||||
try {
|
||||
instance = new DatabaseAdapter(context.getApplicationContext());
|
||||
|
@ -402,7 +402,7 @@ public class DatabaseAdapter {
|
|||
*
|
||||
* @return SQLite instance
|
||||
*/
|
||||
synchronized SQLiteDatabase getDbRead() {
|
||||
SQLiteDatabase getDbRead() {
|
||||
if (!db.isOpen())
|
||||
db = SQLiteDatabase.openOrCreateDatabase(databasePath, null);
|
||||
return db;
|
||||
|
@ -413,7 +413,7 @@ public class DatabaseAdapter {
|
|||
*
|
||||
* @return SQLite instance
|
||||
*/
|
||||
synchronized SQLiteDatabase getDbWrite() {
|
||||
SQLiteDatabase getDbWrite() {
|
||||
SQLiteDatabase db = getDbRead();
|
||||
db.beginTransaction();
|
||||
return db;
|
||||
|
@ -422,7 +422,7 @@ public class DatabaseAdapter {
|
|||
/**
|
||||
* Commit changes and close Database
|
||||
*/
|
||||
synchronized void commit() {
|
||||
void commit() {
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
}
|
||||
|
|
|
@ -224,11 +224,10 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult
|
|||
if (o instanceof User) {
|
||||
user = (User) o;
|
||||
userId = user.getId();
|
||||
adapter.setupProfilePage(user.getId());
|
||||
} else {
|
||||
userId = i.getLongExtra(KEY_PROFILE_ID, 0);
|
||||
adapter.setupProfilePage(userId);
|
||||
}
|
||||
adapter.setupProfilePage(userId);
|
||||
if (settings.likeEnabled()) {
|
||||
tabIndicator = AppStyles.setTabIconsWithText(tabLayout, settings, R.array.profile_tab_icons_like);
|
||||
} else {
|
||||
|
@ -735,6 +734,8 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult
|
|||
Spanned bio = Tagger.makeTextWithLinks(user.getDescription(), settings.getHighlightColor(), this);
|
||||
following.setText(StringTools.NUMBER_FORMAT.format(user.getFollowing()));
|
||||
follower.setText(StringTools.NUMBER_FORMAT.format(user.getFollower()));
|
||||
following.setVisibility(VISIBLE);
|
||||
follower.setVisibility(VISIBLE);
|
||||
username.setText(user.getUsername());
|
||||
screenName.setText(user.getScreenname());
|
||||
if (user.getStatusCount() >= 0) {
|
||||
|
@ -806,9 +807,5 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult
|
|||
profileImage.setImageResource(0);
|
||||
}
|
||||
}
|
||||
if (following.getVisibility() != VISIBLE) {
|
||||
following.setVisibility(VISIBLE);
|
||||
follower.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -114,10 +114,10 @@ public class UserAdapter extends Adapter<ViewHolder> implements OnHolderClickLis
|
|||
|
||||
|
||||
@Override
|
||||
public boolean onPlaceholderClick(int position) {
|
||||
boolean actionPerformed = listener.onPlaceholderClick(users.getNext());
|
||||
public boolean onPlaceholderClick(int index) {
|
||||
boolean actionPerformed = listener.onPlaceholderClick(users.getNext(), index);
|
||||
if (actionPerformed) {
|
||||
loadingIndex = position;
|
||||
loadingIndex = index;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -148,36 +148,24 @@ public class UserAdapter extends Adapter<ViewHolder> implements OnHolderClickLis
|
|||
*
|
||||
* @param newUsers new userlist
|
||||
*/
|
||||
public void addItems(@NonNull Users newUsers) {
|
||||
disableLoading();
|
||||
// add empty list
|
||||
if (newUsers.isEmpty()) {
|
||||
// remove placeholder if there isn't a next page
|
||||
if (!users.isEmpty() && users.peekLast() == null) {
|
||||
int end = users.size() - 1;
|
||||
users.remove(end);
|
||||
notifyItemRemoved(end);
|
||||
}
|
||||
}
|
||||
// add items to the top of the list
|
||||
else if (users.isEmpty() || !newUsers.hasPrevious()) {
|
||||
users.replace(newUsers);
|
||||
// add placeholder if there is a next page
|
||||
if (newUsers.hasNext()) {
|
||||
public void addItems(@NonNull Users newUsers, int index) {
|
||||
if (index < 0) {
|
||||
users.replaceAll(newUsers);
|
||||
if (users.getNext() != 0L) {
|
||||
users.add(null);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
// add items to the end of the list
|
||||
else {
|
||||
int end = users.size() - 1;
|
||||
// remove placeholder if there isn't a next page
|
||||
if (!newUsers.hasNext()) {
|
||||
users.remove(end);
|
||||
notifyItemRemoved(end);
|
||||
} else {
|
||||
users.addAll(index, newUsers);
|
||||
if (users.getNext() != 0L && users.peekLast() != null) {
|
||||
users.add(null);
|
||||
notifyItemRangeInserted(index, newUsers.size() + 1);
|
||||
} else if (users.getNext() == 0L && users.peekLast() == null) {
|
||||
users.remove(users.size() - 1);
|
||||
notifyItemRangeInserted(index, newUsers.size() - 1);
|
||||
} else if (!newUsers.isEmpty()) {
|
||||
notifyItemRangeInserted(index, newUsers.size());
|
||||
}
|
||||
users.addAt(newUsers, end);
|
||||
notifyItemRangeInserted(end, newUsers.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,9 +222,10 @@ public class UserAdapter extends Adapter<ViewHolder> implements OnHolderClickLis
|
|||
* handle placeholder click
|
||||
*
|
||||
* @param cursor next cursor of the list
|
||||
* @param index index of the placeholder
|
||||
* @return true if click was handled
|
||||
*/
|
||||
boolean onPlaceholderClick(long cursor);
|
||||
boolean onPlaceholderClick(long cursor, int index);
|
||||
|
||||
/**
|
||||
* remove user from a list
|
||||
|
|
|
@ -136,6 +136,11 @@ public class UserFragment extends ListFragment implements UserClickListener, Asy
|
|||
*/
|
||||
public static final int USER_FRAG_FOLLOW_OUTGOING = 0x72544f17;
|
||||
|
||||
/**
|
||||
* "index" used to replace the whole list with new items
|
||||
*/
|
||||
public static final int CLEAR_LIST = -1;
|
||||
|
||||
|
||||
private ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), this);
|
||||
|
||||
|
@ -163,14 +168,14 @@ public class UserFragment extends ListFragment implements UserClickListener, Asy
|
|||
setAdapter(adapter);
|
||||
|
||||
setRefresh(true);
|
||||
load(-1L);
|
||||
load(-1L, CLEAR_LIST);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onReset() {
|
||||
setRefresh(true);
|
||||
load(-1L);
|
||||
load(-1L, CLEAR_LIST);
|
||||
}
|
||||
|
||||
|
||||
|
@ -196,7 +201,7 @@ public class UserFragment extends ListFragment implements UserClickListener, Asy
|
|||
|
||||
@Override
|
||||
protected void onReload() {
|
||||
load(-1L);
|
||||
load(-1L, CLEAR_LIST);
|
||||
}
|
||||
|
||||
|
||||
|
@ -211,9 +216,9 @@ public class UserFragment extends ListFragment implements UserClickListener, Asy
|
|||
|
||||
|
||||
@Override
|
||||
public boolean onPlaceholderClick(long cursor) {
|
||||
public boolean onPlaceholderClick(long cursor, int index) {
|
||||
if (userLoader.isIdle()) {
|
||||
load(cursor);
|
||||
load(cursor, index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -233,7 +238,7 @@ public class UserFragment extends ListFragment implements UserClickListener, Asy
|
|||
@Override
|
||||
public void onResult(UserResult result) {
|
||||
if (result.users != null) {
|
||||
adapter.addItems(result.users);
|
||||
adapter.addItems(result.users, result.index);
|
||||
} else if (getContext() != null) {
|
||||
String message = ErrorHandler.getErrorMessage(getContext(), result.exception);
|
||||
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
|
||||
|
@ -257,51 +262,51 @@ public class UserFragment extends ListFragment implements UserClickListener, Asy
|
|||
*
|
||||
* @param cursor cursor of the list
|
||||
*/
|
||||
private void load(long cursor) {
|
||||
private void load(long cursor, int index) {
|
||||
UserParam param;
|
||||
switch (mode) {
|
||||
case USER_FRAG_FOLLOWER:
|
||||
param = new UserParam(UserParam.FOLLOWS, id, cursor, search);
|
||||
param = new UserParam(UserParam.FOLLOWS, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
case USER_FRAG_FOLLOWING:
|
||||
param = new UserParam(UserParam.FRIENDS, id, cursor, search);
|
||||
param = new UserParam(UserParam.FRIENDS, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
case USER_FRAG_REPOST:
|
||||
param = new UserParam(UserParam.REPOST, id, cursor, search);
|
||||
param = new UserParam(UserParam.REPOST, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
case USER_FRAG_FAVORIT:
|
||||
param = new UserParam(UserParam.FAVORIT, id, cursor, search);
|
||||
param = new UserParam(UserParam.FAVORIT, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
case USER_FRAG_SEARCH:
|
||||
param = new UserParam(UserParam.SEARCH, id, cursor, search);
|
||||
param = new UserParam(UserParam.SEARCH, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
case USER_FRAG_LIST_SUBSCRIBER:
|
||||
param = new UserParam(UserParam.SUBSCRIBER, id, cursor, search);
|
||||
param = new UserParam(UserParam.SUBSCRIBER, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
case USER_FRAG_LIST_MEMBERS:
|
||||
param = new UserParam(UserParam.LISTMEMBER, id, cursor, search);
|
||||
param = new UserParam(UserParam.LISTMEMBER, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
case USER_FRAG_BLOCKED_USERS:
|
||||
param = new UserParam(UserParam.BLOCK, id, cursor, search);
|
||||
param = new UserParam(UserParam.BLOCK, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
case USER_FRAG_MUTED_USERS:
|
||||
param = new UserParam(UserParam.MUTE, id, cursor, search);
|
||||
param = new UserParam(UserParam.MUTE, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
case USER_FRAG_FOLLOW_OUTGOING:
|
||||
param = new UserParam(UserParam.REQUEST_OUT, id, cursor, search);
|
||||
param = new UserParam(UserParam.REQUEST_OUT, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
case USER_FRAG_FOLLOW_INCOMING:
|
||||
param = new UserParam(UserParam.REQUEST_IN, id, cursor, search);
|
||||
param = new UserParam(UserParam.REQUEST_IN, index, id, cursor, search);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue