diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java
index e038fb7fd9085d1f3d38e7c0fb77a3f37e8f1a4f..817bdd0e4e541c2a11851de0008acb7f28a85b5c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java
@@ -43,6 +43,8 @@ import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
 import org.briarproject.briar.api.privategroup.PrivateGroupManager;
 import org.briarproject.briar.api.privategroup.invitation.GroupInvitationFactory;
 import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
+import org.thoughtcrime.securesms.components.emoji.EmojiProvider;
+import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel;
 
 import java.util.concurrent.Executor;
 
@@ -138,10 +140,14 @@ public interface AndroidComponent
 	@IoExecutor
 	Executor ioExecutor();
 
-	void inject(BriarService activity);
+	void inject(BriarService briarService);
 
 	void inject(BriarReportSender briarReportSender);
 
+	void inject(EmojiProvider emojiProvider);
+
+	void inject(RecentEmojiPageModel recentEmojiPageModel);
+
 	// Eager singleton load
 	void inject(AppModule.EagerSingletons init);
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java
index 432cd87947761d69990d0ba6f61cfc5372cea399..60ed47f5ab6c9a118439e07a4f324e4c255816ef 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java
@@ -64,8 +64,6 @@ import org.briarproject.briar.android.sharing.ShareForumFragment;
 import org.briarproject.briar.android.sharing.ShareForumMessageFragment;
 import org.briarproject.briar.android.sharing.SharingModule;
 import org.briarproject.briar.android.splash.SplashScreenActivity;
-import org.thoughtcrime.securesms.components.emoji.EmojiProvider;
-import org.thoughtcrime.securesms.components.emoji.RecentEmojiPageModel;
 
 import dagger.Component;
 
