mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 03:09:04 +01:00
Avoid race conditions when updating the UI from events.
This commit is contained in:
@@ -24,13 +24,15 @@ public abstract class ThreadItemAdapter<I extends ThreadItem>
|
||||
|
||||
private final NestedTreeList<I> items = new NestedTreeList<>();
|
||||
private final Map<I, ValueAnimator> animatingItems = new HashMap<>();
|
||||
private final ThreadItemListener<I> listener;
|
||||
private final LinearLayoutManager layoutManager;
|
||||
|
||||
// highlight not dependant on time
|
||||
private I replyItem;
|
||||
// temporary highlight
|
||||
private I addedItem;
|
||||
|
||||
private final ThreadItemListener<I> listener;
|
||||
private final LinearLayoutManager layoutManager;
|
||||
private volatile int revision = 0;
|
||||
|
||||
public ThreadItemAdapter(ThreadItemListener<I> listener,
|
||||
LinearLayoutManager layoutManager) {
|
||||
@@ -290,6 +292,29 @@ public abstract class ThreadItemAdapter<I extends ThreadItem>
|
||||
animatingItems.remove(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the adapter's revision counter. This method should be called on
|
||||
* any thread before starting an asynchronous load that could overwrite
|
||||
* other changes to the adapter, and called again on the UI thread before
|
||||
* applying the changes from the asynchronous load. If the revision has
|
||||
* changed between the two calls, the asynchronous load should be restarted
|
||||
* without applying its changes. Otherwise {@link #incrementRevision()}
|
||||
* should be called before applying the changes.
|
||||
*/
|
||||
public int getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the adapter's revision counter. This method should be called
|
||||
* on the UI thread before applying any changes to the adapter that could
|
||||
* be overwritten by an asynchronous load.
|
||||
*/
|
||||
@UiThread
|
||||
public void incrementRevision() {
|
||||
revision++;
|
||||
}
|
||||
|
||||
protected interface ThreadItemListener<I> {
|
||||
|
||||
void onItemVisible(I item);
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.briarproject.api.sync.MessageId;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static android.support.design.widget.Snackbar.make;
|
||||
import static android.view.View.GONE;
|
||||
@@ -42,6 +43,9 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
|
||||
protected static final String KEY_INPUT_VISIBILITY = "inputVisibility";
|
||||
protected static final String KEY_REPLY_ID = "replyId";
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ThreadListActivity.class.getName());
|
||||
|
||||
protected A adapter;
|
||||
protected BriarRecyclerView list;
|
||||
protected TextInputView textInput;
|
||||
@@ -106,18 +110,24 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
|
||||
protected abstract void onNamedGroupLoaded(G groupItem);
|
||||
|
||||
private void loadItems() {
|
||||
final int revision = adapter.getRevision();
|
||||
getController().loadItems(
|
||||
new UiResultExceptionHandler<Collection<I>, DbException>(
|
||||
this) {
|
||||
new UiResultExceptionHandler<Collection<I>, DbException>(this) {
|
||||
@Override
|
||||
public void onResultUi(Collection<I> items) {
|
||||
if (items.isEmpty()) {
|
||||
list.showData();
|
||||
if (revision == adapter.getRevision()) {
|
||||
adapter.incrementRevision();
|
||||
if (items.isEmpty()) {
|
||||
list.showData();
|
||||
} else {
|
||||
adapter.setItems(items);
|
||||
list.showData();
|
||||
if (replyId != null)
|
||||
adapter.setReplyItemById(replyId);
|
||||
}
|
||||
} else {
|
||||
adapter.setItems(items);
|
||||
list.showData();
|
||||
if (replyId != null)
|
||||
adapter.setReplyItemById(replyId);
|
||||
LOG.info("Concurrent update, reloading");
|
||||
loadItems();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,6 +281,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
|
||||
}
|
||||
|
||||
protected void addItem(final I item, boolean isLocal) {
|
||||
adapter.incrementRevision();
|
||||
adapter.add(item);
|
||||
if (isLocal && adapter.isVisible(item)) {
|
||||
displaySnackbarShort(getItemPostedString());
|
||||
|
||||
Reference in New Issue
Block a user