From 86f8d97d81d10a99f8dd8b83da5736cdc69ba089 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Sat, 1 Mar 2014 11:20:04 +0000
Subject: [PATCH] Moved some boilerplate into the BriarActivity superclass.

---
 .../briarproject/android/BriarActivity.java   | 22 ++++++
 .../android/DashboardActivity.java            | 12 +---
 .../android/PasswordActivity.java             |  2 +-
 .../android/contact/ContactListActivity.java  | 19 +-----
 .../android/contact/ConversationActivity.java | 32 ++-------
 .../contact/ReadPrivateMessageActivity.java   | 34 +++-------
 .../contact/WritePrivateMessageActivity.java  | 17 +----
 .../groups/ConfigureGroupActivity.java        | 19 +-----
 .../android/groups/CreateGroupActivity.java   | 67 ++++++++-----------
 .../android/groups/GroupActivity.java         | 26 +------
 .../android/groups/GroupListActivity.java     | 26 +------
 .../android/groups/ManageGroupsActivity.java  | 12 +---
 .../android/groups/ReadGroupPostActivity.java | 34 +++-------
 .../groups/WriteGroupPostActivity.java        | 19 +-----
 .../identity/CreateIdentityActivity.java      | 11 +--
 .../invitation/AddContactActivity.java        | 11 +--
 16 files changed, 95 insertions(+), 268 deletions(-)

diff --git a/briar-android/src/org/briarproject/android/BriarActivity.java b/briar-android/src/org/briarproject/android/BriarActivity.java
index 57e9804f55..904bce5bff 100644
--- a/briar-android/src/org/briarproject/android/BriarActivity.java
+++ b/briar-android/src/org/briarproject/android/BriarActivity.java
@@ -4,13 +4,16 @@ import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
 import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
 import static java.util.logging.Level.INFO;
 
+import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
 
 import org.briarproject.android.BriarService.BriarBinder;
 import org.briarproject.android.BriarService.BriarServiceConnection;
+import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.db.DatabaseConfig;
+import org.briarproject.api.lifecycle.LifecycleManager;
 
 import roboguice.activity.RoboFragmentActivity;
 import android.content.Intent;
