diff --git a/briar-android/src/org/briarproject/android/ActivityModule.java b/briar-android/src/org/briarproject/android/ActivityModule.java
index ff40912c11a418058129e70b78f733a07d05b2b5..21a7d35ef0312f13904c567ca24c88924182231f 100644
--- a/briar-android/src/org/briarproject/android/ActivityModule.java
+++ b/briar-android/src/org/briarproject/android/ActivityModule.java
@@ -20,7 +20,6 @@ import org.briarproject.android.controller.PasswordController;
 import org.briarproject.android.controller.PasswordControllerImpl;
 import org.briarproject.android.controller.SetupController;
 import org.briarproject.android.controller.SetupControllerImpl;
-import org.briarproject.android.controller.TransportStateListener;
 import org.briarproject.android.forum.ForumController;
 import org.briarproject.android.forum.ForumControllerImpl;
 
@@ -52,27 +51,27 @@ public class ActivityModule {
 
 	@ActivityScope
 	@Provides
-	protected SetupController provideSetupController(
+	SetupController provideSetupController(
 			SetupControllerImpl setupControllerImpl) {
 		return setupControllerImpl;
 	}
 
 	@ActivityScope
 	@Provides
-	protected ConfigController provideConfigController(
+	ConfigController provideConfigController(
 			ConfigControllerImpl configControllerImpl) {
 		return configControllerImpl;
 	}
 
 	@ActivityScope
 	@Provides
-	protected SharedPreferences provideSharedPreferences(Activity activity) {
+	SharedPreferences provideSharedPreferences(Activity activity) {
 		return activity.getSharedPreferences("db", Context.MODE_PRIVATE);
 	}
 
 	@ActivityScope
 	@Provides
-	protected PasswordController providePasswordController(
+	PasswordController providePasswordController(
 			PasswordControllerImpl passwordControllerImpl) {
 		return passwordControllerImpl;
 	}
@@ -87,8 +86,7 @@ public class ActivityModule {
 
 	@ActivityScope
 	@Provides
-	protected DbController provideDBController(
-			DbControllerImpl dbController) {
+	DbController provideDBController(DbControllerImpl dbController) {
 		return dbController;
 	}
 
@@ -109,26 +107,21 @@ public class ActivityModule {
 
 	@ActivityScope
 	@Provides
-	protected FeedController provideFeedController(
-			FeedControllerImpl feedController) {
+	FeedController provideFeedController(FeedControllerImpl feedController) {
 		return feedController;
 	}
 
 	@ActivityScope
 	@Provides
-	protected NavDrawerController provideNavDrawerController(
-			NavDrawerControllerImpl navDrawerControllerImpl) {
-		activity.addLifecycleController(navDrawerControllerImpl);
-		if (activity instanceof TransportStateListener) {
-			navDrawerControllerImpl.setTransportListener(
-					(TransportStateListener) activity);
-		}
-		return navDrawerControllerImpl;
+	NavDrawerController provideNavDrawerController(
+			NavDrawerControllerImpl navDrawerController) {
+		activity.addLifecycleController(navDrawerController);
+		return navDrawerController;
 	}
 
 	@ActivityScope
 	@Provides
-	protected BriarServiceConnection provideBriarServiceConnection() {
+	BriarServiceConnection provideBriarServiceConnection() {
 		return new BriarServiceConnection();
 	}
 
diff --git a/briar-android/src/org/briarproject/android/BaseActivity.java b/briar-android/src/org/briarproject/android/BaseActivity.java
index 92f31ef7e52f5d526e5d534fd72e341648329506..5ee0bbee89713f98e4e8d9bff30c9d93760db844 100644
--- a/briar-android/src/org/briarproject/android/BaseActivity.java
+++ b/briar-android/src/org/briarproject/android/BaseActivity.java
@@ -2,7 +2,6 @@ package org.briarproject.android;
 
 import android.os.Bundle;
 import android.os.IBinder;
-import android.support.annotation.UiThread;
 import android.support.v7.app.AppCompatActivity;
 import android.view.View;
 import android.view.inputmethod.InputMethodManager;
@@ -18,7 +17,7 @@ import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT;
 import static org.briarproject.android.TestingConstants.PREVENT_SCREENSHOTS;
 
 public abstract class BaseActivity extends AppCompatActivity
-		implements DestroyableActivity {
+		implements DestroyableContext {
 
 	protected ActivityComponent activityComponent;
 
@@ -49,7 +48,7 @@ public abstract class BaseActivity extends AppCompatActivity
 		injectActivity(activityComponent);
 
 		for (ActivityLifecycleController alc : lifecycleControllers) {
-			alc.onActivityCreate();
+			alc.onActivityCreate(this);
 		}
 	}
 
@@ -87,9 +86,14 @@ public abstract class BaseActivity extends AppCompatActivity
 		}
 	}
 
-	@UiThread
-	public boolean hasBeenDestroyed() {
-		return destroyed;
+	@Override
+	public void runOnUiThreadUnlessDestroyed(final Runnable r) {
+		runOnUiThread(new Runnable() {
+			@Override
+			public void run() {
+				if (!destroyed && !isFinishing()) r.run();
+			}
+		});
 	}
 
 	public void showSoftKeyboardForced(View view) {
diff --git a/briar-android/src/org/briarproject/android/BriarActivity.java b/briar-android/src/org/briarproject/android/BriarActivity.java
index d13dda3826ef2670ea7c6234eb292d2af17c48ed..49dc574a858a2590b120bba32c74ae28a6291294 100644
--- a/briar-android/src/org/briarproject/android/BriarActivity.java
+++ b/briar-android/src/org/briarproject/android/BriarActivity.java
@@ -94,7 +94,7 @@ public abstract class BriarActivity extends BaseActivity {
 
 	@Deprecated
 	protected void finishOnUiThread() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				finish();
diff --git a/briar-android/src/org/briarproject/android/BriarFragmentActivity.java b/briar-android/src/org/briarproject/android/BriarFragmentActivity.java
index 513ace7b560c5b038f7839e1240fcf2ed690a3ca..946ebbd3569b672e1df1a331f584bbeada7f0407 100644
--- a/briar-android/src/org/briarproject/android/BriarFragmentActivity.java
+++ b/briar-android/src/org/briarproject/android/BriarFragmentActivity.java
@@ -1,7 +1,6 @@
 package org.briarproject.android;
 
 import android.support.annotation.AnimRes;
-import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentTransaction;
 import android.support.v7.app.ActionBar;
 import android.support.v7.app.AlertDialog;
@@ -12,6 +11,8 @@ import org.briarproject.android.contact.ContactListFragment;
 import org.briarproject.android.forum.ForumListFragment;
 import org.briarproject.android.fragment.BaseFragment;
 
+import static android.support.v4.app.FragmentManager.POP_BACK_STACK_INCLUSIVE;
+
 /**
  * This class should be extended by classes that wish to utilise fragments in
  * Briar, it encapsulates all fragment related code.
@@ -33,11 +34,8 @@ public abstract class BriarFragmentActivity extends BriarActivity {
 	}
 
 	void clearBackStack() {
-		getSupportFragmentManager()
-				.popBackStackImmediate(
-						null,
-						FragmentManager.POP_BACK_STACK_INCLUSIVE
-				);
+		getSupportFragmentManager().popBackStackImmediate(null,
+				POP_BACK_STACK_INCLUSIVE);
 	}
 
 	@Override
diff --git a/briar-android/src/org/briarproject/android/DestroyableActivity.java b/briar-android/src/org/briarproject/android/DestroyableActivity.java
deleted file mode 100644
index 94622406de1415117f2cbb3e1776e8d56bc759e4..0000000000000000000000000000000000000000
--- a/briar-android/src/org/briarproject/android/DestroyableActivity.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.briarproject.android;
-
-import android.support.annotation.UiThread;
-
-public interface DestroyableActivity {
-
-	void runOnUiThread(Runnable runnable);
-
-	@UiThread
-	boolean hasBeenDestroyed();
-
-}
diff --git a/briar-android/src/org/briarproject/android/DestroyableContext.java b/briar-android/src/org/briarproject/android/DestroyableContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..75faa0d104267707287daf8644f6a966b98ba0de
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/DestroyableContext.java
@@ -0,0 +1,6 @@
+package org.briarproject.android;
+
+public interface DestroyableContext {
+
+	void runOnUiThreadUnlessDestroyed(Runnable runnable);
+}
diff --git a/briar-android/src/org/briarproject/android/NavDrawerActivity.java b/briar-android/src/org/briarproject/android/NavDrawerActivity.java
index a7af5d0d062edb19ce994264f51f33208504bf54..62af704f57d51f06484c9b640b46b63b089e87ea 100644
--- a/briar-android/src/org/briarproject/android/NavDrawerActivity.java
+++ b/briar-android/src/org/briarproject/android/NavDrawerActivity.java
@@ -27,7 +27,7 @@ import org.briarproject.android.controller.NavDrawerController;
 import org.briarproject.android.controller.TransportStateListener;
 import org.briarproject.android.controller.handler.UiResultHandler;
 import org.briarproject.android.forum.ForumListFragment;
-import org.briarproject.android.fragment.BaseFragment;
+import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
 import org.briarproject.api.TransportId;
 import org.briarproject.api.identity.LocalAuthor;
 
@@ -43,7 +43,7 @@ import static android.support.v4.widget.DrawerLayout.LOCK_MODE_UNLOCKED;
 import static android.view.View.INVISIBLE;
 
 public class NavDrawerActivity extends BriarFragmentActivity implements
-		BaseFragment.BaseFragmentListener, TransportStateListener,
+		BaseFragmentListener, TransportStateListener,
 		OnNavigationItemSelectedListener {
 
 	static final String INTENT_CONTACTS = "intent_contacts";
@@ -58,9 +58,8 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
 	private ActionBarDrawerToggle drawerToggle;
 
 	@Inject
-	protected NavDrawerController controller;
+	NavDrawerController controller;
 
-	private Toolbar toolbar;
 	private DrawerLayout drawerLayout;
 	private TextView progressTitle;
 	private ViewGroup progressViewGroup;
@@ -78,11 +77,9 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
 //		clearBackStack();
 		if (intent.getBooleanExtra(INTENT_FORUMS, false)) {
 			startFragment(ForumListFragment.newInstance());
-		}
-		else if (intent.getBooleanExtra(INTENT_CONTACTS, false)) {
+		} else if (intent.getBooleanExtra(INTENT_CONTACTS, false)) {
 			startFragment(ContactListFragment.newInstance());
-		}
-		else if (intent.getBooleanExtra(INTENT_BLOGS, false)) {
+		} else if (intent.getBooleanExtra(INTENT_BLOGS, false)) {
 			startFragment(FeedFragment.newInstance());
 		}
 		setIntent(null);
@@ -100,7 +97,7 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
 		exitIfStartupFailed(getIntent());
 		setContentView(R.layout.activity_nav_drawer);
 
-		toolbar = (Toolbar) findViewById(R.id.toolbar);
+		Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
 		drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
 		NavigationView navigation =
 				(NavigationView) findViewById(R.id.navigation);
@@ -318,7 +315,7 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
 	}
 
 	private void setTransport(final TransportId id, final boolean enabled) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				if (transports == null || transportsAdapter == null) return;
diff --git a/briar-android/src/org/briarproject/android/blogs/BaseController.java b/briar-android/src/org/briarproject/android/blogs/BaseController.java
index bfd1a0b13ae9bbeac959058b58c67e1173b0269d..a2f4b7d26a852a908dd715df91bf808227e726de 100644
--- a/briar-android/src/org/briarproject/android/blogs/BaseController.java
+++ b/briar-android/src/org/briarproject/android/blogs/BaseController.java
@@ -3,6 +3,7 @@ package org.briarproject.android.blogs;
 import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 
+import org.briarproject.android.DestroyableContext;
 import org.briarproject.android.controller.handler.ResultExceptionHandler;
 import org.briarproject.api.blogs.BlogPostHeader;
 import org.briarproject.api.db.DbException;
@@ -33,9 +34,13 @@ interface BaseController {
 
 	void setOnBlogPostAddedListener(OnBlogPostAddedListener listener);
 
-	interface OnBlogPostAddedListener {
+	interface OnBlogPostAddedListener extends DestroyableContext {
+
 		@UiThread
 		void onBlogPostAdded(BlogPostHeader header, boolean local);
+
+		@UiThread
+		void onBlogRemoved();
 	}
 
 }
diff --git a/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java b/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java
index 3c4f1bc21bbee32c2be22b73ae56f772acb96c5a..f624023bd320b7d36fecd9fab90018c2a721d7b4 100644
--- a/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java
@@ -1,6 +1,5 @@
 package org.briarproject.android.blogs;
 
-import android.app.Activity;
 import android.support.annotation.CallSuper;
 import android.support.annotation.Nullable;
 
@@ -39,16 +38,14 @@ abstract class BaseControllerImpl extends DbControllerImpl
 			Logger.getLogger(BaseControllerImpl.class.getName());
 
 	@Inject
-	protected Activity activity;
+	EventBus eventBus;
 	@Inject
-	protected EventBus eventBus;
+	AndroidNotificationManager notificationManager;
 	@Inject
-	protected AndroidNotificationManager notificationManager;
-	@Inject
-	protected IdentityManager identityManager;
+	IdentityManager identityManager;
 
 	@Inject
-	protected volatile BlogManager blogManager;
+	volatile BlogManager blogManager;
 
 	private final Map<MessageId, String> bodyCache = new ConcurrentHashMap<>();
 	private final Map<MessageId, BlogPostHeader> headerCache =
@@ -75,12 +72,12 @@ abstract class BaseControllerImpl extends DbControllerImpl
 	@CallSuper
 	public void eventOccurred(Event e) {
 		if (e instanceof BlogPostAddedEvent) {
-			final BlogPostAddedEvent m = (BlogPostAddedEvent) e;
+			final BlogPostAddedEvent b = (BlogPostAddedEvent) e;
 			LOG.info("New blog post added");
-			activity.runOnUiThread(new Runnable() {
+			listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 				@Override
 				public void run() {
-					listener.onBlogPostAdded(m.getHeader(), m.isLocal());
+					listener.onBlogPostAdded(b.getHeader(), b.isLocal());
 				}
 			});
 		}
@@ -110,8 +107,7 @@ abstract class BaseControllerImpl extends DbControllerImpl
 		});
 	}
 
-	protected Collection<BlogPostItem> loadItems(GroupId groupId)
-			throws DbException {
+	Collection<BlogPostItem> loadItems(GroupId groupId) throws DbException {
 		long now = System.currentTimeMillis();
 		Collection<BlogPostHeader> headers =
 				blogManager.getPostHeaders(groupId);
diff --git a/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java b/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java
index 85c5dff3359c65e651c4e7e00ed41e8de818610f..04ee0a747db6aac0901c0e381ff2d823f15a797c 100644
--- a/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java
@@ -22,7 +22,7 @@ import static org.briarproject.android.util.AndroidUtils.MIN_RESOLUTION;
 
 abstract class BasePostFragment extends BaseFragment {
 
-	private final Logger LOG =
+	private static final Logger LOG =
 			Logger.getLogger(BasePostFragment.class.getName());
 
 	private View view;
diff --git a/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java
index e27c1470f5fe09d2e401b53189a5a8da3dfea3c9..424fa5d45d725570a20439da8b1d7cf16ccca5be 100644
--- a/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java
@@ -90,6 +90,7 @@ abstract class BasePostPagerFragment extends BaseFragment
 
 	abstract void loadBlogPost(BlogPostHeader header);
 
+	@UiThread
 	protected void onBlogPostsLoaded(MessageId select,
 			Collection<BlogPostItem> posts) {
 
@@ -98,6 +99,7 @@ abstract class BasePostPagerFragment extends BaseFragment
 		selectPost(select);
 	}
 
+	@UiThread
 	protected void onBlogPostsLoadedException(DbException exception) {
 		// TODO: Decide how to handle errors in the UI
 		finish();
@@ -174,4 +176,8 @@ abstract class BasePostPagerFragment extends BaseFragment
 		}
 	}
 
+	@Override
+	public void onBlogRemoved() {
+		finish();
+	}
 }
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java b/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java
index ebc976468917ecb47d62e1131b3ed61b5b5e162d..6dd1c6ab54d0a805585356bee90e866e0b2c4246 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java
@@ -1,5 +1,7 @@
 package org.briarproject.android.blogs;
 
+import android.app.Activity;
+
 import org.briarproject.android.controller.ActivityLifecycleController;
 import org.briarproject.android.controller.handler.ResultExceptionHandler;
 import org.briarproject.api.blogs.Blog;
@@ -32,7 +34,7 @@ public class BlogControllerImpl extends BaseControllerImpl
 	}
 
 	@Override
-	public void onActivityCreate() {
+	public void onActivityCreate(Activity activity) {
 	}
 
 	@Override
@@ -69,11 +71,10 @@ public class BlogControllerImpl extends BaseControllerImpl
 			GroupRemovedEvent s = (GroupRemovedEvent) e;
 			if (s.getGroup().getId().equals(groupId)) {
 				LOG.info("Blog removed");
-				activity.runOnUiThread(new Runnable() {
+				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 					@Override
 					public void run() {
-						// TODO: Not the controller's job, add a listener method
-						activity.finish();
+						listener.onBlogRemoved();
 					}
 				});
 			}
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java
index 963b7175ea740ac116deec87081c5d18b5054499..25d266c312050286eeeb69289005f19930edb29e 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java
@@ -160,8 +160,8 @@ public class BlogFragment extends BaseFragment implements
 				getActivity().onBackPressed();
 				return true;
 			case R.id.action_write_blog_post:
-				Intent i =
-						new Intent(getActivity(), WriteBlogPostActivity.class);
+				Intent i = new Intent(getActivity(),
+						WriteBlogPostActivity.class);
 				i.putExtra(GROUP_ID, groupId.getBytes());
 				i.putExtra(BLOG_NAME, blogName);
 				startActivityForResult(i, REQUEST_WRITE_POST,
@@ -224,7 +224,7 @@ public class BlogFragment extends BaseFragment implements
 					@Override
 					public void onExceptionUi(DbException exception) {
 						// TODO: Decide how to handle errors in the UI
-						getActivity().finish();
+						finish();
 					}
 				}
 		);
@@ -338,7 +338,7 @@ public class BlogFragment extends BaseFragment implements
 						Toast.makeText(getActivity(),
 								R.string.blogs_blog_removed, LENGTH_SHORT)
 								.show();
-						getActivity().supportFinishAfterTransition();
+						finish();
 					}
 
 					@Override
@@ -349,4 +349,8 @@ public class BlogFragment extends BaseFragment implements
 				});
 	}
 
+	@Override
+	public void onBlogRemoved() {
+		finish();
+	}
 }
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java
index 560e62e38bacf01221f4addc89bff3eb101ab8d9..3db8c4d084baf1c5766165191ea6d28aeeebbc2d 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java
@@ -41,6 +41,7 @@ public class BlogPostPagerFragment extends BasePostPagerFragment {
 	}
 
 
+	@Override
 	void loadBlogPosts(final MessageId select) {
 		blogController.loadBlogPosts(
 				new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
@@ -57,6 +58,7 @@ public class BlogPostPagerFragment extends BasePostPagerFragment {
 				});
 	}
 
+	@Override
 	void loadBlogPost(BlogPostHeader header) {
 		blogController.loadBlogPost(header,
 				new UiResultExceptionHandler<BlogPostItem, DbException>(
@@ -73,5 +75,4 @@ public class BlogPostPagerFragment extends BasePostPagerFragment {
 					}
 				});
 	}
-
 }
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
index a8a8cea9d7e71bfb566133494d97a73240deb3e7..d07a800d59a6bbe61b5de4b0e453e68326b2ece9 100644
--- a/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
@@ -231,4 +231,9 @@ public class FeedFragment extends BaseFragment implements
 		}
 		s.show();
 	}
+
+	@Override
+	public void onBlogRemoved() {
+		finish();
+	}
 }
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java
index 5f5c351dc1a465dcf880caa26cf22250b48b74f1..b37d99eefe7de372dc663bb957616a314ba0e860 100644
--- a/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java
@@ -74,5 +74,4 @@ public class FeedPostPagerFragment extends BasePostPagerFragment {
 					}
 				});
 	}
-
 }
diff --git a/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java b/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java
index d5d799692e2f2ae9aafec0292a0c47aef90bcdf6..e3d50dfeefa8d288cc2e67477f04937784d6732a 100644
--- a/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java
@@ -65,12 +65,7 @@ public class ReblogFragment extends BaseFragment implements TextInputListener {
 	@Override
 	public void onAttach(Context context) {
 		super.onAttach(context);
-		try {
-			listener = (BaseFragmentListener) context;
-		} catch (ClassCastException e) {
-			throw new ClassCastException(
-					"Using class must implement BaseFragmentListener");
-		}
+		listener = (BaseFragmentListener) context;
 	}
 
 	@Override
@@ -93,12 +88,6 @@ public class ReblogFragment extends BaseFragment implements TextInputListener {
 		return v;
 	}
 
-	@Override
-	public void onActivityCreated(@Nullable Bundle savedInstanceState) {
-		super.onActivityCreated(savedInstanceState);
-		listener.getActivityComponent().inject(this);
-	}
-
 	@Override
 	public void onStart() {
 		super.onStart();
diff --git a/briar-android/src/org/briarproject/android/blogs/RssFeedImportActivity.java b/briar-android/src/org/briarproject/android/blogs/RssFeedImportActivity.java
index f16663a1c447941aeb7631eb64e74b870dd40a13..2150b31badd6b1c2bc064320addc625123995740 100644
--- a/briar-android/src/org/briarproject/android/blogs/RssFeedImportActivity.java
+++ b/briar-android/src/org/briarproject/android/blogs/RssFeedImportActivity.java
@@ -42,10 +42,11 @@ public class RssFeedImportActivity extends BriarActivity {
 
 	@Inject
 	@IoExecutor
-	protected Executor ioExecutor;
+	Executor ioExecutor;
 
 	// Fields that are accessed from background threads must be volatile
 	private volatile GroupId groupId = null;
+
 	@Inject
 	@SuppressWarnings("WeakerAccess")
 	volatile FeedManager feedManager;
@@ -139,7 +140,7 @@ public class RssFeedImportActivity extends BriarActivity {
 	}
 
 	private void feedImported() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				supportFinishAfterTransition();
@@ -148,11 +149,9 @@ public class RssFeedImportActivity extends BriarActivity {
 	}
 
 	private void importFailed() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
-				if (RssFeedImportActivity.this.hasBeenDestroyed()) return;
-
 				// hide progress bar, show publish button
 				progressBar.setVisibility(GONE);
 				importButton.setVisibility(VISIBLE);
diff --git a/briar-android/src/org/briarproject/android/blogs/RssFeedManageActivity.java b/briar-android/src/org/briarproject/android/blogs/RssFeedManageActivity.java
index 60230717bbc2263001c8a505b523ea352206be3b..2fe3ad30ccf90ac3496ef0d5989cbd4b6856e45d 100644
--- a/briar-android/src/org/briarproject/android/blogs/RssFeedManageActivity.java
+++ b/briar-android/src/org/briarproject/android/blogs/RssFeedManageActivity.java
@@ -40,6 +40,7 @@ public class RssFeedManageActivity extends BriarActivity
 
 	// Fields that are accessed from background threads must be volatile
 	private volatile GroupId groupId = null;
+
 	@Inject
 	@SuppressWarnings("WeakerAccess")
 	volatile FeedManager feedManager;
@@ -135,7 +136,7 @@ public class RssFeedManageActivity extends BriarActivity
 	}
 
 	private void addFeeds(final List<Feed> feeds) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				if (feeds.size() == 0) list.showData();
@@ -145,7 +146,7 @@ public class RssFeedManageActivity extends BriarActivity
 	}
 
 	private void onFeedDeleted(final Feed feed) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				adapter.remove(feed);
@@ -154,7 +155,7 @@ public class RssFeedManageActivity extends BriarActivity
 	}
 
 	private void onDeleteError() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				Snackbar.make(list,
diff --git a/briar-android/src/org/briarproject/android/blogs/WriteBlogPostActivity.java b/briar-android/src/org/briarproject/android/blogs/WriteBlogPostActivity.java
index d657fe913b96e7b5467a409161b2afe5e0a20797..70d326ca42266b50da015e30191740ad786e0a2c 100644
--- a/briar-android/src/org/briarproject/android/blogs/WriteBlogPostActivity.java
+++ b/briar-android/src/org/briarproject/android/blogs/WriteBlogPostActivity.java
@@ -44,7 +44,7 @@ public class WriteBlogPostActivity extends BriarActivity
 			Logger.getLogger(WriteBlogPostActivity.class.getName());
 
 	@Inject
-	protected AndroidNotificationManager notificationManager;
+	AndroidNotificationManager notificationManager;
 
 	private TextInputView input;
 	private ProgressBar progressBar;
@@ -52,7 +52,7 @@ public class WriteBlogPostActivity extends BriarActivity
 	// Fields that are accessed from background threads must be volatile
 	private volatile GroupId groupId;
 	@Inject
-	protected volatile IdentityManager identityManager;
+	volatile IdentityManager identityManager;
 	@Inject
 	volatile BlogPostFactory blogPostFactory;
 	@Inject
@@ -168,7 +168,7 @@ public class WriteBlogPostActivity extends BriarActivity
 	}
 
 	private void postPublished() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				setResult(RESULT_OK);
@@ -178,7 +178,7 @@ public class WriteBlogPostActivity extends BriarActivity
 	}
 
 	private void postFailedToPublish() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				// hide progress bar, show publish button
diff --git a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java
index 22f77a841dc18a44aadf1c5772718188d4159b95..c4536bd9cbaebc97418c69c6cbab1bcf99cec082 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java
@@ -63,33 +63,29 @@ import static org.briarproject.android.BriarActivity.GROUP_ID;
 
 public class ContactListFragment extends BaseFragment implements EventListener {
 
-	public final static String TAG = "ContactListFragment";
-
-	private static final Logger LOG =
-			Logger.getLogger(ContactListFragment.class.getName());
+	public static final String TAG = ContactListFragment.class.getName();
+	private static final Logger LOG = Logger.getLogger(TAG);
 
 	@Inject
 	ConnectionRegistry connectionRegistry;
 	@Inject
-	protected EventBus eventBus;
+	EventBus eventBus;
 	@Inject
-	protected AndroidNotificationManager notificationManager;
+	AndroidNotificationManager notificationManager;
 
-	private ContactListAdapter adapter = null;
-	private BriarRecyclerView list = null;
+	private ContactListAdapter adapter;
+	private BriarRecyclerView list;
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject
-	protected volatile ContactManager contactManager;
+	volatile ContactManager contactManager;
 	@Inject
-	protected volatile IdentityManager identityManager;
+	volatile IdentityManager identityManager;
 	@Inject
-	protected volatile ConversationManager conversationManager;
+	volatile ConversationManager conversationManager;
 
 	public static ContactListFragment newInstance() {
-
 		Bundle args = new Bundle();
-
 		ContactListFragment fragment = new ContactListFragment();
 		fragment.setArguments(args);
 		return fragment;
@@ -230,7 +226,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 	}
 
 	private void displayContacts(final List<ContactListItem> contacts) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				if (contacts.size() == 0) list.showData();
@@ -284,7 +280,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 	}
 
 	private void updateItem(final ContactId c, final ConversationItem m) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				int position = adapter.findItemPosition(c);
@@ -298,7 +294,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 	}
 
 	private void updateItem(final GroupId g, final ConversationItem m) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				int position = adapter.findItemPosition(g);
@@ -312,7 +308,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 	}
 
 	private void removeItem(final ContactId c) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				int position = adapter.findItemPosition(c);
@@ -323,7 +319,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 	}
 
 	private void setConnected(final ContactId c, final boolean connected) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				int position = adapter.findItemPosition(c);
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
index 75c0b88c8fc38fda8a0b4bda51de840049608bf8..1d563ad0ce1679a7d218e911d083d3d270eb95d4 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
@@ -130,21 +130,21 @@ public class ConversationActivity extends BriarActivity
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject
-	protected volatile ContactManager contactManager;
+	volatile ContactManager contactManager;
 	@Inject
-	protected volatile MessagingManager messagingManager;
+	volatile MessagingManager messagingManager;
 	@Inject
-	protected volatile EventBus eventBus;
+	volatile EventBus eventBus;
 	@Inject
-	protected volatile SettingsManager settingsManager;
+	volatile SettingsManager settingsManager;
 	@Inject
 	volatile PrivateMessageFactory privateMessageFactory;
 	@Inject
-	protected volatile IntroductionManager introductionManager;
+	volatile IntroductionManager introductionManager;
 	@Inject
-	protected volatile ForumSharingManager forumSharingManager;
+	volatile ForumSharingManager forumSharingManager;
 	@Inject
-	protected volatile BlogSharingManager blogSharingManager;
+	volatile BlogSharingManager blogSharingManager;
 
 	private volatile GroupId groupId = null;
 	private volatile ContactId contactId = null;
@@ -309,7 +309,7 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void displayContactDetails() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				toolbarAvatar.setImageDrawable(
@@ -374,7 +374,7 @@ public class ConversationActivity extends BriarActivity
 	private void displayMessages(final Collection<PrivateMessageHeader> headers,
 			final Collection<IntroductionMessage> introductions,
 			final Collection<InvitationMessage> invitations) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				textInputView.setSendButtonEnabled(true);
@@ -446,7 +446,7 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void displayMessageBody(final MessageId m, final byte[] body) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				bodyCache.put(m, body);
@@ -466,7 +466,7 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void addConversationItem(final ConversationItem item) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				adapter.add(item);
@@ -599,7 +599,7 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void markMessageReadIfNew(final BaseMessageHeader h) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				ConversationItem item = adapter.getLastItem();
@@ -635,7 +635,7 @@ public class ConversationActivity extends BriarActivity
 
 	private void markMessages(final Collection<MessageId> messageIds,
 			final boolean sent, final boolean seen) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				Set<MessageId> messages = new HashSet<>(messageIds);
@@ -747,7 +747,7 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void finishAfterContactRemoved() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				String deleted = getString(R.string.contact_deleted_toast);
@@ -781,7 +781,7 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void enableIntroductionAction(final MenuItem item) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				item.setEnabled(true);
@@ -790,7 +790,7 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void showIntroductionOnboarding() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				// find view of overflow icon
@@ -877,7 +877,7 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void introductionResponseError() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				Toast.makeText(ConversationActivity.this,
diff --git a/briar-android/src/org/briarproject/android/controller/ActivityLifecycleController.java b/briar-android/src/org/briarproject/android/controller/ActivityLifecycleController.java
index 68b15592ce12a740f3ffbd4c357501269136d57e..303f9b89b40e36fd8a90f0e3dfc06092201c47c2 100644
--- a/briar-android/src/org/briarproject/android/controller/ActivityLifecycleController.java
+++ b/briar-android/src/org/briarproject/android/controller/ActivityLifecycleController.java
@@ -1,7 +1,10 @@
 package org.briarproject.android.controller;
 
+import android.app.Activity;
+
 public interface ActivityLifecycleController {
-	void onActivityCreate();
+
+	void onActivityCreate(Activity activity);
 
 	void onActivityResume();
 
diff --git a/briar-android/src/org/briarproject/android/controller/BriarControllerImpl.java b/briar-android/src/org/briarproject/android/controller/BriarControllerImpl.java
index 7dd180a448b0b9fbc3b31204e44ad38f918c1337..459730ebd2b616224156ace7baefe430060b286a 100644
--- a/briar-android/src/org/briarproject/android/controller/BriarControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/controller/BriarControllerImpl.java
@@ -20,11 +20,11 @@ public class BriarControllerImpl implements BriarController {
 			Logger.getLogger(BriarControllerImpl.class.getName());
 
 	@Inject
-	protected BriarServiceConnection serviceConnection;
+	BriarServiceConnection serviceConnection;
 	@Inject
-	protected DatabaseConfig databaseConfig;
+	DatabaseConfig databaseConfig;
 	@Inject
-	protected Activity activity;
+	Activity activity;
 
 	private boolean bound = false;
 
@@ -35,7 +35,7 @@ public class BriarControllerImpl implements BriarController {
 
 	@Override
 	@CallSuper
-	public void onActivityCreate() {
+	public void onActivityCreate(Activity activity) {
 		if (databaseConfig.getEncryptionKey() != null) startAndBindService();
 	}
 
@@ -90,7 +90,7 @@ public class BriarControllerImpl implements BriarController {
 		}.start();
 	}
 
-	protected void unbindService() {
+	private void unbindService() {
 		if (bound) activity.unbindService(serviceConnection);
 	}
 
diff --git a/briar-android/src/org/briarproject/android/controller/NavDrawerController.java b/briar-android/src/org/briarproject/android/controller/NavDrawerController.java
index 8cd8aa86067f3d76565bdc06af7af767054d7ff9..8d25d45b30bb36b5d938fc34aafb6dced50c2196 100644
--- a/briar-android/src/org/briarproject/android/controller/NavDrawerController.java
+++ b/briar-android/src/org/briarproject/android/controller/NavDrawerController.java
@@ -6,8 +6,6 @@ import org.briarproject.api.identity.LocalAuthor;
 
 public interface NavDrawerController extends ActivityLifecycleController {
 
-	void setTransportListener(TransportStateListener transportListener);
-
 	boolean isTransportRunning(TransportId transportId);
 
 	void storeLocalAuthor(LocalAuthor author,
diff --git a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImpl.java b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImpl.java
index 23a680bd39ffdb5c968dc1b8041683e0cdd825cd..3cfa06d7720df6a95c74217cab5b6528dd61dd18 100644
--- a/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/controller/NavDrawerControllerImpl.java
@@ -30,19 +30,17 @@ public class NavDrawerControllerImpl extends DbControllerImpl
 			Logger.getLogger(NavDrawerControllerImpl.class.getName());
 
 	@Inject
-	protected ReferenceManager referenceManager;
+	ReferenceManager referenceManager;
 	@Inject
-	protected PluginManager pluginManager;
+	PluginManager pluginManager;
 	@Inject
-	protected EventBus eventBus;
-	@Inject
-	protected Activity activity;
+	EventBus eventBus;
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject
 	protected volatile IdentityManager identityManager;
 
-	private TransportStateListener transportStateListener;
+	private TransportStateListener listener;
 
 	@Inject
 	public NavDrawerControllerImpl() {
@@ -50,8 +48,8 @@ public class NavDrawerControllerImpl extends DbControllerImpl
 	}
 
 	@Override
-	public void onActivityCreate() {
-
+	public void onActivityCreate(Activity activity) {
+		listener = (TransportStateListener) activity;
 	}
 
 	@Override
@@ -88,21 +86,14 @@ public class NavDrawerControllerImpl extends DbControllerImpl
 
 	private void transportStateUpdate(final TransportId id,
 			final boolean enabled) {
-		activity.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
-				if (transportStateListener != null) {
-					transportStateListener.stateUpdate(id, enabled);
-				}
+				listener.stateUpdate(id, enabled);
 			}
 		});
 	}
 
-	@Override
-	public void setTransportListener(TransportStateListener transportListener) {
-		this.transportStateListener = transportListener;
-	}
-
 	@Override
 	public boolean isTransportRunning(TransportId transportId) {
 		Plugin plugin = pluginManager.getPlugin(transportId);
diff --git a/briar-android/src/org/briarproject/android/controller/TransportStateListener.java b/briar-android/src/org/briarproject/android/controller/TransportStateListener.java
index 7f472b601768a4a93c413a3a584f751c7a63c7cb..3bb1c0a883e31cc25facdd157de8d44752b4a7b5 100644
--- a/briar-android/src/org/briarproject/android/controller/TransportStateListener.java
+++ b/briar-android/src/org/briarproject/android/controller/TransportStateListener.java
@@ -1,8 +1,9 @@
 package org.briarproject.android.controller;
 
+import org.briarproject.android.DestroyableContext;
 import org.briarproject.api.TransportId;
 
-public interface TransportStateListener {
+public interface TransportStateListener extends DestroyableContext {
 
 	void stateUpdate(TransportId id, boolean enabled);
 }
diff --git a/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java b/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java
index 04ea2ebad2e08ac7fc982767325a1a75542dc555..b2d01d4f74b997d072cf986ebe14ffc79bdf08a8 100644
--- a/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java
+++ b/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java
@@ -2,35 +2,33 @@ package org.briarproject.android.controller.handler;
 
 import android.support.annotation.UiThread;
 
-import org.briarproject.android.DestroyableActivity;
+import org.briarproject.android.DestroyableContext;
 
 public abstract class UiResultExceptionHandler<R, E extends Exception>
 		implements ResultExceptionHandler<R, E> {
 
-	private final DestroyableActivity listener;
+	private final DestroyableContext listener;
 
-	protected UiResultExceptionHandler(DestroyableActivity listener) {
+	protected UiResultExceptionHandler(DestroyableContext listener) {
 		this.listener = listener;
 	}
 
 	@Override
 	public void onResult(final R result) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
-				if (!listener.hasBeenDestroyed())
-					onResultUi(result);
+				onResultUi(result);
 			}
 		});
 	}
 
 	@Override
 	public void onException(final E exception) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
-				if (!listener.hasBeenDestroyed())
-					onExceptionUi(exception);
+				onExceptionUi(exception);
 			}
 		});
 	}
diff --git a/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java b/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java
index 9c2fbe614285339c57cc3c7917161bb8b29d19a7..6516ff71519886c95f732f51a80cd900915809d0 100644
--- a/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java
+++ b/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java
@@ -2,24 +2,22 @@ package org.briarproject.android.controller.handler;
 
 import android.support.annotation.UiThread;
 
-import org.briarproject.android.DestroyableActivity;
-import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
+import org.briarproject.android.DestroyableContext;
 
 public abstract class UiResultHandler<R> implements ResultHandler<R> {
 
-	private final DestroyableActivity listener;
+	private final DestroyableContext listener;
 
-	protected UiResultHandler(DestroyableActivity listener) {
+	protected UiResultHandler(DestroyableContext listener) {
 		this.listener = listener;
 	}
 
 	@Override
 	public void onResult(final R result) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
-				if (!listener.hasBeenDestroyed())
-					onResultUi(result);
+				onResultUi(result);
 			}
 		});
 	}
diff --git a/briar-android/src/org/briarproject/android/forum/CreateForumActivity.java b/briar-android/src/org/briarproject/android/forum/CreateForumActivity.java
index f1de11e32b78cc2470eb49f1efc6c436e0fef768..ff1644b1c95052d0d28d3849d7bf3be891d6ee94 100644
--- a/briar-android/src/org/briarproject/android/forum/CreateForumActivity.java
+++ b/briar-android/src/org/briarproject/android/forum/CreateForumActivity.java
@@ -144,7 +144,7 @@ public class CreateForumActivity extends BriarActivity
 	}
 
 	private void displayForum(final Forum f) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				Intent i = new Intent(CreateForumActivity.this,
diff --git a/briar-android/src/org/briarproject/android/forum/ForumActivity.java b/briar-android/src/org/briarproject/android/forum/ForumActivity.java
index 5660bcd23b761e54978fac87623adaed7e9dc898..b7f6fe279ffa5b592f183fb1d4c16466207034c8 100644
--- a/briar-android/src/org/briarproject/android/forum/ForumActivity.java
+++ b/briar-android/src/org/briarproject/android/forum/ForumActivity.java
@@ -267,9 +267,8 @@ public class ForumActivity extends BriarActivity implements
 			// root post
 			forumController.createPost(StringUtils.toUtf8(text), resultHandler);
 		} else {
-			forumController
-					.createPost(StringUtils.toUtf8(text), replyEntry.getId(),
-							resultHandler);
+			forumController.createPost(StringUtils.toUtf8(text),
+					replyEntry.getId(), resultHandler);
 		}
 		textInput.hideSoftKeyboard();
 		textInput.setVisibility(GONE);
@@ -344,7 +343,7 @@ public class ForumActivity extends BriarActivity implements
 	}
 
 	@Override
-	public void onExternalEntryAdded(ForumPostHeader header) {
+	public void onForumPostReceived(ForumPostHeader header) {
 		forumController.loadPost(header,
 				new UiResultExceptionHandler<ForumEntry, DbException>(this) {
 					@Override
@@ -357,6 +356,10 @@ public class ForumActivity extends BriarActivity implements
 						// TODO add proper exception handling
 					}
 				});
+	}
 
+	@Override
+	public void onForumRemoved() {
+		finish();
 	}
 }
diff --git a/briar-android/src/org/briarproject/android/forum/ForumController.java b/briar-android/src/org/briarproject/android/forum/ForumController.java
index 459aafb2ff0799110372ba4f6b02953d2e9ab3ac..ad08dbc4dd534a918736c43486fcfc6fa44917ce 100644
--- a/briar-android/src/org/briarproject/android/forum/ForumController.java
+++ b/briar-android/src/org/briarproject/android/forum/ForumController.java
@@ -3,6 +3,7 @@ package org.briarproject.android.forum;
 import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 
+import org.briarproject.android.DestroyableContext;
 import org.briarproject.android.controller.ActivityLifecycleController;
 import org.briarproject.android.controller.handler.ResultExceptionHandler;
 import org.briarproject.android.controller.handler.ResultHandler;
@@ -38,9 +39,13 @@ public interface ForumController extends ActivityLifecycleController {
 	void createPost(byte[] body, MessageId parentId,
 			ResultExceptionHandler<ForumEntry, DbException> resultHandler);
 
-	interface ForumPostListener {
+	interface ForumPostListener extends DestroyableContext {
+
+		@UiThread
+		void onForumPostReceived(ForumPostHeader header);
+
 		@UiThread
-		void onExternalEntryAdded(ForumPostHeader header);
+		void onForumRemoved();
 	}
 
 }
diff --git a/briar-android/src/org/briarproject/android/forum/ForumControllerImpl.java b/briar-android/src/org/briarproject/android/forum/ForumControllerImpl.java
index 98f7ac139ed816f61b4a9241b79e1c2248a200ff..0a1cb23a39850ae7529f650c03a6fc447b68b0b5 100644
--- a/briar-android/src/org/briarproject/android/forum/ForumControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/forum/ForumControllerImpl.java
@@ -51,21 +51,19 @@ public class ForumControllerImpl extends DbControllerImpl
 	private static final Logger LOG =
 			Logger.getLogger(ForumControllerImpl.class.getName());
 
-	@Inject
-	protected Activity activity;
 	@Inject
 	@CryptoExecutor
-	protected Executor cryptoExecutor;
+	Executor cryptoExecutor;
 	@Inject
 	volatile ForumPostFactory forumPostFactory;
 	@Inject
-	protected volatile CryptoComponent crypto;
+	volatile CryptoComponent crypto;
 	@Inject
-	protected volatile ForumManager forumManager;
+	volatile ForumManager forumManager;
 	@Inject
-	protected volatile EventBus eventBus;
+	volatile EventBus eventBus;
 	@Inject
-	protected volatile IdentityManager identityManager;
+	volatile IdentityManager identityManager;
 
 	private final Map<MessageId, byte[]> bodyCache = new ConcurrentHashMap<>();
 	private final AtomicLong newestTimeStamp = new AtomicLong();
@@ -81,7 +79,7 @@ public class ForumControllerImpl extends DbControllerImpl
 	}
 
 	@Override
-	public void onActivityCreate() {
+	public void onActivityCreate(Activity activity) {
 		if (activity instanceof ForumPostListener) {
 			listener = (ForumPostListener) activity;
 		} else {
@@ -114,10 +112,10 @@ public class ForumControllerImpl extends DbControllerImpl
 				LOG.info("Forum post received, adding...");
 				final ForumPostHeader fph = pe.getForumPostHeader();
 				updateNewestTimestamp(fph.getTimestamp());
-				activity.runOnUiThread(new Runnable() {
+				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 					@Override
 					public void run() {
-						listener.onExternalEntryAdded(fph);
+						listener.onForumPostReceived(fph);
 					}
 				});
 			}
@@ -125,10 +123,10 @@ public class ForumControllerImpl extends DbControllerImpl
 			GroupRemovedEvent s = (GroupRemovedEvent) e;
 			if (s.getGroup().getId().equals(forum.getId())) {
 				LOG.info("Forum removed");
-				activity.runOnUiThread(new Runnable() {
+				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 					@Override
 					public void run() {
-						activity.finish();
+						listener.onForumRemoved();
 					}
 				});
 			}
diff --git a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java
index 70d82d05d974105f3ac5ba301f7fcf620727f19e..1ebba8c1c327b16b23c9489e623ec4c62713784c 100644
--- a/briar-android/src/org/briarproject/android/forum/ForumListFragment.java
+++ b/briar-android/src/org/briarproject/android/forum/ForumListFragment.java
@@ -56,13 +56,13 @@ public class ForumListFragment extends BaseEventFragment implements
 	private Snackbar snackbar;
 
 	@Inject
-	protected AndroidNotificationManager notificationManager;
+	AndroidNotificationManager notificationManager;
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject
-	protected volatile ForumManager forumManager;
+	volatile ForumManager forumManager;
 	@Inject
-	protected volatile ForumSharingManager forumSharingManager;
+	volatile ForumSharingManager forumSharingManager;
 
 	public static ForumListFragment newInstance() {
 
@@ -181,7 +181,7 @@ public class ForumListFragment extends BaseEventFragment implements
 	}
 
 	private void displayForums(final Collection<ForumListItem> forums) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				if (forums.size() > 0) adapter.addAll(forums);
@@ -211,10 +211,9 @@ public class ForumListFragment extends BaseEventFragment implements
 	}
 
 	private void displayAvailableForums(final int availableCount) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
-				if (getActivity() == null) return;
 				if (availableCount == 0) {
 					snackbar.dismiss();
 				} else {
@@ -245,16 +244,16 @@ public class ForumListFragment extends BaseEventFragment implements
 				removeForum(g.getGroup().getId());
 			}
 		} else if (e instanceof ForumPostReceivedEvent) {
-			ForumPostReceivedEvent m = (ForumPostReceivedEvent) e;
+			ForumPostReceivedEvent f = (ForumPostReceivedEvent) e;
 			LOG.info("Forum post added, updating...");
-			updateItem(m.getGroupId(), m.getForumPostHeader());
+			updateItem(f.getGroupId(), f.getForumPostHeader());
 		} else if (e instanceof ForumInvitationReceivedEvent) {
 			loadAvailableForums();
 		}
 	}
 
 	private void updateItem(final GroupId g, final ForumPostHeader m) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				int position = adapter.findItemPosition(g);
@@ -268,7 +267,7 @@ public class ForumListFragment extends BaseEventFragment implements
 	}
 
 	private void removeForum(final GroupId g) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				int position = adapter.findItemPosition(g);
diff --git a/briar-android/src/org/briarproject/android/fragment/BaseFragment.java b/briar-android/src/org/briarproject/android/fragment/BaseFragment.java
index 7c1e072acc7effc6e94dbec16de11950c480fffb..d671bf245c692463ea937e7d6532e831dea79278 100644
--- a/briar-android/src/org/briarproject/android/fragment/BaseFragment.java
+++ b/briar-android/src/org/briarproject/android/fragment/BaseFragment.java
@@ -7,9 +7,10 @@ import android.support.annotation.UiThread;
 import android.support.v4.app.Fragment;
 
 import org.briarproject.android.ActivityComponent;
-import org.briarproject.android.DestroyableActivity;
+import org.briarproject.android.DestroyableContext;
 
-public abstract class BaseFragment extends Fragment {
+public abstract class BaseFragment extends Fragment
+		implements DestroyableContext {
 
 	protected BaseFragmentListener listener;
 
@@ -20,12 +21,7 @@ public abstract class BaseFragment extends Fragment {
 	@Override
 	public void onAttach(Context context) {
 		super.onAttach(context);
-		try {
-			listener = (BaseFragmentListener) context;
-		} catch (ClassCastException e) {
-			throw new ClassCastException(
-					"Using class must implement BaseFragmentListener");
-		}
+		listener = (BaseFragmentListener) context;
 	}
 
 	@Override
@@ -37,7 +33,7 @@ public abstract class BaseFragment extends Fragment {
 	@Override
 	public void onActivityCreated(@Nullable Bundle savedInstanceState) {
 		super.onActivityCreated(savedInstanceState);
-		this.injectFragment(listener.getActivityComponent());
+		injectFragment(listener.getActivityComponent());
 		listener.onFragmentCreated(getUniqueTag());
 	}
 
@@ -46,7 +42,7 @@ public abstract class BaseFragment extends Fragment {
 		getActivity().supportFinishAfterTransition();
 	}
 
-	public interface BaseFragmentListener extends DestroyableActivity {
+	public interface BaseFragmentListener extends DestroyableContext {
 
 		void runOnDbThread(Runnable runnable);
 
@@ -56,4 +52,9 @@ public abstract class BaseFragment extends Fragment {
 		@UiThread
 		void onFragmentCreated(String tag);
 	}
+
+	@Override
+	public void runOnUiThreadUnlessDestroyed(Runnable r) {
+		listener.runOnUiThreadUnlessDestroyed(r);
+	}
 }
diff --git a/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java b/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java
index 5b768aaa1a1370b7b83c7bc5f9ce67a2af229ec7..15c718b6709519831533590334fa7b702d860f05 100644
--- a/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java
+++ b/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java
@@ -75,15 +75,10 @@ public class SettingsFragment extends PreferenceFragmentCompat
 	public void onAttach(Context context) {
 		super.onAttach(context);
 
-		try {
-			listener = (SettingsActivity) context;
-			androidExecutor = listener.getAndroidExecutor();
-			settingsManager = listener.getSettingsManager();
-			eventBus = listener.getEventBus();
-		} catch (ClassCastException e) {
-			throw new ClassCastException(context.toString()
-					+ " is not a SettingsActivity");
-		}
+		listener = (SettingsActivity) context;
+		androidExecutor = listener.getAndroidExecutor();
+		settingsManager = listener.getSettingsManager();
+		eventBus = listener.getEventBus();
 	}
 
 	@Override
@@ -195,7 +190,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
 	}
 
 	private void displaySettings() {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				enableBluetooth.setValue(Boolean.toString(bluetoothSetting));
diff --git a/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java b/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java
index 0a7ffe7bd2c0b16316e0dc3ceae7cd2bb1be48f2..6a01c3020af3c6c0d1defea18b7138995729659b 100644
--- a/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java
+++ b/briar-android/src/org/briarproject/android/introduction/ContactChooserFragment.java
@@ -39,10 +39,8 @@ import static java.util.logging.Level.WARNING;
 
 public class ContactChooserFragment extends BaseFragment {
 
-	public final static String TAG = "ContactChooserFragment";
-
-	private static final Logger LOG =
-			Logger.getLogger(ContactChooserFragment.class.getName());
+	public static final String TAG = ContactChooserFragment.class.getName();
+	private static final Logger LOG = Logger.getLogger(TAG);
 
 	private IntroductionActivity introductionActivity;
 	private BriarRecyclerView list;
@@ -72,12 +70,7 @@ public class ContactChooserFragment extends BaseFragment {
 	@Override
 	public void onAttach(Context context) {
 		super.onAttach(context);
-		try {
-			introductionActivity = (IntroductionActivity) context;
-		} catch (ClassCastException e) {
-			throw new InstantiationError(
-					"This fragment is only meant to be attached to the IntroductionActivity");
-		}
+		introductionActivity = (IntroductionActivity) context;
 	}
 
 	@Override
@@ -182,7 +175,7 @@ public class ContactChooserFragment extends BaseFragment {
 
 	private void displayContacts(final AuthorId localAuthorId,
 			final List<ContactListItem> contacts) {
-		introductionActivity.runOnUiThread(new Runnable() {
+		introductionActivity.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				adapter.setLocalAuthor(localAuthorId);
diff --git a/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java b/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java
index 05996d5dac10ba74bc297729fb5bdbc30c999985..4b5b3c3cd0cbfed5282613b3e8c69005d5a1d6a4 100644
--- a/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java
+++ b/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java
@@ -37,12 +37,12 @@ import static java.util.logging.Level.WARNING;
 public class IntroductionMessageFragment extends BaseFragment
 		implements TextInputView.TextInputListener {
 
-	public final static String TAG = "IntroductionMessageFragment";
+	public static final String TAG =
+			IntroductionMessageFragment.class.getName();
+	private static final Logger LOG = Logger.getLogger(TAG);
 
 	private final static String CONTACT_ID_1 = "contact1";
 	private final static String CONTACT_ID_2 = "contact2";
-	private static final Logger LOG =
-			Logger.getLogger(IntroductionMessageFragment.class.getName());
 
 	private IntroductionActivity introductionActivity;
 	private ViewHolder ui;
@@ -72,12 +72,7 @@ public class IntroductionMessageFragment extends BaseFragment
 	@Override
 	public void onAttach(Context context) {
 		super.onAttach(context);
-		try {
-			introductionActivity = (IntroductionActivity) context;
-		} catch (ClassCastException e) {
-			throw new java.lang.InstantiationError(
-					"This fragment is only meant to be attached to the IntroductionActivity");
-		}
+		introductionActivity = (IntroductionActivity) context;
 	}
 
 	@Override
@@ -142,7 +137,7 @@ public class IntroductionMessageFragment extends BaseFragment
 	}
 
 	private void setUpViews(final Contact c1, final Contact c2) {
-		introductionActivity.runOnUiThread(new Runnable() {
+		introductionActivity.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				contact1 = c1;
@@ -209,7 +204,7 @@ public class IntroductionMessageFragment extends BaseFragment
 	}
 
 	private void introductionError() {
-		introductionActivity.runOnUiThread(new Runnable() {
+		introductionActivity.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				Toast.makeText(introductionActivity,
diff --git a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java
index 55bdf8fd9ddf4dc4d41a0fbfcb7dc6ffcc1e1fad..bec5b346f6e2c1dd711febfcd23a6fb790431471 100644
--- a/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java
+++ b/briar-android/src/org/briarproject/android/invitation/AddContactActivity.java
@@ -205,6 +205,7 @@ public class AddContactActivity extends BriarActivity
 
 	void loadLocalAuthor() {
 		runOnDbThread(new Runnable() {
+			@Override
 			public void run() {
 				try {
 					long now = System.currentTimeMillis();
@@ -222,7 +223,7 @@ public class AddContactActivity extends BriarActivity
 	}
 
 	void setLocalAuthorId(final AuthorId localAuthorId) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				AddContactActivity.this.localAuthorId = localAuthorId;
@@ -283,8 +284,10 @@ public class AddContactActivity extends BriarActivity
 		}
 	}
 
+	@Override
 	public void connectionSucceeded() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
+			@Override
 			public void run() {
 				connected = true;
 				setView(new ConfirmationCodeView(AddContactActivity.this,
@@ -293,8 +296,10 @@ public class AddContactActivity extends BriarActivity
 		});
 	}
 
+	@Override
 	public void connectionFailed() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
+			@Override
 			public void run() {
 				connectionFailed = true;
 				setView(new ErrorView(AddContactActivity.this,
@@ -304,9 +309,11 @@ public class AddContactActivity extends BriarActivity
 		});
 	}
 
+	@Override
 	public void keyAgreementSucceeded(final int localCode,
 			final int remoteCode) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
+			@Override
 			public void run() {
 				localConfirmationCode = localCode;
 				remoteConfirmationCode = remoteCode;
@@ -315,8 +322,10 @@ public class AddContactActivity extends BriarActivity
 		});
 	}
 
+	@Override
 	public void keyAgreementFailed() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
+			@Override
 			public void run() {
 				connectionFailed = true;
 				setView(new ErrorView(AddContactActivity.this,
@@ -326,8 +335,10 @@ public class AddContactActivity extends BriarActivity
 		});
 	}
 
+	@Override
 	public void remoteConfirmationSucceeded() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
+			@Override
 			public void run() {
 				remoteCompared = true;
 				remoteMatched = true;
@@ -339,8 +350,10 @@ public class AddContactActivity extends BriarActivity
 		});
 	}
 
+	@Override
 	public void remoteConfirmationFailed() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
+			@Override
 			public void run() {
 				remoteCompared = true;
 				remoteMatched = false;
@@ -352,8 +365,10 @@ public class AddContactActivity extends BriarActivity
 		});
 	}
 
+	@Override
 	public void pseudonymExchangeSucceeded(final String remoteName) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
+			@Override
 			public void run() {
 				contactName = remoteName;
 				showToastAndFinish();
@@ -361,8 +376,10 @@ public class AddContactActivity extends BriarActivity
 		});
 	}
 
+	@Override
 	public void pseudonymExchangeFailed() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
+			@Override
 			public void run() {
 				setView(new ErrorView(AddContactActivity.this,
 						R.string.connection_failed,
@@ -386,34 +403,42 @@ public class AddContactActivity extends BriarActivity
 			this.handle = handle;
 		}
 
+		@Override
 		public void connectionSucceeded() {
 			// Wait for key agreement to succeed or fail
 		}
 
+		@Override
 		public void connectionFailed() {
 			referenceManager.removeReference(handle, InvitationTask.class);
 		}
 
+		@Override
 		public void keyAgreementSucceeded(int localCode, int remoteCode) {
 			// Wait for remote confirmation to succeed or fail
 		}
 
+		@Override
 		public void keyAgreementFailed() {
 			referenceManager.removeReference(handle, InvitationTask.class);
 		}
 
+		@Override
 		public void remoteConfirmationSucceeded() {
 			// Wait for the pseudonym exchange to succeed or fail
 		}
 
+		@Override
 		public void remoteConfirmationFailed() {
 			referenceManager.removeReference(handle, InvitationTask.class);
 		}
 
+		@Override
 		public void pseudonymExchangeSucceeded(String remoteName) {
 			referenceManager.removeReference(handle, InvitationTask.class);
 		}
 
+		@Override
 		public void pseudonymExchangeFailed() {
 			referenceManager.removeReference(handle, InvitationTask.class);
 		}
diff --git a/briar-android/src/org/briarproject/android/keyagreement/IntroFragment.java b/briar-android/src/org/briarproject/android/keyagreement/IntroFragment.java
index 2a1c2365ede8ce650a0cf332a5c5f544dc83fca8..6ce313f372313df927fcdef120e73b65711d3da9 100644
--- a/briar-android/src/org/briarproject/android/keyagreement/IntroFragment.java
+++ b/briar-android/src/org/briarproject/android/keyagreement/IntroFragment.java
@@ -43,12 +43,7 @@ public class IntroFragment extends BaseFragment {
 	@Override
 	public void onAttach(Context context) {
 		super.onAttach(context);
-		try {
-			screenSeenListener = (IntroScreenSeenListener) context;
-		} catch (ClassCastException e) {
-			throw new ClassCastException(
-					"Using class must implement IntroScreenSeenListener");
-		}
+		screenSeenListener = (IntroScreenSeenListener) context;
 	}
 
 	@Override
diff --git a/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java b/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java
index a9c7fb4b6b69251b6b1ebe61b5afd76b32915e7c..8ef2764cf42ea9af3fd483057b866ad38b6bcb86 100644
--- a/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java
+++ b/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java
@@ -128,7 +128,7 @@ public class KeyAgreementActivity extends BriarFragmentActivity implements
 	}
 
 	private void keyAgreementFinished(final KeyAgreementResult result) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				startContactExchange(result);
@@ -162,7 +162,7 @@ public class KeyAgreementActivity extends BriarFragmentActivity implements
 
 	@Override
 	public void contactExchangeSucceeded(final Author remoteAuthor) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				String contactName = remoteAuthor.getName();
@@ -177,7 +177,7 @@ public class KeyAgreementActivity extends BriarFragmentActivity implements
 
 	@Override
 	public void duplicateContact(final Author remoteAuthor) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				String contactName = remoteAuthor.getName();
@@ -192,7 +192,7 @@ public class KeyAgreementActivity extends BriarFragmentActivity implements
 
 	@Override
 	public void contactExchangeFailed() {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				Toast.makeText(KeyAgreementActivity.this,
diff --git a/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java b/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java
index 3ebe742ebc23115c3c3eef89b523f6b2b863c12d..cef537288c3c845d24137d380994bed35b9f93d3 100644
--- a/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java
+++ b/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java
@@ -18,7 +18,6 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.AlphaAnimation;
 import android.widget.ImageView;
-import android.widget.ProgressBar;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -67,23 +66,21 @@ public class ShowQrCodeFragment extends BaseEventFragment
 	private static final Logger LOG = Logger.getLogger(TAG);
 
 	@Inject
-	protected KeyAgreementTaskFactory keyAgreementTaskFactory;
+	KeyAgreementTaskFactory keyAgreementTaskFactory;
 	@Inject
-	protected PayloadEncoder payloadEncoder;
+	PayloadEncoder payloadEncoder;
 	@Inject
-	protected PayloadParser payloadParser;
+	PayloadParser payloadParser;
 	@Inject
-	protected AndroidExecutor androidExecutor;
+	AndroidExecutor androidExecutor;
 	@Inject
 	@IoExecutor
-	protected Executor ioExecutor;
+	Executor ioExecutor;
 
 	private CameraView cameraView;
-	private ViewGroup cameraOverlay;
 	private View statusView;
 	private TextView status;
 	private ImageView qrCode;
-	private ProgressBar mainProgressBar;
 	private TextView mainProgressTitle;
 	private ViewGroup mainProgressContainer;
 
@@ -124,11 +121,9 @@ public class ShowQrCodeFragment extends BaseEventFragment
 		super.onViewCreated(view, savedInstanceState);
 
 		cameraView = (CameraView) view.findViewById(R.id.camera_view);
-		cameraOverlay = (ViewGroup) view.findViewById(R.id.camera_overlay);
 		statusView = view.findViewById(R.id.status_container);
 		status = (TextView) view.findViewById(R.id.connect_status);
 		qrCode = (ImageView) view.findViewById(R.id.qr_code);
-		mainProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
 		mainProgressTitle =
 				(TextView) view.findViewById(R.id.title_progress_bar);
 		mainProgressContainer =
@@ -286,11 +281,12 @@ public class ShowQrCodeFragment extends BaseEventFragment
 			KeyAgreementAbortedEvent event = (KeyAgreementAbortedEvent) e;
 			keyAgreementAborted(event.didRemoteAbort());
 		} else if (e instanceof KeyAgreementFinishedEvent) {
-			listener.runOnUiThread(new Runnable() {
+			listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 				@Override
 				public void run() {
 					mainProgressContainer.setVisibility(VISIBLE);
-					mainProgressTitle.setText(R.string.exchanging_contact_details);
+					mainProgressTitle.setText(
+							R.string.exchanging_contact_details);
 				}
 			});
 		}
@@ -309,9 +305,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 				String input =
 						Base64.encodeToString(payloadEncoder.encode(payload),
 								0);
-				Bitmap bitmap =
-						QrCodeUtils.createQrCode(dm, input);
-				return bitmap;
+				return QrCodeUtils.createQrCode(dm, input);
 			}
 
 			@Override
@@ -328,7 +322,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 	}
 
 	private void setQrCode(final Payload localPayload) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				generateBitmapQR(localPayload);
@@ -337,7 +331,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 	}
 
 	private void keyAgreementFailed() {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				reset();
@@ -349,7 +343,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 	}
 
 	private void keyAgreementWaiting() {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				status.setText(R.string.waiting_for_contact);
@@ -358,7 +352,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 	}
 
 	private void keyAgreementStarted() {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				mainProgressContainer.setVisibility(VISIBLE);
@@ -368,7 +362,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 	}
 
 	private void keyAgreementAborted(final boolean remoteAborted) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				reset();
@@ -385,7 +379,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 
 	@Override
 	public void handleResult(final Result result) {
-		listener.runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				LOG.info("Got result from decoder");
diff --git a/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java b/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java
index 893ea91262addaa7c1e18b962968a1999172d7f2..286e0616dc6192934de34a3bf678bf808d236362 100644
--- a/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java
+++ b/briar-android/src/org/briarproject/android/sharing/ContactSelectorFragment.java
@@ -46,10 +46,8 @@ import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
 public class ContactSelectorFragment extends BaseFragment implements
 		BaseContactListAdapter.OnItemClickListener {
 
-	public final static String TAG = "ContactSelectorFragment";
-
-	private static final Logger LOG =
-			Logger.getLogger(ContactSelectorFragment.class.getName());
+	public static final String TAG = ContactSelectorFragment.class.getName();
+	private static final Logger LOG = Logger.getLogger(TAG);
 
 	private ShareActivity shareActivity;
 	private Menu menu;
@@ -84,12 +82,7 @@ public class ContactSelectorFragment extends BaseFragment implements
 	@Override
 	public void onAttach(Context context) {
 		super.onAttach(context);
-		try {
-			shareActivity = (ShareActivity) context;
-		} catch (ClassCastException e) {
-			throw new InstantiationError(
-					"This fragment is only meant to be attached to a subclass of ShareActivity");
-		}
+		shareActivity = (ShareActivity) context;
 	}
 
 	@Override
@@ -221,7 +214,7 @@ public class ContactSelectorFragment extends BaseFragment implements
 	}
 
 	private void displayContacts(final List<ContactListItem> contacts) {
-		shareActivity.runOnUiThread(new Runnable() {
+		shareActivity.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				if (!contacts.isEmpty()) adapter.addAll(contacts);
diff --git a/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java b/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java
index c7d99b14bd0f8990fd0d8617be028fd00e20dce9..941dbb48f16d102557c16a22ed722211e9dce4de 100644
--- a/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java
+++ b/briar-android/src/org/briarproject/android/sharing/InvitationsActivity.java
@@ -32,7 +32,7 @@ abstract class InvitationsActivity extends BriarActivity
 	private BriarRecyclerView list;
 
 	@Inject
-	protected EventBus eventBus;
+	EventBus eventBus;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -103,7 +103,7 @@ abstract class InvitationsActivity extends BriarActivity
 
 	protected void displayInvitations(
 			final Collection<InvitationItem> invitations, final boolean clear) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				if (invitations.isEmpty()) {
diff --git a/briar-android/src/org/briarproject/android/sharing/ShareBlogMessageFragment.java b/briar-android/src/org/briarproject/android/sharing/ShareBlogMessageFragment.java
index f981602996fd24a138b4e48b5e6e0ceece55625f..d9f944ab0c91654912f33c1797d34a67cffbfabd 100644
--- a/briar-android/src/org/briarproject/android/sharing/ShareBlogMessageFragment.java
+++ b/briar-android/src/org/briarproject/android/sharing/ShareBlogMessageFragment.java
@@ -14,6 +14,7 @@ import org.briarproject.api.db.DbException;
 import org.briarproject.api.sync.GroupId;
 
 import java.util.Collection;
+import java.util.logging.Logger;
 
 import javax.inject.Inject;
 
@@ -23,6 +24,7 @@ import static java.util.logging.Level.WARNING;
 public class ShareBlogMessageFragment extends ShareMessageFragment {
 
 	public final static String TAG = ShareBlogMessageFragment.class.getName();
+	private static final Logger LOG = Logger.getLogger(TAG);
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject
@@ -52,6 +54,12 @@ public class ShareBlogMessageFragment extends ShareMessageFragment {
 		component.inject(this);
 	}
 
+	@Override
+	public String getUniqueTag() {
+		return TAG;
+	}
+
+	@Override
 	protected void share(final String msg) {
 		listener.runOnDbThread(new Runnable() {
 			@Override
@@ -69,8 +77,9 @@ public class ShareBlogMessageFragment extends ShareMessageFragment {
 		});
 	}
 
+	@Override
 	protected void sharingError() {
-		runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				int res = R.string.blogs_sharing_error;
diff --git a/briar-android/src/org/briarproject/android/sharing/ShareForumMessageFragment.java b/briar-android/src/org/briarproject/android/sharing/ShareForumMessageFragment.java
index f24869467a69076768f143086e9e419d91496c3e..8414096f01073fbfbf44532af73030591cbe634f 100644
--- a/briar-android/src/org/briarproject/android/sharing/ShareForumMessageFragment.java
+++ b/briar-android/src/org/briarproject/android/sharing/ShareForumMessageFragment.java
@@ -14,6 +14,7 @@ import org.briarproject.api.forum.ForumSharingManager;
 import org.briarproject.api.sync.GroupId;
 
 import java.util.Collection;
+import java.util.logging.Logger;
 
 import javax.inject.Inject;
 
@@ -23,6 +24,7 @@ import static java.util.logging.Level.WARNING;
 public class ShareForumMessageFragment extends ShareMessageFragment {
 
 	public final static String TAG = ShareForumMessageFragment.class.getName();
+	private static final Logger LOG = Logger.getLogger(TAG);
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject
@@ -49,6 +51,12 @@ public class ShareForumMessageFragment extends ShareMessageFragment {
 		component.inject(this);
 	}
 
+	@Override
+	public String getUniqueTag() {
+		return TAG;
+	}
+
+	@Override
 	protected void share(final String msg) {
 		listener.runOnDbThread(new Runnable() {
 			@Override
@@ -67,8 +75,9 @@ public class ShareForumMessageFragment extends ShareMessageFragment {
 		});
 	}
 
+	@Override
 	protected void sharingError() {
-		runOnUiThread(new Runnable() {
+		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				int res = R.string.forum_share_error;
diff --git a/briar-android/src/org/briarproject/android/sharing/ShareMessageFragment.java b/briar-android/src/org/briarproject/android/sharing/ShareMessageFragment.java
index 0df394e1f807a0aa4c51e4e358efca7249dc405d..5a8f4747639dec6154ac2de9f03c82bc01c44f29 100644
--- a/briar-android/src/org/briarproject/android/sharing/ShareMessageFragment.java
+++ b/briar-android/src/org/briarproject/android/sharing/ShareMessageFragment.java
@@ -18,7 +18,6 @@ import org.briarproject.api.sync.GroupId;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.logging.Logger;
 
 import javax.inject.Inject;
 
@@ -29,10 +28,6 @@ import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
 abstract class ShareMessageFragment extends BaseFragment
 		implements TextInputListener {
 
-	public final static String TAG = ShareMessageFragment.class.getName();
-
-	protected static final Logger LOG = Logger.getLogger(TAG);
-
 	protected ViewHolder ui;
 	private ShareActivity shareActivity;
 
@@ -56,12 +51,7 @@ abstract class ShareMessageFragment extends BaseFragment
 	@Override
 	public void onAttach(Context context) {
 		super.onAttach(context);
-		try {
-			shareActivity = (ShareActivity) context;
-		} catch (ClassCastException e) {
-			throw new InstantiationError(
-					"This fragment is only meant to be attached to the ShareForumActivity");
-		}
+		shareActivity = (ShareActivity) context;
 	}
 
 	@Override
@@ -104,11 +94,6 @@ abstract class ShareMessageFragment extends BaseFragment
 		}
 	}
 
-	@Override
-	public String getUniqueTag() {
-		return TAG;
-	}
-
 	protected void setTitle(int res) {
 		shareActivity.setTitle(res);
 	}
@@ -136,10 +121,6 @@ abstract class ShareMessageFragment extends BaseFragment
 		return groupId;
 	}
 
-	protected void runOnUiThread(Runnable runnable) {
-		listener.runOnUiThread(runnable);
-	}
-
 	protected static class ViewHolder {
 		protected final LargeTextInputView message;
 
diff --git a/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java b/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java
index 422a7d16d85af5d05181c16d88a0c3a6737bad2b..969d525a3fdf2328ec9f0dea1358d0196da94778 100644
--- a/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java
+++ b/briar-android/src/org/briarproject/android/sharing/SharingStatusActivity.java
@@ -27,16 +27,16 @@ import static java.util.logging.Level.WARNING;
 
 abstract class SharingStatusActivity extends BriarActivity {
 
+	private static final Logger LOG =
+			Logger.getLogger(SharingStatusActivity.class.getName());
+
 	private GroupId groupId;
 	private BriarRecyclerView sharedByList, sharedWithList;
 	private SharingStatusAdapter sharedByAdapter, sharedWithAdapter;
 
 	// Fields that are accessed from background threads must be volatile
 	@Inject
-	protected volatile IdentityManager identityManager;
-
-	public final static String TAG = SharingStatusActivity.class.getName();
-	private static final Logger LOG = Logger.getLogger(TAG);
+	volatile IdentityManager identityManager;
 
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
@@ -120,7 +120,7 @@ abstract class SharingStatusActivity extends BriarActivity {
 	}
 
 	private void displaySharedBy(final List<ContactListItem> contacts) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				if (contacts.isEmpty()) {
@@ -156,7 +156,7 @@ abstract class SharingStatusActivity extends BriarActivity {
 	}
 
 	private void displaySharedWith(final List<ContactListItem> contacts) {
-		runOnUiThread(new Runnable() {
+		runOnUiThreadUnlessDestroyed(new Runnable() {
 			@Override
 			public void run() {
 				if (contacts.isEmpty()) {
diff --git a/briar-android/src/org/briarproject/android/view/TextInputView.java b/briar-android/src/org/briarproject/android/view/TextInputView.java
index e005624d2a62b58832bfa745f0a40cd71cc622a6..da1e58969a92b850a00ae99f0d3a19c417a10dc2 100644
--- a/briar-android/src/org/briarproject/android/view/TextInputView.java
+++ b/briar-android/src/org/briarproject/android/view/TextInputView.java
@@ -24,17 +24,14 @@ import org.thoughtcrime.securesms.components.emoji.EmojiDrawer.EmojiEventListene
 import org.thoughtcrime.securesms.components.emoji.EmojiEditText;
 import org.thoughtcrime.securesms.components.emoji.EmojiToggle;
 
-import java.util.logging.Logger;
-
 import static android.content.Context.INPUT_METHOD_SERVICE;
+import static android.content.Context.LAYOUT_INFLATER_SERVICE;
+import static android.view.KeyEvent.KEYCODE_BACK;
 
 @UiThread
 public class TextInputView extends KeyboardAwareLinearLayout
 		implements EmojiEventListener {
 
-	private static final String TAG = TextInputView.class.getName();
-	private static final Logger LOG = Logger.getLogger(TAG);
-
 	protected final ViewHolder ui;
 	protected TextInputListener listener;
 
@@ -59,7 +56,7 @@ public class TextInputView extends KeyboardAwareLinearLayout
 
 	protected void inflateLayout(Context context) {
 		LayoutInflater inflater = (LayoutInflater) context
-				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+				.getSystemService(LAYOUT_INFLATER_SERVICE);
 		inflater.inflate(R.layout.text_input_view, this, true);
 	}
 
@@ -91,7 +88,7 @@ public class TextInputView extends KeyboardAwareLinearLayout
 		ui.editText.setOnKeyListener(new OnKeyListener() {
 			@Override
 			public boolean onKey(View v, int keyCode, KeyEvent event) {
-				if (keyCode == KeyEvent.KEYCODE_BACK && isEmojiDrawerOpen()) {
+				if (keyCode == KEYCODE_BACK && isEmojiDrawerOpen()) {
 					hideEmojiDrawer();
 					return true;
 				}
@@ -207,10 +204,11 @@ public class TextInputView extends KeyboardAwareLinearLayout
 	}
 
 	protected class ViewHolder {
+
 		private final EmojiToggle emojiToggle;
-		protected final EmojiEditText editText;
-		protected final View sendButton;
-		protected final EmojiDrawer emojiDrawer;
+		final EmojiEditText editText;
+		final View sendButton;
+		final EmojiDrawer emojiDrawer;
 
 		private ViewHolder() {
 			emojiToggle = (EmojiToggle) findViewById(R.id.emoji_toggle);