diff --git a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
index 0d5e9005d2b54d57cc05da816417ff0d0506ba5c..03e7595a7e1d82a5139cd6442b58cafae7ec2f04 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
@@ -36,7 +36,6 @@ import java.util.logging.Logger;
 
 import javax.inject.Inject;
 
-import static android.support.v7.util.SortedList.INVALID_POSITION;
 import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
 
@@ -91,7 +90,6 @@ public class ContactListActivity extends BriarActivity
 	public void onResume() {
 		super.onResume();
 		eventBus.addListener(this);
-
 		loadContacts();
 	}
 
@@ -133,26 +131,9 @@ public class ContactListActivity extends BriarActivity
 	private void displayContacts(final List<ContactListItem> contacts) {
 		runOnUiThread(new Runnable() {
 			public void run() {
-				if (contacts.size() > 0) {
-					if (adapter.getItemCount() > 0) {
-						// update existing items rather than just adding them,
-						// because different timestamps in added items change
-						// sorting criteria and cause duplicates
-						for (ContactListItem contact : contacts) {
-							int position = adapter.findItemPosition(contact);
-							if (position == INVALID_POSITION) {
-								adapter.add(contact);
-							} else {
-								adapter.updateItem(position, contact);
-							}
-						}
-					} else {
-						adapter.addAll(contacts);
-					}
-				} else {
-					// no contacts to display, make sure progress bar is hidden
-					list.showData();
-				}
+				adapter.clear();
+				if (contacts.size() == 0) list.showData();
+				else adapter.addAll(contacts);
 			}
 		});
 	}
@@ -217,10 +198,9 @@ public class ContactListActivity extends BriarActivity
 	private void removeItem(final ContactId c) {
 		runOnUiThread(new Runnable() {
 			public void run() {
-				ContactListItem item = adapter.findItem(c);
-				if (item != null) {
-					adapter.remove(item);
-				}
+				int position = adapter.findItemPosition(c);
+				ContactListItem item = adapter.getItem(position);
+				if (item != null) adapter.remove(item);
 			}
 		});
 	}