@@ -30,6 +33,10 @@ public class BriarActivity extends RoboFragmentActivity {
 	@Inject private DatabaseConfig databaseConfig;
 	private boolean bound = false;
 
+	// Fields that are accessed from background threads must be volatile
+	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
+	@Inject private volatile LifecycleManager lifecycleManager;
+
 	@Override
 	public void onCreate(Bundle state) {
 		super.onCreate(state);
@@ -100,6 +107,21 @@ public class BriarActivity extends RoboFragmentActivity {
 		}.start();
 	}
 
+	protected void runOnDbThread(final Runnable task) {
+		dbUiExecutor.execute(new Runnable() {
+			public void run() {
+				try {
+					lifecycleManager.waitForDatabase();
+					task.run();
+				} catch(InterruptedException e) {
+					if(LOG.isLoggable(INFO))
+						LOG.info("Interrupted while waiting for database");
+					Thread.currentThread().interrupt();
+				}
+			}
+		});
+	}
+
 	protected void finishOnUiThread() {
 		runOnUiThread(new Runnable() {
 			public void run() {
diff --git a/briar-android/src/org/briarproject/android/DashboardActivity.java b/briar-android/src/org/briarproject/android/DashboardActivity.java
index 956254c4f1..5fbdf520a9 100644
--- a/briar-android/src/org/briarproject/android/DashboardActivity.java
+++ b/briar-android/src/org/briarproject/android/DashboardActivity.java
@@ -8,7 +8,6 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -18,11 +17,9 @@ import org.briarproject.android.contact.ContactListActivity;
 import org.briarproject.android.groups.GroupListActivity;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.api.LocalAuthor;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.android.ReferenceManager;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
-import org.briarproject.api.lifecycle.LifecycleManager;
 
 import android.content.Intent;
 import android.content.res.Resources;
@@ -43,11 +40,9 @@ public class DashboardActivity extends BriarActivity {
 			Logger.getLogger(DashboardActivity.class.getName());
 
 	@Inject private ReferenceManager referenceManager;
-	@Inject @DatabaseUiExecutor private Executor dbUiExecutor;
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject private volatile LifecycleManager lifecycleManager;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -191,10 +186,9 @@ public class DashboardActivity extends BriarActivity {
 	}
 
 	private void storeLocalAuthor(final LocalAuthor a) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					db.addLocalAuthor(a);
 					long duration = System.currentTimeMillis() - now;
@@ -208,10 +202,6 @@ public class DashboardActivity extends BriarActivity {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/PasswordActivity.java b/briar-android/src/org/briarproject/android/PasswordActivity.java
index fb0cf2fc01..64ddd1080c 100644
--- a/briar-android/src/org/briarproject/android/PasswordActivity.java
+++ b/briar-android/src/org/briarproject/android/PasswordActivity.java
@@ -40,7 +40,6 @@ import android.widget.TextView.OnEditorActionListener;
 
 public class PasswordActivity extends RoboActivity {
 
-	@Inject private DatabaseConfig databaseConfig;
 	@Inject @CryptoExecutor private Executor cryptoExecutor;
 	private TextView enterPassword = null;
 	private Button continueButton = null;
@@ -48,6 +47,7 @@ public class PasswordActivity extends RoboActivity {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile CryptoComponent crypto;
+	@Inject private volatile DatabaseConfig databaseConfig;
 
 	@Override
 	public void onCreate(Bundle state) {
diff --git a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
index 14cb86f3a9..5250b1c7e4 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
@@ -13,7 +13,6 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
 
 import java.util.Collection;
 import java.util.Map;
-import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -26,7 +25,6 @@ import org.briarproject.android.util.ListLoadingProgressBar;
 import org.briarproject.api.AuthorId;
 import org.briarproject.api.Contact;
 import org.briarproject.api.ContactId;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.db.MessageHeader;
@@ -37,7 +35,6 @@ import org.briarproject.api.event.Event;
 import org.briarproject.api.event.EventListener;
 import org.briarproject.api.event.MessageAddedEvent;
 import org.briarproject.api.event.MessageExpiredEvent;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.transport.ConnectionListener;
 import org.briarproject.api.transport.ConnectionRegistry;
@@ -70,8 +67,6 @@ ConnectionListener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -128,10 +123,9 @@ ConnectionListener {
 
 	private void loadContacts() {
 		clearContacts();
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					Map<ContactId, Long> times = db.getLastConnected();
 					for(Contact c : db.getContacts()) {
@@ -153,10 +147,6 @@ ConnectionListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -257,10 +247,9 @@ ConnectionListener {
 	}
 
 	private void reloadContact(final ContactId c) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					Collection<MessageHeader> headers =
 							db.getInboxMessageHeaders(c);
@@ -273,10 +262,6 @@ ConnectionListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
index dd7ce04bca..a3540fe149 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
@@ -38,7 +38,6 @@ import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.android.util.ListLoadingProgressBar;
 import org.briarproject.api.AuthorId;
 import org.briarproject.api.ContactId;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.crypto.CryptoExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
@@ -51,7 +50,6 @@ import org.briarproject.api.event.Event;
 import org.briarproject.api.event.EventListener;
 import org.briarproject.api.event.MessageAddedEvent;
 import org.briarproject.api.event.MessageExpiredEvent;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.Group;
 import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.messaging.Message;
@@ -95,8 +93,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 	@Inject private volatile MessageFactory messageFactory;
 	private volatile ContactId contactId = null;
 	private volatile GroupId groupId = null;
@@ -202,10 +198,9 @@ implements EventListener, OnClickListener, OnItemClickListener {
 	}
 
 	private void loadHeadersAndGroup() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					Collection<MessageHeader> headers =
 							db.getInboxMessageHeaders(contactId);
@@ -221,10 +216,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -259,10 +250,9 @@ implements EventListener, OnClickListener, OnItemClickListener {
 	}
 
 	private void loadMessageBody(final MessageHeader h) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					byte[] body = db.getMessageBody(h.getId());
 					long duration = System.currentTimeMillis() - now;
@@ -274,10 +264,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -333,10 +319,9 @@ implements EventListener, OnClickListener, OnItemClickListener {
 	}
 
 	private void markMessagesRead(final Collection<MessageId> unread) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					for(MessageId m : unread) db.setReadFlag(m, true);
 					long duration = System.currentTimeMillis() - now;
@@ -345,10 +330,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -408,10 +389,9 @@ implements EventListener, OnClickListener, OnItemClickListener {
 	}
 
 	private void storeMessage(final Message m) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					db.addLocalMessage(m);
 					long duration = System.currentTimeMillis() - now;
@@ -420,10 +400,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java b/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java
index 43db69ad26..c321319a85 100644
--- a/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java
@@ -11,7 +11,6 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
 import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
 import static org.briarproject.api.Author.Status.VERIFIED;
 
-import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -23,11 +22,9 @@ import org.briarproject.android.util.ElasticHorizontalSpace;
 import org.briarproject.android.util.HorizontalBorder;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.api.AuthorId;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.db.NoSuchMessageException;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.messaging.MessageId;
 import org.briarproject.util.StringUtils;
@@ -62,8 +59,6 @@ implements OnClickListener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 	private volatile MessageId messageId = null;
 	private volatile GroupId groupId = null;
 	private volatile long timestamp = -1;
@@ -182,10 +177,9 @@ implements OnClickListener {
 	}
 
 	private void setReadInDatabase(final boolean read) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					db.setReadFlag(messageId, read);
 					long duration = System.currentTimeMillis() - now;
@@ -195,10 +189,6 @@ implements OnClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -215,35 +205,33 @@ implements OnClickListener {
 	}
 
 	private void loadMessageBody() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					byte[] body = db.getMessageBody(messageId);
 					long duration = System.currentTimeMillis() - now;
 					if(LOG.isLoggable(INFO))
 						LOG.info("Loading message took " + duration + " ms");
-					final String text = StringUtils.fromUtf8(body);
-					runOnUiThread(new Runnable() {
-						public void run() {
-							content.setText(text);
-						}
-					});
+					displayMessageBody(StringUtils.fromUtf8(body));
 				} catch(NoSuchMessageException e) {
 					finishOnUiThread();
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
 	}
 
+	private void displayMessageBody(final String body) {
+		runOnUiThread(new Runnable() {
+			public void run() {
+				content.setText(body);
+			}
+		});
+	}
+
 	@Override
 	public void onSaveInstanceState(Bundle state) {
 		super.onSaveInstanceState(state);
diff --git a/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java b/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java
index 1a92f3c99c..9abb58bda8 100644
--- a/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java
@@ -26,13 +26,11 @@ import org.briarproject.android.util.CommonLayoutParams;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.api.AuthorId;
 import org.briarproject.api.LocalAuthor;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.crypto.CryptoExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.db.NoSuchContactException;
 import org.briarproject.api.db.NoSuchSubscriptionException;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.Group;
 import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.messaging.Message;
@@ -66,8 +64,6 @@ implements OnClickListener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 	@Inject private volatile MessageFactory messageFactory;
 	private volatile String contactName = null;
 	private volatile GroupId groupId = null;
@@ -146,10 +142,9 @@ implements OnClickListener {
 	}
 
 	private void loadAuthorAndGroup() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					localAuthor = db.getLocalAuthor(localAuthorId);
 					group = db.getGroup(groupId);
@@ -164,9 +159,6 @@ implements OnClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -212,10 +204,9 @@ implements OnClickListener {
 	}
 
 	private void storeMessage(final Message m) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					db.addLocalMessage(m);
 					long duration = System.currentTimeMillis() - now;
@@ -224,10 +215,6 @@ implements OnClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/groups/ConfigureGroupActivity.java b/briar-android/src/org/briarproject/android/groups/ConfigureGroupActivity.java
index e512112397..cacca2be88 100644
--- a/briar-android/src/org/briarproject/android/groups/ConfigureGroupActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/ConfigureGroupActivity.java
@@ -11,7 +11,6 @@ import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP;
 
 import java.util.Collection;
 import java.util.Collections;
-import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -22,10 +21,8 @@ import org.briarproject.android.contact.SelectContactsDialog;
 import org.briarproject.android.invitation.AddContactActivity;
 import org.briarproject.api.Contact;
 import org.briarproject.api.ContactId;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.Group;
 import org.briarproject.api.messaging.GroupId;
 
@@ -60,8 +57,6 @@ SelectContactsDialog.Listener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 	private volatile Group group = null;
 	private volatile Collection<ContactId> selected = Collections.emptyList();
 
@@ -163,10 +158,9 @@ SelectContactsDialog.Listener {
 	}
 
 	private void loadContacts() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					Collection<Contact> contacts = db.getContacts();
 					long duration = System.currentTimeMillis() - now;
@@ -176,10 +170,6 @@ SelectContactsDialog.Listener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -202,10 +192,9 @@ SelectContactsDialog.Listener {
 	private void updateGroup(final boolean subscribe,
 			final boolean wasSubscribed, final boolean all,
 			final Collection<ContactId> visible) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					if(subscribe) {
 						if(!wasSubscribed) db.addGroup(group);
@@ -220,10 +209,6 @@ SelectContactsDialog.Listener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 				finishOnUiThread();
 			}
diff --git a/briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java b/briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java
index 2432278459..c031f78d51 100644
--- a/briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/CreateGroupActivity.java
@@ -16,7 +16,6 @@ import static org.briarproject.api.messaging.MessagingConstants.MAX_GROUP_NAME_L
 
 import java.util.Collection;
 import java.util.Collections;
-import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -28,10 +27,8 @@ import org.briarproject.android.invitation.AddContactActivity;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.api.Contact;
 import org.briarproject.api.ContactId;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.Group;
 import org.briarproject.api.messaging.GroupFactory;
 import org.briarproject.util.StringUtils;
@@ -71,8 +68,6 @@ SelectContactsDialog.Listener {
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile GroupFactory groupFactory;
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 	private volatile Collection<ContactId> selected = Collections.emptyList();
 
 	@Override
@@ -166,46 +161,42 @@ SelectContactsDialog.Listener {
 			loadContacts();
 		} else if(view == createButton) {
 			if(!validateName()) return;
-			final String name = nameEntry.getText().toString();
-			final boolean all = visibleToAll.isChecked();
-			final Collection<ContactId> visible =
-					Collections.unmodifiableCollection(selected);
-			// Replace the button with a progress bar
 			createButton.setVisibility(GONE);
 			progress.setVisibility(VISIBLE);
-			// Create and store the group in a background thread
-			dbUiExecutor.execute(new Runnable() {
-				public void run() {
-					try {
-						lifecycleManager.waitForDatabase();
-						Group g = groupFactory.createGroup(name);
-						long now = System.currentTimeMillis();
-						db.addGroup(g);
-						if(all) db.setVisibleToAll(g.getId(), true);
-						else db.setVisibility(g.getId(), visible);
-						long duration = System.currentTimeMillis() - now;
-						if(LOG.isLoggable(INFO))
-							LOG.info("Storing group took " + duration + " ms");
-					} catch(DbException e) {
-						if(LOG.isLoggable(WARNING))
-							LOG.log(WARNING, e.toString(), e);
-					} catch(InterruptedException e) {
-						if(LOG.isLoggable(INFO))
-							LOG.info("Interrupted while waiting for database");
-						Thread.currentThread().interrupt();
-					}
-					finishOnUiThread();
-				}
-			});
+			String name = nameEntry.getText().toString();
+			boolean all = visibleToAll.isChecked();
+			Collection<ContactId> visible =
+					Collections.unmodifiableCollection(selected);
+			storeGroup(name, all, visible);
 		}
 	}
 
+	private void storeGroup(final String name, final boolean all,
+			final Collection<ContactId> visible) {
+		runOnDbThread(new Runnable() {
+			public void run() {
+				try {
+					Group g = groupFactory.createGroup(name);
+					long now = System.currentTimeMillis();
+					db.addGroup(g);
+					if(all) db.setVisibleToAll(g.getId(), true);
+					else db.setVisibility(g.getId(), visible);
+					long duration = System.currentTimeMillis() - now;
+					if(LOG.isLoggable(INFO))
+						LOG.info("Storing group took " + duration + " ms");
+				} catch(DbException e) {
+					if(LOG.isLoggable(WARNING))
+						LOG.log(WARNING, e.toString(), e);
+				}
+				finishOnUiThread();
+			}
+		});
+	}
 
 	private void loadContacts() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					Collection<Contact> contacts = db.getContacts();
 					long duration = System.currentTimeMillis() - now;
@@ -215,10 +206,6 @@ SelectContactsDialog.Listener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/groups/GroupActivity.java b/briar-android/src/org/briarproject/android/groups/GroupActivity.java
index 06f475a2bc..c38c7985e9 100644
--- a/briar-android/src/org/briarproject/android/groups/GroupActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/GroupActivity.java
@@ -18,7 +18,6 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -28,7 +27,6 @@ import org.briarproject.android.BriarActivity;
 import org.briarproject.android.util.HorizontalBorder;
 import org.briarproject.android.util.ListLoadingProgressBar;
 import org.briarproject.api.Author;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.db.MessageHeader;
@@ -39,7 +37,6 @@ import org.briarproject.api.event.EventListener;
 import org.briarproject.api.event.MessageAddedEvent;
 import org.briarproject.api.event.MessageExpiredEvent;
 import org.briarproject.api.event.SubscriptionRemovedEvent;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.messaging.MessageId;
 
@@ -71,8 +68,6 @@ OnClickListener, OnItemClickListener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 	private volatile GroupId groupId = null;
 
 	@Override
@@ -137,10 +132,9 @@ OnClickListener, OnItemClickListener {
 	}
 
 	private void loadHeaders() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					Collection<MessageHeader> headers =
 							db.getMessageHeaders(groupId);
@@ -153,10 +147,6 @@ OnClickListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -190,10 +180,9 @@ OnClickListener, OnItemClickListener {
 	}
 
 	private void loadMessageBody(final MessageHeader h) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					byte[] body = db.getMessageBody(h.getId());
 					long duration = System.currentTimeMillis() - now;
@@ -205,10 +194,6 @@ OnClickListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -264,10 +249,9 @@ OnClickListener, OnItemClickListener {
 	}
 
 	private void markMessagesRead(final Collection<MessageId> unread) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					for(MessageId m : unread) db.setReadFlag(m, true);
 					long duration = System.currentTimeMillis() - now;
@@ -276,10 +260,6 @@ OnClickListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/groups/GroupListActivity.java b/briar-android/src/org/briarproject/android/groups/GroupListActivity.java
index 5691b3bc34..55133a9890 100644
--- a/briar-android/src/org/briarproject/android/groups/GroupListActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/GroupListActivity.java
@@ -15,7 +15,6 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
 import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -26,7 +25,6 @@ import org.briarproject.android.util.ElasticHorizontalSpace;
 import org.briarproject.android.util.HorizontalBorder;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.android.util.ListLoadingProgressBar;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.db.MessageHeader;
@@ -38,7 +36,6 @@ import org.briarproject.api.event.MessageExpiredEvent;
 import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
 import org.briarproject.api.event.SubscriptionAddedEvent;
 import org.briarproject.api.event.SubscriptionRemovedEvent;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.Group;
 import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.messaging.GroupStatus;
@@ -73,8 +70,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -154,10 +149,9 @@ implements EventListener, OnClickListener, OnItemClickListener {
 
 	private void loadHeaders() {
 		clearHeaders();
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					int availableCount = 0;
 					long now = System.currentTimeMillis();
 					for(GroupStatus s : db.getAvailableGroups()) {
@@ -181,10 +175,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -296,10 +286,9 @@ implements EventListener, OnClickListener, OnItemClickListener {
 	}
 
 	private void loadHeaders(final Group g) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					Collection<MessageHeader> headers =
 							db.getMessageHeaders(g.getId());
@@ -312,10 +301,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -341,10 +326,9 @@ implements EventListener, OnClickListener, OnItemClickListener {
 	}
 
 	private void loadAvailable() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					int available = 0;
 					long now = System.currentTimeMillis();
 					for(GroupStatus s : db.getAvailableGroups())
@@ -356,10 +340,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java b/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java
index b698a8c591..04acb34f85 100644
--- a/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java
@@ -6,7 +6,6 @@ import static java.util.logging.Level.WARNING;
 import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
 
 import java.util.Collection;
-import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -14,7 +13,6 @@ import javax.inject.Inject;
 import org.briarproject.R;
 import org.briarproject.android.BriarActivity;
 import org.briarproject.android.util.ListLoadingProgressBar;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.event.Event;
@@ -22,7 +20,6 @@ import org.briarproject.api.event.EventListener;
 import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
 import org.briarproject.api.event.SubscriptionAddedEvent;
 import org.briarproject.api.event.SubscriptionRemovedEvent;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.Group;
 import org.briarproject.api.messaging.GroupStatus;
 
@@ -47,8 +44,6 @@ implements EventListener, OnItemClickListener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -79,10 +74,9 @@ implements EventListener, OnItemClickListener {
 	}
 
 	private void loadGroups() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					Collection<GroupStatus> available = db.getAvailableGroups();
 					long duration = System.currentTimeMillis() - now;
@@ -92,10 +86,6 @@ implements EventListener, OnItemClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java b/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java
index c038bdbdfd..1b6332bb89 100644
--- a/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java
@@ -10,7 +10,6 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP;
 import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
 import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
 
-import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -22,11 +21,9 @@ import org.briarproject.android.util.ElasticHorizontalSpace;
 import org.briarproject.android.util.HorizontalBorder;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.api.Author;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.db.NoSuchMessageException;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.messaging.MessageId;
 import org.briarproject.util.StringUtils;
@@ -61,8 +58,6 @@ implements OnClickListener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 	private volatile MessageId messageId = null;
 	private volatile long timestamp = -1;
 
@@ -179,10 +174,9 @@ implements OnClickListener {
 	}
 
 	private void setReadInDatabase(final boolean read) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					db.setReadFlag(messageId, read);
 					long duration = System.currentTimeMillis() - now;
@@ -192,10 +186,6 @@ implements OnClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -212,35 +202,33 @@ implements OnClickListener {
 	}
 
 	private void loadMessageBody() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					byte[] body = db.getMessageBody(messageId);
 					long duration = System.currentTimeMillis() - now;
 					if(LOG.isLoggable(INFO))
 						LOG.info("Loading message took " + duration + " ms");
-					final String text = StringUtils.fromUtf8(body);
-					runOnUiThread(new Runnable() {
-						public void run() {
-							content.setText(text);
-						}
-					});
+					displayMessageBody(StringUtils.fromUtf8(body));
 				} catch(NoSuchMessageException e) {
 					finishOnUiThread();
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
 	}
 
+	private void displayMessageBody(final String body) {
+		runOnUiThread(new Runnable() {
+			public void run() {
+				content.setText(body);
+			}
+		});
+	}
+
 	@Override
 	public void onSaveInstanceState(Bundle state) {
 		super.onSaveInstanceState(state);
diff --git a/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java b/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java
index 2222c9479b..76bc207bc9 100644
--- a/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java
@@ -31,14 +31,12 @@ import org.briarproject.android.util.CommonLayoutParams;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.api.AuthorId;
 import org.briarproject.api.LocalAuthor;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.CryptoExecutor;
 import org.briarproject.api.crypto.KeyParser;
 import org.briarproject.api.crypto.PrivateKey;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.messaging.Group;
 import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.messaging.Message;
@@ -68,6 +66,7 @@ implements OnItemSelectedListener, OnClickListener {
 	private static final Logger LOG =
 			Logger.getLogger(WriteGroupPostActivity.class.getName());
 
+	@Inject @CryptoExecutor private Executor cryptoExecutor;
 	private LocalAuthorSpinnerAdapter adapter = null;
 	private Spinner spinner = null;
 	private ImageButton sendButton = null;
@@ -77,9 +76,6 @@ implements OnItemSelectedListener, OnClickListener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
-	@Inject @CryptoExecutor private volatile Executor cryptoExecutor;
 	@Inject private volatile CryptoComponent crypto;
 	@Inject private volatile MessageFactory messageFactory;
 	private volatile MessageId parentId = null;
@@ -165,10 +161,9 @@ implements OnItemSelectedListener, OnClickListener {
 	}
 
 	private void loadAuthorsAndGroup() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					Collection<LocalAuthor> localAuthors = db.getLocalAuthors();
 					group = db.getGroup(groupId);
@@ -179,9 +174,6 @@ implements OnItemSelectedListener, OnClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
@@ -295,10 +287,9 @@ implements OnItemSelectedListener, OnClickListener {
 	}
 
 	private void storeMessage(final Message m) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					db.addLocalMessage(m);
 					long duration = System.currentTimeMillis() - now;
@@ -307,10 +298,6 @@ implements OnItemSelectedListener, OnClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java b/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java
index 18dee05d79..72a5549beb 100644
--- a/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java
+++ b/briar-android/src/org/briarproject/android/identity/CreateIdentityActivity.java
@@ -24,13 +24,11 @@ import org.briarproject.android.BriarActivity;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.api.AuthorFactory;
 import org.briarproject.api.LocalAuthor;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.CryptoExecutor;
 import org.briarproject.api.crypto.KeyPair;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
-import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.util.StringUtils;
 
 import android.content.Intent;
@@ -61,8 +59,6 @@ implements OnEditorActionListener, OnClickListener {
 	@Inject private volatile CryptoComponent crypto;
 	@Inject private volatile AuthorFactory authorFactory;
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -146,10 +142,9 @@ implements OnEditorActionListener, OnClickListener {
 	}
 
 	private void storeLocalAuthor(final LocalAuthor a) {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					db.addLocalAuthor(a);
 					long duration = System.currentTimeMillis() - now;
@@ -158,10 +153,6 @@ implements OnEditorActionListener, OnClickListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					if(LOG.isLoggable(INFO))
-						LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 				setResultAndFinish(a);
 			}
diff --git a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java
index 7fa673e498..5c778d765b 100644
--- a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java
+++ b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java
@@ -5,7 +5,6 @@ import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
 
 import java.util.Collection;
-import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -14,7 +13,6 @@ import org.briarproject.R;
 import org.briarproject.android.BriarActivity;
 import org.briarproject.api.AuthorId;
 import org.briarproject.api.LocalAuthor;
-import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.android.ReferenceManager;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.db.DatabaseComponent;
@@ -23,7 +21,6 @@ import org.briarproject.api.invitation.InvitationListener;
 import org.briarproject.api.invitation.InvitationState;
 import org.briarproject.api.invitation.InvitationTask;
 import org.briarproject.api.invitation.InvitationTaskFactory;
-import org.briarproject.api.lifecycle.LifecycleManager;
 
 import android.content.Intent;
 import android.os.Bundle;
@@ -54,8 +51,6 @@ implements InvitationListener {
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
-	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	@Inject private volatile LifecycleManager lifecycleManager;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -199,10 +194,9 @@ implements InvitationListener {
 	}
 
 	void loadLocalAuthors() {
-		dbUiExecutor.execute(new Runnable() {
+		runOnDbThread(new Runnable() {
 			public void run() {
 				try {
-					lifecycleManager.waitForDatabase();
 					long now = System.currentTimeMillis();
 					Collection<LocalAuthor> authors = db.getLocalAuthors();
 					long duration = System.currentTimeMillis() - now;
@@ -212,9 +206,6 @@ implements InvitationListener {
 				} catch(DbException e) {
 					if(LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
-				} catch(InterruptedException e) {
-					LOG.info("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
 				}
 			}
 		});
-- 
GitLab