@@ -151,10 +149,6 @@ public interface ActivityComponent {
 
 	void inject(RssFeedManageActivity activity);
 
-	void inject(EmojiProvider emojiProvider);
-
-	void inject(RecentEmojiPageModel recentEmojiPageModel);
-
 	// Fragments
 	void inject(ContactListFragment fragment);
 
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
index 5a34edf4b3d3a585e514b7703feb8e124b31285b..c479ee1685509469741714c9ce94cf88b0440beb 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
@@ -18,7 +18,7 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
 import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
 import org.briarproject.bramble.api.system.AndroidExecutor;
 import org.briarproject.briar.R;
-import org.briarproject.briar.android.activity.BaseActivity;
+import org.briarproject.briar.android.BriarApplication;
 import org.thoughtcrime.securesms.components.util.FutureTaskListener;
 import org.thoughtcrime.securesms.components.util.ListenableFutureTask;
 import org.thoughtcrime.securesms.util.BitmapDecodingException;
@@ -35,6 +35,8 @@ import java.util.regex.Pattern;
 import javax.annotation.Nullable;
 import javax.inject.Inject;
 
+import static android.graphics.Paint.ANTI_ALIAS_FLAG;
+import static android.graphics.Paint.FILTER_BITMAP_FLAG;
 import static android.graphics.PixelFormat.TRANSLUCENT;
 import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
 import static java.util.logging.Level.INFO;
@@ -47,7 +49,7 @@ public class EmojiProvider {
 	private static volatile EmojiProvider INSTANCE = null;
 
 	private static final Paint PAINT =
-			new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
+			new Paint(FILTER_BITMAP_FLAG | ANTI_ALIAS_FLAG);
 
 	@Inject
 	AndroidExecutor androidExecutor;
@@ -77,8 +79,9 @@ public class EmojiProvider {
 				if (INSTANCE == null) {
 					LOG.info("Creating new instance of EmojiProvider");
 					INSTANCE = new EmojiProvider(context);
-					((BaseActivity) context).getActivityComponent()
-							.inject(INSTANCE);
+					BriarApplication app =
+							(BriarApplication) context.getApplicationContext();
+					app.getApplicationComponent().inject(INSTANCE);
 				}
 			}
 		}
@@ -93,7 +96,7 @@ public class EmojiProvider {
 		staticPages = EmojiPages.getPages(context);
 		for (EmojiPageModel page : staticPages) {
 			if (page.hasSpriteMap()) {
-				final EmojiPageBitmap pageBitmap = new EmojiPageBitmap(page);
+				EmojiPageBitmap pageBitmap = new EmojiPageBitmap(page);
 				for (int i = 0; i < page.getEmoji().length; i++) {
 					offsets.put(Character.codePointAt(page.getEmoji()[i], 0),
 							new DrawInfo(pageBitmap, i));
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java
index 89d086ef790157ad949abcfac7029ddab1abdf89..21eab06aeacba6b12feb34694a1c3ecbaddc3227 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/RecentEmojiPageModel.java
@@ -2,19 +2,21 @@ package org.thoughtcrime.securesms.components.emoji;
 
 import android.content.Context;
 import android.support.annotation.DrawableRes;
-import android.support.annotation.NonNull;
-import android.support.annotation.UiThread;
 
+import org.briarproject.bramble.api.db.DatabaseExecutor;
 import org.briarproject.bramble.api.db.DbException;
+import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
+import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
 import org.briarproject.bramble.api.settings.Settings;
 import org.briarproject.bramble.api.settings.SettingsManager;
+import org.briarproject.bramble.util.StringUtils;
 import org.briarproject.briar.R;
-import org.briarproject.briar.android.activity.BaseActivity;
-import org.briarproject.briar.android.controller.DbController;
+import org.briarproject.briar.android.BriarApplication;
 
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
+import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import javax.annotation.Nullable;
@@ -23,7 +25,8 @@ import javax.inject.Inject;
 import static java.util.logging.Level.WARNING;
 import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
 
-@UiThread
+@MethodsNotNullByDefault
+@ParametersNotNullByDefault
 public class RecentEmojiPageModel implements EmojiPageModel {
 
 	private static final Logger LOG =
@@ -32,27 +35,27 @@ public class RecentEmojiPageModel implements EmojiPageModel {
 	private static final String EMOJI_LRU_PREFERENCE = "pref_emoji_recent";
 	private static final int EMOJI_LRU_SIZE = 50;
 
-	private final LinkedHashSet<String> recentlyUsed;
-	private Settings settings;
+	private final LinkedHashSet<String> recentlyUsed; // UI thread
 
 	@Inject
 	SettingsManager settingsManager;
+
 	@Inject
-	DbController dbController;
+	@DatabaseExecutor
+	Executor dbExecutor;
 
 	RecentEmojiPageModel(Context context) {
-		if (!(context instanceof BaseActivity)) {
-			throw new IllegalArgumentException(
-					"Needs to be created from BaseActivity");
-		}
-		((BaseActivity) context).getActivityComponent().inject(this);
+		BriarApplication app =
+				(BriarApplication) context.getApplicationContext();
+		app.getApplicationComponent().inject(this);
 		recentlyUsed = getPersistedCache();
 	}
 
 	private LinkedHashSet<String> getPersistedCache() {
 		String serialized;
 		try {
-			settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
+			// FIXME: Don't make DB calls on the UI thread
+			Settings settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
 			serialized = settings.get(EMOJI_LRU_PREFERENCE);
 		} catch (DbException e) {
 			if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
@@ -67,7 +70,6 @@ public class RecentEmojiPageModel implements EmojiPageModel {
 		return R.drawable.ic_emoji_recent;
 	}
 
-	@NonNull
 	@Override
 	public String[] getEmoji() {
 		return toReversePrimitiveArray(recentlyUsed);
@@ -92,31 +94,26 @@ public class RecentEmojiPageModel implements EmojiPageModel {
 			iterator.next();
 			iterator.remove();
 		}
-		save(recentlyUsed);
+		save(serialize(recentlyUsed));
 	}
 
 	private String serialize(LinkedHashSet<String> emojis) {
-		String result = "";
-		for (String emoji : emojis) {
-			result += emoji + ";";
-		}
-		if (!emojis.isEmpty())
-			result = result.substring(0, result.length() - 1);
-		return result;
+		return StringUtils.join(emojis, ";");
 	}
 
-	private LinkedHashSet<String> deserialize(@Nullable String str) {
-		String[] list = str == null ? new String[] {} : str.split(";");
+	private LinkedHashSet<String> deserialize(@Nullable String serialized) {
+		if (serialized == null) return new LinkedHashSet<>();
+		String[] list = serialized.split(";");
 		LinkedHashSet<String> result = new LinkedHashSet<>(list.length);
 		Collections.addAll(result, list);
 		return result;
 	}
 
-	private void save(final LinkedHashSet<String> recentlyUsed) {
-		dbController.runOnDbThread(new Runnable() {
+	private void save(final String serialized) {
+		dbExecutor.execute(new Runnable() {
 			@Override
 			public void run() {
-				String serialized = serialize(recentlyUsed);
+				Settings settings = new Settings();
 				settings.put(EMOJI_LRU_PREFERENCE, serialized);
 				try {
 					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
@@ -128,8 +125,7 @@ public class RecentEmojiPageModel implements EmojiPageModel {
 		});
 	}
 
-	private String[] toReversePrimitiveArray(
-			@NonNull LinkedHashSet<String> emojiSet) {
+	private String[] toReversePrimitiveArray(LinkedHashSet<String> emojiSet) {
 		String[] emojis = new String[emojiSet.size()];
 		int i = emojiSet.size() - 1;
 		for (String emoji : emojiSet) {