diff --git a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
index 777349e687a630cc23e67cc9366de7998d6a3e28..9d040e87d55380621a75ef665676ca92a0809c57 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
@@ -23,7 +23,7 @@ import static android.support.v7.util.SortedList.INVALID_POSITION;
 public class ContactListAdapter
 		extends RecyclerView.Adapter<ContactListAdapter.ContactHolder> {
 
-	private SortedList<ContactListItem> contacts =
+	private final SortedList<ContactListItem> contacts =
 			new SortedList<ContactListItem>(ContactListItem.class,
 					new SortedList.Callback<ContactListItem>() {
 						@Override
@@ -141,11 +141,7 @@ public class ContactListAdapter
 
 	@Override
 	public int getItemCount() {
-		return contacts == null ? 0 : contacts.size();
-	}
-
-	public boolean isEmpty() {
-		return contacts == null || contacts.size() == 0;
+		return contacts.size();
 	}
 
 	public ContactListItem getItem(int position) {
@@ -159,15 +155,6 @@ public class ContactListAdapter
 		contacts.updateItemAt(position, item);
 	}
 
-	public ContactListItem findItem(ContactId c) {
-		int count = getItemCount();
-		for (int i = 0; i < count; i++) {
-			ContactListItem item = getItem(i);
-			if (item.getContact().getId().equals(c)) return item;
-		}
-		return null; // Not found
-	}
-
 	public int findItemPosition(ContactListItem item) {
 		return contacts.indexOf(item);
 	}
@@ -181,16 +168,16 @@ public class ContactListAdapter
 		return INVALID_POSITION; // Not found
 	}
 
-	public void addAll(final List<ContactListItem> contacts) {
+	public void addAll(List<ContactListItem> contacts) {
 		this.contacts.addAll(contacts);
 	}
 
-	public void add(final ContactListItem contact) {
-		this.contacts.add(contact);
+	public void add(ContactListItem contact) {
+		contacts.add(contact);
 	}
 
-	public void remove(final ContactListItem contact) {
-		this.contacts.remove(contact);
+	public void remove(ContactListItem contact) {
+		contacts.remove(contact);
 	}
 
 	public void clear() {
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
index 96f61a4499b1cea9fb2944a71177376296cd4ce4..09509c0ee4cfd411672bea00da246de2a3598d4c 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
@@ -14,6 +14,8 @@ import org.briarproject.R;
 import org.briarproject.api.messaging.PrivateMessageHeader;
 import org.briarproject.util.StringUtils;
 
+import static android.support.v7.util.SortedList.INVALID_POSITION;
+
 class ConversationAdapter extends
 		RecyclerView.Adapter<ConversationAdapter.MessageHolder> {
 
@@ -21,7 +23,7 @@ class ConversationAdapter extends
 	private static final int MSG_IN = 1;
 	private static final int MSG_IN_UNREAD = 2;
 
-	private SortedList<ConversationItem> messages =
+	private final SortedList<ConversationItem> messages =
 			new SortedList<ConversationItem>(ConversationItem.class,
 					new SortedList.Callback<ConversationItem>() {
 						@Override
@@ -145,14 +147,13 @@ class ConversationAdapter extends
 
 	@Override
 	public int getItemCount() {
-		return messages == null ? 0 : messages.size();
-	}
-
-	public boolean isEmpty() {
-		return messages == null || messages.size() == 0;
+		return messages.size();
 	}
 
 	public ConversationItem getItem(int position) {
+		if (position == INVALID_POSITION || messages.size() <= position) {
+			return null; // Not found
+		}
 		return messages.get(position);
 	}
 
@@ -168,10 +169,6 @@ class ConversationAdapter extends
 		this.messages.add(message);
 	}
 
-	public void remove(final ConversationItem message) {
-		this.messages.remove(message);
-	}
-
 	public void clear() {
 		this.messages.beginBatchedUpdates();
 
diff --git a/briar-android/src/org/briarproject/android/forum/AvailableForumsActivity.java b/briar-android/src/org/briarproject/android/forum/AvailableForumsActivity.java
index a14704d30991db1c05e9ff6704e62a6aa35eda9f..c8cd4b051ae45aa570bf62ad79e85bdb59350e92 100644
--- a/briar-android/src/org/briarproject/android/forum/AvailableForumsActivity.java
+++ b/briar-android/src/org/briarproject/android/forum/AvailableForumsActivity.java
@@ -111,7 +111,6 @@ implements EventListener, OnItemClickListener {
 					for (ForumContacts f : available)
 						adapter.add(new AvailableForumsItem(f));
 					adapter.sort(AvailableForumsItemComparator.INSTANCE);
-					adapter.notifyDataSetChanged();
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/forum/ForumActivity.java b/briar-android/src/org/briarproject/android/forum/ForumActivity.java
index 73706fad8997f20e07a834fd08073e65252f676b..7f725d40d2db8a62bcd2653572a3348ce689bdc9 100644
--- a/briar-android/src/org/briarproject/android/forum/ForumActivity.java
+++ b/briar-android/src/org/briarproject/android/forum/ForumActivity.java
@@ -220,7 +220,6 @@ public class ForumActivity extends BriarActivity implements EventListener,
 					// Scroll to the bottom
 					list.setSelection(adapter.getCount() - 1);
 				}
-				adapter.notifyDataSetChanged();
 			}
 		});
 	}
diff --git a/briar-android/src/org/briarproject/android/forum/ForumListActivity.java b/briar-android/src/org/briarproject/android/forum/ForumListActivity.java
index 7ee1693a498cc0afc830626216b7f73dab18cd2d..fef329409a2b21c4c62bb4a0f2ba9d64fcf91c5c 100644
--- a/briar-android/src/org/briarproject/android/forum/ForumListActivity.java
+++ b/briar-android/src/org/briarproject/android/forum/ForumListActivity.java
@@ -180,7 +180,6 @@ public class ForumListActivity extends BriarActivity
 				available.setVisibility(GONE);
 				loading.setVisibility(VISIBLE);
 				adapter.clear();
-				adapter.notifyDataSetChanged();
 			}
 		});
 	}
@@ -197,7 +196,6 @@ public class ForumListActivity extends BriarActivity
 				// Add a new item
 				adapter.add(new ForumListItem(f, headers));
 				adapter.sort(ForumListItemComparator.INSTANCE);
-				adapter.notifyDataSetChanged();
 				selectFirstUnread();
 			}
 		});
@@ -298,7 +296,6 @@ public class ForumListActivity extends BriarActivity
 				ForumListItem item = findForum(g);
 				if (item != null) {
 					adapter.remove(item);
-					adapter.notifyDataSetChanged();
 					if (adapter.isEmpty()) {
 						empty.setVisibility(VISIBLE);
 						list.setVisibility(GONE);
diff --git a/briar-android/src/org/briarproject/android/forum/WriteForumPostActivity.java b/briar-android/src/org/briarproject/android/forum/WriteForumPostActivity.java
index a29fade64a183f139cc3e76dca1d3abf7022feb7..40e72a14877abad5ce9c4f3d74b3dc372a3449f3 100644
--- a/briar-android/src/org/briarproject/android/forum/WriteForumPostActivity.java
+++ b/briar-android/src/org/briarproject/android/forum/WriteForumPostActivity.java
@@ -192,7 +192,6 @@ implements OnItemSelectedListener, OnClickListener {
 				for (LocalAuthor a : localAuthors)
 					adapter.add(new LocalAuthorItem(a));
 				adapter.sort(LocalAuthorItemComparator.INSTANCE);
-				adapter.notifyDataSetChanged();
 				int count = adapter.getCount();
 				for (int i = 0; i < count; i++) {
 					LocalAuthorItem item = adapter.getItem(i);
diff --git a/briar-android/src/org/briarproject/android/identity/LocalAuthorSpinnerAdapter.java b/briar-android/src/org/briarproject/android/identity/LocalAuthorSpinnerAdapter.java
index 7fc331edf9bb28d3ef25404eef589fa2383bb10c..2aa2358f45e1c62c248e7ba6109cd4ed0cb4aca3 100644
--- a/briar-android/src/org/briarproject/android/identity/LocalAuthorSpinnerAdapter.java
+++ b/briar-android/src/org/briarproject/android/identity/LocalAuthorSpinnerAdapter.java
@@ -1,17 +1,5 @@
 package org.briarproject.android.identity;
 
-import static android.text.TextUtils.TruncateAt.END;
-import static org.briarproject.android.identity.LocalAuthorItem.ANONYMOUS;
-import static org.briarproject.android.identity.LocalAuthorItem.NEW;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import org.briarproject.R;
-import org.briarproject.android.util.LayoutUtils;
-
 import android.content.Context;
 import android.view.View;
 import android.view.ViewGroup;
@@ -19,6 +7,18 @@ import android.widget.BaseAdapter;
 import android.widget.SpinnerAdapter;
 import android.widget.TextView;
 
+import org.briarproject.R;
+import org.briarproject.android.util.LayoutUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import static android.text.TextUtils.TruncateAt.END;
+import static org.briarproject.android.identity.LocalAuthorItem.ANONYMOUS;
+import static org.briarproject.android.identity.LocalAuthorItem.NEW;
+
 public class LocalAuthorSpinnerAdapter extends BaseAdapter
 implements SpinnerAdapter {
 
@@ -33,10 +33,12 @@ implements SpinnerAdapter {
 
 	public void add(LocalAuthorItem item) {
 		list.add(item);
+		notifyDataSetChanged();
 	}
 
 	public void clear() {
 		list.clear();
+		notifyDataSetChanged();
 	}
 
 	public int getCount() {
@@ -94,5 +96,6 @@ implements SpinnerAdapter {
 
 	public void sort(Comparator<LocalAuthorItem> comparator) {
 		Collections.sort(list, comparator);
+		notifyDataSetChanged();
 	}
 }
diff --git a/briar-android/src/org/briarproject/android/invitation/ChooseIdentityView.java b/briar-android/src/org/briarproject/android/invitation/ChooseIdentityView.java
index 95fcca9057e6bc6139ace43234c315d53f7ead89..940de7e7594f83fff6a48fd6d1d0062ce8e8f048 100644
--- a/briar-android/src/org/briarproject/android/invitation/ChooseIdentityView.java
+++ b/briar-android/src/org/briarproject/android/invitation/ChooseIdentityView.java
@@ -66,7 +66,6 @@ implements OnItemSelectedListener, OnClickListener {
 		adapter.clear();
 		for (LocalAuthor a : authors) adapter.add(new LocalAuthorItem(a));
 		adapter.sort(LocalAuthorItemComparator.INSTANCE);
-		adapter.notifyDataSetChanged();
 		// If a local author has been selected, select it again
 		AuthorId localAuthorId = container.getLocalAuthorId();
 		if (localAuthorId == null) return;