From 5fa6b0ca1c749e52407ebc1e147e84f27f3d70cd Mon Sep 17 00:00:00 2001
From: akwizgran <michael@briarproject.org>
Date: Thu, 16 Nov 2017 10:29:18 +0000
Subject: [PATCH] Lambdas.

---
 .../plugin/droidtooth/DroidtoothPlugin.java   | 115 ++-
 .../bramble/plugin/tor/TorPlugin.java         | 170 ++---
 .../bramble/system/AndroidExecutorImpl.java   |  13 +-
 .../bramble/test/BrambleTestCase.java         |   9 +-
 .../briarproject/bramble/PoliteExecutor.java  |  21 +-
 .../bramble/TimeLoggingExecutor.java          |  17 +-
 .../bramble/db/DatabaseComponentImpl.java     |  14 +-
 .../bramble/plugin/ConnectionManagerImpl.java |  14 +-
 .../briarproject/bramble/plugin/Poller.java   |  38 +-
 .../bramble/plugin/tcp/LanTcpPlugin.java      |  16 +-
 .../bramble/plugin/tcp/PortMapperImpl.java    |   7 +-
 .../bramble/plugin/tcp/TcpPlugin.java         |  75 +-
 .../reliability/ReliabilityLayerImpl.java     |  52 +-
 .../bramble/sync/DuplexOutgoingSession.java   |   7 +-
 .../bramble/sync/SimplexOutgoingSession.java  |   7 +-
 .../bramble/sync/ValidationManagerImpl.java   |  70 +-
 .../bramble/transport/KeyManagerImpl.java     |   8 +-
 .../transport/TransportKeyManagerImpl.java    |  30 +-
 .../bramble/PoliteExecutorTest.java           |  56 +-
 .../lifecycle/ShutdownManagerImplTest.java    |   6 +-
 .../lifecycle/WindowsShutdownManagerImpl.java |  16 +-
 .../plugin/bluetooth/BluetoothPlugin.java     |  82 +--
 .../bramble/plugin/modem/ModemImpl.java       |  15 +-
 .../AndroidNotificationManagerImpl.java       | 254 +++----
 .../briar/android/BriarService.java           |  51 +-
 .../briar/android/activity/BaseActivity.java  |   7 +-
 .../briar/android/activity/BriarActivity.java |  21 +-
 .../android/blog/BaseControllerImpl.java      | 114 ++-
 .../briar/android/blog/BasePostFragment.java  |  11 +-
 .../briar/android/blog/BlogActivity.java      |  17 +-
 .../android/blog/BlogControllerImpl.java      | 106 ++-
 .../briar/android/blog/BlogFragment.java      |  14 +-
 .../android/blog/BlogPostViewHolder.java      |  53 +-
 .../android/blog/FeedControllerImpl.java      |  73 +-
 .../briar/android/blog/FeedFragment.java      |   7 +-
 .../briar/android/blog/ReblogFragment.java    |   7 +-
 .../briar/android/blog/RssFeedAdapter.java    |  15 +-
 .../android/blog/RssFeedImportActivity.java   |  72 +-
 .../android/blog/RssFeedManageActivity.java   |  89 +--
 .../android/blog/WriteBlogPostActivity.java   |  49 +-
 .../contact/ContactItemViewHolder.java        |   7 +-
 .../android/contact/ContactListFragment.java  | 167 ++---
 .../android/contact/ConversationActivity.java | 652 +++++++-----------
 .../ConversationRequestViewHolder.java        |  31 +-
 .../ContactSelectorControllerImpl.java        |  33 +-
 .../android/controller/DbControllerImpl.java  |  17 +-
 .../controller/SharingControllerImpl.java     |  11 +-
 .../handler/UiExceptionHandler.java           |   7 +-
 .../handler/UiResultExceptionHandler.java     |   7 +-
 .../controller/handler/UiResultHandler.java   |   7 +-
 .../android/forum/CreateForumActivity.java    |  69 +-
 .../briar/android/forum/ForumActivity.java    |  25 +-
 .../android/forum/ForumControllerImpl.java    |  91 +--
 .../briar/android/forum/ForumListAdapter.java |  15 +-
 .../android/forum/ForumListFragment.java      | 131 ++--
 .../briar/android/fragment/BaseFragment.java  |  13 +-
 .../fragment/ScreenFilterDialogFragment.java  |   8 +-
 .../introduction/ContactChooserFragment.java  |  57 +-
 .../IntroductionMessageFragment.java          |  98 ++-
 .../android/keyagreement/CameraView.java      |  42 +-
 .../android/keyagreement/IntroFragment.java   |  15 +-
 .../keyagreement/KeyAgreementActivity.java    | 101 +--
 .../keyagreement/ShowQrCodeFragment.java      | 105 +--
 .../briar/android/login/PasswordActivity.java |  21 +-
 .../android/login/PasswordControllerImpl.java |  38 +-
 .../android/login/SetupControllerImpl.java    |  17 +-
 .../android/navdrawer/NavDrawerActivity.java  |  26 +-
 .../navdrawer/NavDrawerControllerImpl.java    |  90 ++-
 .../panic/PanicPreferencesFragment.java       | 104 ++-
 .../android/panic/PanicResponderActivity.java |  21 +-
 .../conversation/GroupActivity.java           |  17 +-
 .../conversation/GroupControllerImpl.java     | 149 ++--
 .../creation/CreateGroupControllerImpl.java   | 144 ++--
 .../creation/CreateGroupFragment.java         |  21 +-
 .../GroupInvitationControllerImpl.java        |  20 +-
 .../list/GroupListControllerImpl.java         | 126 ++--
 .../privategroup/list/GroupViewHolder.java    |  23 +-
 .../GroupMemberListControllerImpl.java        |  34 +-
 .../reveal/RevealContactsActivity.java        |  16 +-
 .../reveal/RevealContactsControllerImpl.java  |  92 +--
 .../android/reporting/BriarReportPrimer.java  |   9 +-
 .../android/reporting/DevReportActivity.java  |  49 +-
 .../android/settings/SettingsFragment.java    | 257 +++----
 .../sharing/BlogInvitationControllerImpl.java |  22 +-
 .../ForumInvitationControllerImpl.java        |  22 +-
 .../android/sharing/InvitationActivity.java   |  25 +-
 .../sharing/InvitationControllerImpl.java     |  29 +-
 .../android/sharing/InvitationViewHolder.java |  14 +-
 .../sharing/ShareBlogControllerImpl.java      |  34 +-
 .../sharing/ShareForumControllerImpl.java     |  34 +-
 .../sharing/SharingStatusActivity.java        |  34 +-
 .../android/splash/SplashScreenActivity.java  |  17 +-
 .../threaded/BaseThreadItemViewHolder.java    |   9 +-
 .../android/threaded/ThreadListActivity.java  |  23 +-
 .../threaded/ThreadListControllerImpl.java    | 181 +++--
 .../threaded/ThreadPostViewHolder.java        |   7 +-
 .../briar/android/util/UiUtils.java           |  26 +-
 .../briar/android/view/BriarRecyclerView.java |  38 +-
 .../briar/android/view/TextInputView.java     |  63 +-
 .../android/widget/LinkDialogFragment.java    |  17 +-
 .../components/emoji/EmojiDrawer.java         |  20 +-
 .../components/emoji/EmojiPageView.java       |  12 +-
 .../components/emoji/EmojiProvider.java       |  19 +-
 .../emoji/RecentEmojiPageModel.java           |  18 +-
 .../components/util/ListenableFutureTask.java |   9 +-
 .../briar/client/MessageTreeImpl.java         |   8 +-
 .../briar/feed/FeedManagerImpl.java           |  41 +-
 .../briar/test/TestDataCreatorImpl.java       |  16 +-
 .../IntroductionIntegrationTest.java          |  36 +-
 109 files changed, 2106 insertions(+), 3469 deletions(-)

diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java
index a2d0695ece..509e700e5e 100644
--- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java
+++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/droidtooth/DroidtoothPlugin.java
@@ -124,12 +124,7 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
 		// with a message queue, so submit it to the AndroidExecutor
 		try {
 			adapter = androidExecutor.runOnBackgroundThread(
-					new Callable<BluetoothAdapter>() {
-						@Override
-						public BluetoothAdapter call() throws Exception {
-							return BluetoothAdapter.getDefaultAdapter();
-						}
-					}).get();
+					BluetoothAdapter::getDefaultAdapter).get();
 		} catch (InterruptedException e) {
 			Thread.currentThread().interrupt();
 			LOG.warning("Interrupted while getting BluetoothAdapter");
@@ -162,40 +157,36 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
 	}
 
 	private void bind() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!isRunning()) return;
-				String address = AndroidUtils.getBluetoothAddress(appContext,
-						adapter);
-				if (LOG.isLoggable(INFO))
-					LOG.info("Local address " + scrubMacAddress(address));
-				if (!StringUtils.isNullOrEmpty(address)) {
-					// Advertise the Bluetooth address to contacts
-					TransportProperties p = new TransportProperties();
-					p.put(PROP_ADDRESS, address);
-					callback.mergeLocalProperties(p);
-				}
-				// Bind a server socket to accept connections from contacts
-				BluetoothServerSocket ss;
-				try {
-					ss = adapter.listenUsingInsecureRfcommWithServiceRecord(
-							"RFCOMM", getUuid());
-				} catch (IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					return;
-				}
-				if (!isRunning()) {
-					tryToClose(ss);
-					return;
-				}
-				LOG.info("Socket bound");
-				socket = ss;
-				backoff.reset();
-				callback.transportEnabled();
-				acceptContactConnections();
+		ioExecutor.execute(() -> {
+			if (!isRunning()) return;
+			String address = AndroidUtils.getBluetoothAddress(appContext,
+					adapter);
+			if (LOG.isLoggable(INFO))
+				LOG.info("Local address " + scrubMacAddress(address));
+			if (!StringUtils.isNullOrEmpty(address)) {
+				// Advertise the Bluetooth address to contacts
+				TransportProperties p = new TransportProperties();
+				p.put(PROP_ADDRESS, address);
+				callback.mergeLocalProperties(p);
+			}
+			// Bind a server socket to accept connections from contacts
+			BluetoothServerSocket ss;
+			try {
+				ss = adapter.listenUsingInsecureRfcommWithServiceRecord(
+						"RFCOMM", getUuid());
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				return;
 			}
+			if (!isRunning()) {
+				tryToClose(ss);
+				return;
+			}
+			LOG.info("Socket bound");
+			socket = ss;
+			backoff.reset();
+			callback.transportEnabled();
+			acceptContactConnections();
 		});
 	}
 
@@ -300,15 +291,12 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
 			if (StringUtils.isNullOrEmpty(address)) continue;
 			final String uuid = e.getValue().get(PROP_UUID);
 			if (StringUtils.isNullOrEmpty(uuid)) continue;
-			ioExecutor.execute(new Runnable() {
-				@Override
-				public void run() {
-					if (!running) return;
-					BluetoothSocket s = connect(address, uuid);
-					if (s != null) {
-						backoff.reset();
-						callback.outgoingConnectionCreated(c, wrapSocket(s));
-					}
+			ioExecutor.execute(() -> {
+				if (!running) return;
+				BluetoothSocket s = connect(address, uuid);
+				if (s != null) {
+					backoff.reset();
+					callback.outgoingConnectionCreated(c, wrapSocket(s));
 				}
 			});
 		}
@@ -438,21 +426,11 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
 	}
 
 	private void enableAdapterAsync() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				enableAdapter();
-			}
-		});
+		ioExecutor.execute(this::enableAdapter);
 	}
 
 	private void disableAdapterAsync() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				disableAdapter();
-			}
-		});
+		ioExecutor.execute(this::disableAdapter);
 	}
 
 	private class BluetoothStateReceiver extends BroadcastReceiver {
@@ -490,16 +468,13 @@ class DroidtoothPlugin implements DuplexPlugin, EventListener {
 
 		@Override
 		public Callable<KeyAgreementConnection> listen() {
-			return new Callable<KeyAgreementConnection>() {
-				@Override
-				public KeyAgreementConnection call() throws IOException {
-					BluetoothSocket s = ss.accept();
-					if (LOG.isLoggable(INFO))
-						LOG.info(ID.getString() + ": Incoming connection");
-					return new KeyAgreementConnection(
-							new DroidtoothTransportConnection(
-									DroidtoothPlugin.this, s), ID);
-				}
+			return () -> {
+				BluetoothSocket s = ss.accept();
+				if (LOG.isLoggable(INFO))
+					LOG.info(ID.getString() + ": Incoming connection");
+				return new KeyAgreementConnection(
+						new DroidtoothTransportConnection(
+								DroidtoothPlugin.this, s), ID);
 			};
 		}
 
diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java
index 5322532a2c..797eb048c3 100644
--- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java
+++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java
@@ -370,57 +370,45 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
 	}
 
 	private void sendDevReports() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				// TODO: Trigger this with a TransportEnabledEvent
-				File reportDir = AndroidUtils.getReportDir(appContext);
-				reporter.sendReports(reportDir);
-			}
+		ioExecutor.execute(() -> {
+			// TODO: Trigger this with a TransportEnabledEvent
+			File reportDir = AndroidUtils.getReportDir(appContext);
+			reporter.sendReports(reportDir);
 		});
 	}
 
 	private void bind() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				// If there's already a port number stored in config, reuse it
-				String portString = callback.getSettings().get(PREF_TOR_PORT);
-				int port;
-				if (StringUtils.isNullOrEmpty(portString)) port = 0;
-				else port = Integer.parseInt(portString);
-				// Bind a server socket to receive connections from Tor
-				ServerSocket ss = null;
-				try {
-					ss = new ServerSocket();
-					ss.bind(new InetSocketAddress("127.0.0.1", port));
-				} catch (IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					tryToClose(ss);
-					return;
-				}
-				if (!running) {
-					tryToClose(ss);
-					return;
-				}
-				socket = ss;
-				// Store the port number
-				final String localPort = String.valueOf(ss.getLocalPort());
-				Settings s = new Settings();
-				s.put(PREF_TOR_PORT, localPort);
-				callback.mergeSettings(s);
-				// Create a hidden service if necessary
-				ioExecutor.execute(new Runnable() {
-					@Override
-					public void run() {
-						publishHiddenService(localPort);
-					}
-				});
-				backoff.reset();
-				// Accept incoming hidden service connections from Tor
-				acceptContactConnections(ss);
+		ioExecutor.execute(() -> {
+			// If there's already a port number stored in config, reuse it
+			String portString = callback.getSettings().get(PREF_TOR_PORT);
+			int port;
+			if (StringUtils.isNullOrEmpty(portString)) port = 0;
+			else port = Integer.parseInt(portString);
+			// Bind a server socket to receive connections from Tor
+			ServerSocket ss = null;
+			try {
+				ss = new ServerSocket();
+				ss.bind(new InetSocketAddress("127.0.0.1", port));
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				tryToClose(ss);
+				return;
+			}
+			if (!running) {
+				tryToClose(ss);
+				return;
 			}
+			socket = ss;
+			// Store the port number
+			final String localPort = String.valueOf(ss.getLocalPort());
+			Settings s = new Settings();
+			s.put(PREF_TOR_PORT, localPort);
+			callback.mergeSettings(s);
+			// Create a hidden service if necessary
+			ioExecutor.execute(() -> publishHiddenService(localPort));
+			backoff.reset();
+			// Accept incoming hidden service connections from Tor
+			acceptContactConnections(ss);
 		});
 	}
 
@@ -550,15 +538,12 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
 
 	private void connectAndCallBack(final ContactId c,
 			final TransportProperties p) {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!isRunning()) return;
-				DuplexTransportConnection d = createConnection(p);
-				if (d != null) {
-					backoff.reset();
-					callback.outgoingConnectionCreated(c, d);
-				}
+		ioExecutor.execute(() -> {
+			if (!isRunning()) return;
+			DuplexTransportConnection d = createConnection(p);
+			if (d != null) {
+				backoff.reset();
+				callback.outgoingConnectionCreated(c, d);
 			}
 		});
 	}
@@ -691,48 +676,43 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
 	}
 
 	private void updateConnectionStatus() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!running) return;
-
-				Object o = appContext.getSystemService(CONNECTIVITY_SERVICE);
-				ConnectivityManager cm = (ConnectivityManager) o;
-				NetworkInfo net = cm.getActiveNetworkInfo();
-				boolean online = net != null && net.isConnected();
-				boolean wifi = online && net.getType() == TYPE_WIFI;
-				String country = locationUtils.getCurrentCountry();
-				boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(
-						country);
-				Settings s = callback.getSettings();
-				int network = s.getInt(PREF_TOR_NETWORK,
-						PREF_TOR_NETWORK_ALWAYS);
-
-				if (LOG.isLoggable(INFO)) {
-					LOG.info("Online: " + online + ", wifi: " + wifi);
-					if ("".equals(country)) LOG.info("Country code unknown");
-					else LOG.info("Country code: " + country);
-				}
+		ioExecutor.execute(() -> {
+			if (!running) return;
+
+			Object o = appContext.getSystemService(CONNECTIVITY_SERVICE);
+			ConnectivityManager cm = (ConnectivityManager) o;
+			NetworkInfo net = cm.getActiveNetworkInfo();
+			boolean online = net != null && net.isConnected();
+			boolean wifi = online && net.getType() == TYPE_WIFI;
+			String country = locationUtils.getCurrentCountry();
+			boolean blocked = TorNetworkMetadata.isTorProbablyBlocked(
+					country);
+			Settings s = callback.getSettings();
+			int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS);
 
-				try {
-					if (!online) {
-						LOG.info("Disabling network, device is offline");
-						enableNetwork(false);
-					} else if (blocked) {
-						LOG.info("Disabling network, country is blocked");
-						enableNetwork(false);
-					} else if (network == PREF_TOR_NETWORK_NEVER
-							|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) {
-						LOG.info("Disabling network due to data setting");
-						enableNetwork(false);
-					} else {
-						LOG.info("Enabling network");
-						enableNetwork(true);
-					}
-				} catch (IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+			if (LOG.isLoggable(INFO)) {
+				LOG.info("Online: " + online + ", wifi: " + wifi);
+				if ("".equals(country)) LOG.info("Country code unknown");
+				else LOG.info("Country code: " + country);
+			}
+
+			try {
+				if (!online) {
+					LOG.info("Disabling network, device is offline");
+					enableNetwork(false);
+				} else if (blocked) {
+					LOG.info("Disabling network, country is blocked");
+					enableNetwork(false);
+				} else if (network == PREF_TOR_NETWORK_NEVER
+						|| (network == PREF_TOR_NETWORK_WIFI && !wifi)) {
+					LOG.info("Disabling network due to data setting");
+					enableNetwork(false);
+				} else {
+					LOG.info("Enabling network");
+					enableNetwork(true);
 				}
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
diff --git a/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidExecutorImpl.java b/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidExecutorImpl.java
index f07b2d721f..fb7fb701bc 100644
--- a/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidExecutorImpl.java
+++ b/bramble-android/src/main/java/org/briarproject/bramble/system/AndroidExecutorImpl.java
@@ -27,14 +27,11 @@ class AndroidExecutorImpl implements AndroidExecutor {
 	@Inject
 	AndroidExecutorImpl(Application app) {
 		uiHandler = new Handler(app.getApplicationContext().getMainLooper());
-		loop = new Runnable() {
-			@Override
-			public void run() {
-				Looper.prepare();
-				backgroundHandler = new Handler();
-				startLatch.countDown();
-				Looper.loop();
-			}
+		loop = () -> {
+			Looper.prepare();
+			backgroundHandler = new Handler();
+			startLatch.countDown();
+			Looper.loop();
 		};
 	}
 
diff --git a/bramble-api/src/test/java/org/briarproject/bramble/test/BrambleTestCase.java b/bramble-api/src/test/java/org/briarproject/bramble/test/BrambleTestCase.java
index aa0eb55e50..9fae780434 100644
--- a/bramble-api/src/test/java/org/briarproject/bramble/test/BrambleTestCase.java
+++ b/bramble-api/src/test/java/org/briarproject/bramble/test/BrambleTestCase.java
@@ -8,12 +8,9 @@ public abstract class BrambleTestCase {
 
 	public BrambleTestCase() {
 		// Ensure exceptions thrown on worker threads cause tests to fail
-		UncaughtExceptionHandler fail = new UncaughtExceptionHandler() {
-			@Override
-			public void uncaughtException(Thread thread, Throwable throwable) {
-				throwable.printStackTrace();
-				fail();
-			}
+		UncaughtExceptionHandler fail = (thread, throwable) -> {
+			throwable.printStackTrace();
+			fail();
 		};
 		Thread.setDefaultUncaughtExceptionHandler(fail);
 	}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/PoliteExecutor.java b/bramble-core/src/main/java/org/briarproject/bramble/PoliteExecutor.java
index 77bb4c587d..72e52b0c73 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/PoliteExecutor.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/PoliteExecutor.java
@@ -50,18 +50,15 @@ public class PoliteExecutor implements Executor {
 	@Override
 	public void execute(final Runnable r) {
 		final long submitted = System.currentTimeMillis();
-		Runnable wrapped = new Runnable() {
-			@Override
-			public void run() {
-				if (log.isLoggable(LOG_LEVEL)) {
-					long queued = System.currentTimeMillis() - submitted;
-					log.log(LOG_LEVEL, "Queue time " + queued + " ms");
-				}
-				try {
-					r.run();
-				} finally {
-					scheduleNext();
-				}
+		Runnable wrapped = () -> {
+			if (log.isLoggable(LOG_LEVEL)) {
+				long queued = System.currentTimeMillis() - submitted;
+				log.log(LOG_LEVEL, "Queue time " + queued + " ms");
+			}
+			try {
+				r.run();
+			} finally {
+				scheduleNext();
 			}
 		};
 		synchronized (lock) {
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java b/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java
index e7385f59b0..9c3be97798 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/TimeLoggingExecutor.java
@@ -31,16 +31,13 @@ public class TimeLoggingExecutor extends ThreadPoolExecutor {
 	public void execute(final Runnable r) {
 		if (log.isLoggable(LOG_LEVEL)) {
 			final long submitted = System.currentTimeMillis();
-			super.execute(new Runnable() {
-				@Override
-				public void run() {
-					long started = System.currentTimeMillis();
-					long queued = started - submitted;
-					log.log(LOG_LEVEL, "Queue time " + queued + " ms");
-					r.run();
-					long executing = System.currentTimeMillis() - started;
-					log.log(LOG_LEVEL, "Execution time " + executing + " ms");
-				}
+			super.execute(() -> {
+				long started = System.currentTimeMillis();
+				long queued = started - submitted;
+				log.log(LOG_LEVEL, "Queue time " + queued + " ms");
+				r.run();
+				long executing = System.currentTimeMillis() - started;
+				log.log(LOG_LEVEL, "Execution time " + executing + " ms");
 			});
 		} else {
 			super.execute(r);
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
index e31848e7bf..86942bd89f 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
@@ -103,15 +103,11 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 
 	@Override
 	public boolean open() throws DbException {
-		Runnable shutdownHook = new Runnable() {
-			@Override
-			public void run() {
-				try {
-					close();
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		Runnable shutdownHook = () -> {
+			try {
+				close();
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		};
 		boolean reopened = db.open();
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java
index 3714e420ff..8c0063b91d 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/ConnectionManagerImpl.java
@@ -266,12 +266,7 @@ class ConnectionManagerImpl implements ConnectionManager {
 			contactId = ctx.getContactId();
 			connectionRegistry.registerConnection(contactId, transportId, true);
 			// Start the outgoing session on another thread
-			ioExecutor.execute(new Runnable() {
-				@Override
-				public void run() {
-					runOutgoingSession();
-				}
-			});
+			ioExecutor.execute(this::runOutgoingSession);
 			try {
 				// Create and run the incoming session
 				incomingSession = createIncomingSession(ctx, reader);
@@ -368,12 +363,7 @@ class ConnectionManagerImpl implements ConnectionManager {
 				return;
 			}
 			// Start the incoming session on another thread
-			ioExecutor.execute(new Runnable() {
-				@Override
-				public void run() {
-					runIncomingSession();
-				}
-			});
+			ioExecutor.execute(this::runIncomingSession);
 			try {
 				// Create and run the outgoing session
 				outgoingSession = createDuplexOutgoingSession(ctx, writer);
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java
index 6413c459d7..1d985f3d9c 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/Poller.java
@@ -112,29 +112,23 @@ class Poller implements EventListener {
 	}
 
 	private void connectToContact(final ContactId c, final SimplexPlugin p) {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				TransportId t = p.getId();
-				if (!connectionRegistry.isConnected(c, t)) {
-					TransportConnectionWriter w = p.createWriter(c);
-					if (w != null)
-						connectionManager.manageOutgoingConnection(c, t, w);
-				}
+		ioExecutor.execute(() -> {
+			TransportId t = p.getId();
+			if (!connectionRegistry.isConnected(c, t)) {
+				TransportConnectionWriter w = p.createWriter(c);
+				if (w != null)
+					connectionManager.manageOutgoingConnection(c, t, w);
 			}
 		});
 	}
 
 	private void connectToContact(final ContactId c, final DuplexPlugin p) {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				TransportId t = p.getId();
-				if (!connectionRegistry.isConnected(c, t)) {
-					DuplexTransportConnection d = p.createConnection(c);
-					if (d != null)
-						connectionManager.manageOutgoingConnection(c, t, d);
-				}
+		ioExecutor.execute(() -> {
+			TransportId t = p.getId();
+			if (!connectionRegistry.isConnected(c, t)) {
+				DuplexTransportConnection d = p.createConnection(c);
+				if (d != null)
+					connectionManager.manageOutgoingConnection(c, t, d);
 			}
 		});
 	}
@@ -161,12 +155,8 @@ class Poller implements EventListener {
 			if (scheduled == null || due < scheduled.due) {
 				final PollTask task = new PollTask(p, due, randomiseNext);
 				tasks.put(t, task);
-				scheduler.schedule(new Runnable() {
-					@Override
-					public void run() {
-						ioExecutor.execute(task);
-					}
-				}, delay, MILLISECONDS);
+				scheduler.schedule(
+						() -> ioExecutor.execute(task), delay, MILLISECONDS);
 			}
 		} finally {
 			lock.unlock();
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java
index 78009a1ae1..7d26b8e5e0 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java
@@ -260,16 +260,12 @@ class LanTcpPlugin extends TcpPlugin {
 
 		@Override
 		public Callable<KeyAgreementConnection> listen() {
-			return new Callable<KeyAgreementConnection>() {
-				@Override
-				public KeyAgreementConnection call() throws IOException {
-					Socket s = ss.accept();
-					if (LOG.isLoggable(INFO))
-						LOG.info(ID.getString() + ": Incoming connection");
-					return new KeyAgreementConnection(
-							new TcpTransportConnection(LanTcpPlugin.this, s),
-							ID);
-				}
+			return () -> {
+				Socket s = ss.accept();
+				if (LOG.isLoggable(INFO))
+					LOG.info(ID.getString() + ": Incoming connection");
+				return new KeyAgreementConnection(
+						new TcpTransportConnection(LanTcpPlugin.this, s), ID);
 			};
 		}
 
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/PortMapperImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/PortMapperImpl.java
index 2156bd10d1..5790c1ae20 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/PortMapperImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/PortMapperImpl.java
@@ -50,12 +50,7 @@ class PortMapperImpl implements PortMapper {
 			succeeded = gateway.addPortMapping(port, port,
 					getHostAddress(internal), "TCP", "TCP");
 			if (succeeded) {
-				shutdownManager.addShutdownHook(new Runnable() {
-					@Override
-					public void run() {
-						deleteMapping(port);
-					}
-				});
+				shutdownManager.addShutdownHook(() -> deleteMapping(port));
 			}
 			String externalString = gateway.getExternalIPAddress();
 			if (LOG.isLoggable(INFO))
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java
index de913f2eb1..7ee44b4469 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/TcpPlugin.java
@@ -110,41 +110,37 @@ abstract class TcpPlugin implements DuplexPlugin {
 	}
 
 	protected void bind() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!running) return;
-				ServerSocket ss = null;
-				for (InetSocketAddress addr : getLocalSocketAddresses()) {
-					try {
-						ss = new ServerSocket();
-						ss.bind(addr);
-						break;
-					} catch (IOException e) {
-						if (LOG.isLoggable(INFO))
-							LOG.info("Failed to bind " +
-									scrubSocketAddress(addr));
-						tryToClose(ss);
-					}
-				}
-				if (ss == null || !ss.isBound()) {
-					LOG.info("Could not bind server socket");
-					return;
-				}
-				if (!running) {
+		ioExecutor.execute(() -> {
+			if (!running) return;
+			ServerSocket ss = null;
+			for (InetSocketAddress addr : getLocalSocketAddresses()) {
+				try {
+					ss = new ServerSocket();
+					ss.bind(addr);
+					break;
+				} catch (IOException e) {
+					if (LOG.isLoggable(INFO))
+						LOG.info("Failed to bind " + scrubSocketAddress(addr));
 					tryToClose(ss);
-					return;
 				}
-				socket = ss;
-				backoff.reset();
-				InetSocketAddress local =
-						(InetSocketAddress) ss.getLocalSocketAddress();
-				setLocalSocketAddress(local);
-				if (LOG.isLoggable(INFO))
-					LOG.info("Listening on " + scrubSocketAddress(local));
-				callback.transportEnabled();
-				acceptContactConnections();
 			}
+			if (ss == null || !ss.isBound()) {
+				LOG.info("Could not bind server socket");
+				return;
+			}
+			if (!running) {
+				tryToClose(ss);
+				return;
+			}
+			socket = ss;
+			backoff.reset();
+			InetSocketAddress local =
+					(InetSocketAddress) ss.getLocalSocketAddress();
+			setLocalSocketAddress(local);
+			if (LOG.isLoggable(INFO))
+				LOG.info("Listening on " + scrubSocketAddress(local));
+			callback.transportEnabled();
+			acceptContactConnections();
 		});
 	}
 
@@ -220,15 +216,12 @@ abstract class TcpPlugin implements DuplexPlugin {
 
 	private void connectAndCallBack(final ContactId c,
 			final TransportProperties p) {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!isRunning()) return;
-				DuplexTransportConnection d = createConnection(p);
-				if (d != null) {
-					backoff.reset();
-					callback.outgoingConnectionCreated(c, d);
-				}
+		ioExecutor.execute(() -> {
+			if (!isRunning()) return;
+			DuplexTransportConnection d = createConnection(p);
+			if (d != null) {
+				backoff.reset();
+				callback.outgoingConnectionCreated(c, d);
 			}
 		});
 	}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/reliability/ReliabilityLayerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/reliability/ReliabilityLayerImpl.java
index f1ede3ac91..ea730b64fb 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/reliability/ReliabilityLayerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/reliability/ReliabilityLayerImpl.java
@@ -54,36 +54,32 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
 		inputStream = new ReceiverInputStream(receiver);
 		outputStream = new SenderOutputStream(sender);
 		running = true;
-		executor.execute(new Runnable() {
-			@Override
-			public void run() {
-				long now = clock.currentTimeMillis();
-				long next = now + TICK_INTERVAL;
-				try {
-					while (running) {
-						byte[] b = null;
-						while (now < next && b == null) {
-							b = writes.poll(next - now, MILLISECONDS);
-							if (!running) return;
-							now = clock.currentTimeMillis();
-						}
-						if (b == null) {
-							sender.tick();
-							while (next <= now) next += TICK_INTERVAL;
-						} else {
-							if (b.length == 0) return; // Poison pill
-							writeHandler.handleWrite(b);
-						}
+		executor.execute(() -> {
+			long now = clock.currentTimeMillis();
+			long next = now + TICK_INTERVAL;
+			try {
+				while (running) {
+					byte[] b = null;
+					while (now < next && b == null) {
+						b = writes.poll(next - now, MILLISECONDS);
+						if (!running) return;
+						now = clock.currentTimeMillis();
+					}
+					if (b == null) {
+						sender.tick();
+						while (next <= now) next += TICK_INTERVAL;
+					} else {
+						if (b.length == 0) return; // Poison pill
+						writeHandler.handleWrite(b);
 					}
-				} catch (InterruptedException e) {
-					LOG.warning("Interrupted while waiting to write");
-					Thread.currentThread().interrupt();
-					running = false;
-				} catch (IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					running = false;
 				}
+			} catch (InterruptedException e) {
+				LOG.warning("Interrupted while waiting to write");
+				Thread.currentThread().interrupt();
+				running = false;
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				running = false;
 			}
 		});
 	}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/sync/DuplexOutgoingSession.java b/bramble-core/src/main/java/org/briarproject/bramble/sync/DuplexOutgoingSession.java
index 07ecfd566e..04f864d13a 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/sync/DuplexOutgoingSession.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/sync/DuplexOutgoingSession.java
@@ -54,12 +54,7 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
 	private static final Logger LOG =
 			Logger.getLogger(DuplexOutgoingSession.class.getName());
 
-	private static final ThrowingRunnable<IOException> CLOSE =
-			new ThrowingRunnable<IOException>() {
-				@Override
-				public void run() {
-				}
-			};
+	private static final ThrowingRunnable<IOException> CLOSE = () -> {};
 
 	private final DatabaseComponent db;
 	private final Executor dbExecutor;
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/sync/SimplexOutgoingSession.java b/bramble-core/src/main/java/org/briarproject/bramble/sync/SimplexOutgoingSession.java
index bc1dc339ab..3d0ecae22b 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/sync/SimplexOutgoingSession.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/sync/SimplexOutgoingSession.java
@@ -43,12 +43,7 @@ class SimplexOutgoingSession implements SyncSession, EventListener {
 	private static final Logger LOG =
 			Logger.getLogger(SimplexOutgoingSession.class.getName());
 
-	private static final ThrowingRunnable<IOException> CLOSE =
-			new ThrowingRunnable<IOException>() {
-				@Override
-				public void run() {
-				}
-			};
+	private static final ThrowingRunnable<IOException> CLOSE = () -> {};
 
 	private final DatabaseComponent db;
 	private final Executor dbExecutor;
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/sync/ValidationManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/sync/ValidationManagerImpl.java
index 74230834d5..291605a785 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/sync/ValidationManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/sync/ValidationManagerImpl.java
@@ -94,12 +94,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 	}
 
 	private void validateOutstandingMessagesAsync(final ClientId c) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				validateOutstandingMessages(c);
-			}
-		});
+		dbExecutor.execute(() -> validateOutstandingMessages(c));
 	}
 
 	@DatabaseExecutor
@@ -121,12 +116,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 
 	private void validateNextMessageAsync(final Queue<MessageId> unvalidated) {
 		if (unvalidated.isEmpty()) return;
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				validateNextMessage(unvalidated);
-			}
-		});
+		dbExecutor.execute(() -> validateNextMessage(unvalidated));
 	}
 
 	@DatabaseExecutor
@@ -159,12 +149,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 	}
 
 	private void deliverOutstandingMessagesAsync(final ClientId c) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				deliverOutstandingMessages(c);
-			}
-		});
+		dbExecutor.execute(() -> deliverOutstandingMessages(c));
 	}
 
 	@DatabaseExecutor
@@ -187,12 +172,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 	private void deliverNextPendingMessageAsync(
 			final Queue<MessageId> pending) {
 		if (pending.isEmpty()) return;
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				deliverNextPendingMessage(pending);
-			}
-		});
+		dbExecutor.execute(() -> deliverNextPendingMessage(pending));
 	}
 
 	@DatabaseExecutor
@@ -255,12 +235,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 	}
 
 	private void validateMessageAsync(final Message m, final Group g) {
-		validationExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				validateMessage(m, g);
-			}
-		});
+		validationExecutor.execute(() -> validateMessage(m, g));
 	}
 
 	@ValidationExecutor
@@ -285,12 +260,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 
 	private void storeMessageContextAsync(final Message m, final ClientId c,
 			final MessageContext result) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				storeMessageContext(m, c, result);
-			}
-		});
+		dbExecutor.execute(() -> storeMessageContext(m, c, result));
 	}
 
 	@DatabaseExecutor
@@ -385,12 +355,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 	}
 
 	private void shareOutstandingMessagesAsync(final ClientId c) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				shareOutstandingMessages(c);
-			}
-		});
+		dbExecutor.execute(() -> shareOutstandingMessages(c));
 	}
 
 	@DatabaseExecutor
@@ -418,12 +383,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 	 */
 	private void shareNextMessageAsync(final Queue<MessageId> toShare) {
 		if (toShare.isEmpty()) return;
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				shareNextMessage(toShare);
-			}
-		});
+		dbExecutor.execute(() -> shareNextMessage(toShare));
 	}
 
 	@DatabaseExecutor
@@ -452,12 +412,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 
 	private void invalidateNextMessageAsync(final Queue<MessageId> invalidate) {
 		if (invalidate.isEmpty()) return;
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				invalidateNextMessage(invalidate);
-			}
-		});
+		dbExecutor.execute(() -> invalidateNextMessage(invalidate));
 	}
 
 	@DatabaseExecutor
@@ -513,12 +468,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
 	}
 
 	private void loadGroupAndValidateAsync(final Message m) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				loadGroupAndValidate(m);
-			}
-		});
+		dbExecutor.execute(() -> loadGroupAndValidate(m));
 	}
 
 	@DatabaseExecutor
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java
index ee51fcb664..04d1fdbb2e 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/KeyManagerImpl.java
@@ -157,12 +157,8 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
 
 	private void removeContact(final ContactId c) {
 		activeContacts.remove(c);
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				for (TransportKeyManager m : managers.values())
-					m.removeContact(c);
-			}
+		dbExecutor.execute(() -> {
+			for (TransportKeyManager m : managers.values()) m.removeContact(c);
 		});
 	}
 }
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java
index cb69bb1155..95e49f5534 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/TransportKeyManagerImpl.java
@@ -134,32 +134,22 @@ class TransportKeyManagerImpl implements TransportKeyManager {
 	}
 
 	private void scheduleKeyRotation(long now) {
-		Runnable task = new Runnable() {
-			@Override
-			public void run() {
-				rotateKeys();
-			}
-		};
 		long delay = rotationPeriodLength - now % rotationPeriodLength;
-		scheduler.schedule(task, delay, MILLISECONDS);
+		scheduler.schedule((Runnable) this::rotateKeys, delay, MILLISECONDS);
 	}
 
 	private void rotateKeys() {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
+		dbExecutor.execute(() -> {
+			try {
+				Transaction txn = db.startTransaction(false);
 				try {
-					Transaction txn = db.startTransaction(false);
-					try {
-						rotateKeys(txn);
-						db.commitTransaction(txn);
-					} finally {
-						db.endTransaction(txn);
-					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+					rotateKeys(txn);
+					db.commitTransaction(txn);
+				} finally {
+					db.endTransaction(txn);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/PoliteExecutorTest.java b/bramble-core/src/test/java/org/briarproject/bramble/PoliteExecutorTest.java
index 2b1c81154f..fbd12ae79e 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/PoliteExecutorTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/PoliteExecutorTest.java
@@ -28,12 +28,9 @@ public class PoliteExecutorTest extends BrambleTestCase {
 		final CountDownLatch latch = new CountDownLatch(TASKS);
 		for (int i = 0; i < TASKS; i++) {
 			final int result = i;
-			polite.execute(new Runnable() {
-				@Override
-				public void run() {
-					list.add(result);
-					latch.countDown();
-				}
+			polite.execute(() -> {
+				list.add(result);
+				latch.countDown();
 			});
 		}
 		// Wait for all the tasks to finish
@@ -53,12 +50,9 @@ public class PoliteExecutorTest extends BrambleTestCase {
 		final CountDownLatch latch = new CountDownLatch(TASKS);
 		for (int i = 0; i < TASKS; i++) {
 			final int result = i;
-			polite.execute(new Runnable() {
-				@Override
-				public void run() {
-					list.add(result);
-					latch.countDown();
-				}
+			polite.execute(() -> {
+				list.add(result);
+				latch.countDown();
 			});
 		}
 		// Wait for all the tasks to finish
@@ -78,18 +72,15 @@ public class PoliteExecutorTest extends BrambleTestCase {
 		for (int i = 0; i < TASKS; i++) latches[i] = new CountDownLatch(1);
 		for (int i = 0; i < TASKS; i++) {
 			final int result = i;
-			polite.execute(new Runnable() {
-				@Override
-				public void run() {
-					try {
-						// Each task waits for the next task, if any, to finish
-						if (result < TASKS - 1) latches[result + 1].await();
-						list.add(result);
-					} catch (InterruptedException e) {
-						fail();
-					}
-					latches[result].countDown();
+			polite.execute(() -> {
+				try {
+					// Each task waits for the next task, if any, to finish
+					if (result < TASKS - 1) latches[result + 1].await();
+					list.add(result);
+				} catch (InterruptedException e) {
+					fail();
 				}
+				latches[result].countDown();
 			});
 		}
 		// Wait for all the tasks to finish
@@ -108,18 +99,15 @@ public class PoliteExecutorTest extends BrambleTestCase {
 		final CountDownLatch latch = new CountDownLatch(TASKS);
 		for (int i = 0; i < TASKS; i++) {
 			final int result = i;
-			polite.execute(new Runnable() {
-				@Override
-				public void run() {
-					try {
-						// Each task runs faster than the previous task
-						Thread.sleep(TASKS - result);
-						list.add(result);
-					} catch (InterruptedException e) {
-						fail();
-					}
-					latch.countDown();
+			polite.execute(() -> {
+				try {
+					// Each task runs faster than the previous task
+					Thread.sleep(TASKS - result);
+					list.add(result);
+				} catch (InterruptedException e) {
+					fail();
 				}
+				latch.countDown();
 			});
 		}
 		// Wait for all the tasks to finish
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/ShutdownManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/ShutdownManagerImplTest.java
index b7bfad2e62..a4d439b241 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/ShutdownManagerImplTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/ShutdownManagerImplTest.java
@@ -17,11 +17,7 @@ public class ShutdownManagerImplTest extends BrambleTestCase {
 		ShutdownManager s = createShutdownManager();
 		Set<Integer> handles = new HashSet<>();
 		for (int i = 0; i < 100; i++) {
-			int handle = s.addShutdownHook(new Runnable() {
-				@Override
-				public void run() {
-				}
-			});
+			int handle = s.addShutdownHook(() -> {});
 			// The handles should all be distinct
 			assertTrue(handles.add(handle));
 		}
diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/lifecycle/WindowsShutdownManagerImpl.java b/bramble-j2se/src/main/java/org/briarproject/bramble/lifecycle/WindowsShutdownManagerImpl.java
index aac6a02199..b9312a1bab 100644
--- a/bramble-j2se/src/main/java/org/briarproject/bramble/lifecycle/WindowsShutdownManagerImpl.java
+++ b/bramble-j2se/src/main/java/org/briarproject/bramble/lifecycle/WindowsShutdownManagerImpl.java
@@ -113,17 +113,13 @@ class WindowsShutdownManagerImpl extends ShutdownManagerImpl {
 				final User32 user32 = (User32) Native.loadLibrary("user32",
 						User32.class, options);
 				// Create a callback to handle the WM_QUERYENDSESSION message
-				WindowProc proc = new WindowProc() {
-					@Override
-					public LRESULT callback(HWND hwnd, int msg, WPARAM wp,
-							LPARAM lp) {
-						if (msg == WM_QUERYENDSESSION) {
-							// It's safe to delay returning from this message
-							runShutdownHooks();
-						}
-						// Pass the message to the default window procedure
-						return user32.DefWindowProc(hwnd, msg, wp, lp);
+				WindowProc proc = (hwnd, msg, wp, lp) -> {
+					if (msg == WM_QUERYENDSESSION) {
+						// It's safe to delay returning from this message
+						runShutdownHooks();
 					}
+					// Pass the message to the default window procedure
+					return user32.DefWindowProc(hwnd, msg, wp, lp);
 				};
 				// Create a native window
 				HWND hwnd = user32.CreateWindowEx(0, "STATIC", "", WS_MINIMIZE,
diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java
index 22783756b2..ee48ad4168 100644
--- a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java
+++ b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/bluetooth/BluetoothPlugin.java
@@ -108,33 +108,30 @@ class BluetoothPlugin implements DuplexPlugin {
 	}
 
 	private void bind() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (!running) return;
-				// Advertise the Bluetooth address to contacts
-				TransportProperties p = new TransportProperties();
-				p.put(PROP_ADDRESS, localDevice.getBluetoothAddress());
-				callback.mergeLocalProperties(p);
-				// Bind a server socket to accept connections from contacts
-				String url = makeUrl("localhost", getUuid());
-				StreamConnectionNotifier ss;
-				try {
-					ss = (StreamConnectionNotifier) Connector.open(url);
-				} catch (IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					return;
-				}
-				if (!running) {
-					tryToClose(ss);
-					return;
-				}
-				socket = ss;
-				backoff.reset();
-				callback.transportEnabled();
-				acceptContactConnections(ss);
+		ioExecutor.execute(() -> {
+			if (!running) return;
+			// Advertise the Bluetooth address to contacts
+			TransportProperties p = new TransportProperties();
+			p.put(PROP_ADDRESS, localDevice.getBluetoothAddress());
+			callback.mergeLocalProperties(p);
+			// Bind a server socket to accept connections from contacts
+			String url = makeUrl("localhost", getUuid());
+			StreamConnectionNotifier ss;
+			try {
+				ss = (StreamConnectionNotifier) Connector.open(url);
+			} catch (IOException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				return;
+			}
+			if (!running) {
+				tryToClose(ss);
+				return;
 			}
+			socket = ss;
+			backoff.reset();
+			callback.transportEnabled();
+			acceptContactConnections(ss);
 		});
 	}
 
@@ -220,20 +217,18 @@ class BluetoothPlugin implements DuplexPlugin {
 			if (StringUtils.isNullOrEmpty(address)) continue;
 			final String uuid = e.getValue().get(PROP_UUID);
 			if (StringUtils.isNullOrEmpty(uuid)) continue;
-			ioExecutor.execute(new Runnable() {
-				@Override
-				public void run() {
-					if (!running) return;
-					StreamConnection s = connect(makeUrl(address, uuid));
-					if (s != null) {
-						backoff.reset();
-						callback.outgoingConnectionCreated(c, wrapSocket(s));
-					}
+			ioExecutor.execute(() -> {
+				if (!running) return;
+				StreamConnection s = connect(makeUrl(address, uuid));
+				if (s != null) {
+					backoff.reset();
+					callback.outgoingConnectionCreated(c, wrapSocket(s));
 				}
 			});
 		}
 	}
 
+	@Nullable
 	private StreamConnection connect(String url) {
 		if (LOG.isLoggable(INFO)) LOG.info("Connecting to " + url);
 		try {
@@ -341,16 +336,13 @@ class BluetoothPlugin implements DuplexPlugin {
 
 		@Override
 		public Callable<KeyAgreementConnection> listen() {
-			return new Callable<KeyAgreementConnection>() {
-				@Override
-				public KeyAgreementConnection call() throws Exception {
-					StreamConnection s = ss.acceptAndOpen();
-					if (LOG.isLoggable(INFO))
-						LOG.info(ID.getString() + ": Incoming connection");
-					return new KeyAgreementConnection(
-							new BluetoothTransportConnection(
-									BluetoothPlugin.this, s), ID);
-				}
+			return () -> {
+				StreamConnection s = ss.acceptAndOpen();
+				if (LOG.isLoggable(INFO))
+					LOG.info(ID.getString() + ": Incoming connection");
+				return new KeyAgreementConnection(
+						new BluetoothTransportConnection(
+								BluetoothPlugin.this, s), ID);
 			};
 		}
 
diff --git a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemImpl.java b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemImpl.java
index 4aff1d94c1..2ba97b1e2c 100644
--- a/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemImpl.java
+++ b/bramble-j2se/src/main/java/org/briarproject/bramble/plugin/modem/ModemImpl.java
@@ -390,15 +390,12 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 						lock.unlock();
 					}
 				} else if (s.equals("RING")) {
-					ioExecutor.execute(new Runnable() {
-						@Override
-						public void run() {
-							try {
-								answer();
-							} catch (IOException e) {
-								if (LOG.isLoggable(WARNING))
-									LOG.log(WARNING, e.toString(), e);
-							}
+					ioExecutor.execute(() -> {
+						try {
+							answer();
+						} catch (IOException e) {
+							if (LOG.isLoggable(WARNING))
+								LOG.log(WARNING, e.toString(), e);
 						}
 					});
 				}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java
index 329f7b9968..e86afcbdcf 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java
@@ -44,7 +44,6 @@ import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Future;
@@ -138,16 +137,13 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 	@Override
 	public void stopService() throws ServiceException {
 		// Clear all notifications
-		Future<Void> f = androidExecutor.runOnUiThread(new Callable<Void>() {
-			@Override
-			public Void call() {
-				clearContactNotification();
-				clearGroupMessageNotification();
-				clearForumPostNotification();
-				clearBlogPostNotification();
-				clearIntroductionSuccessNotification();
-				return null;
-			}
+		Future<Void> f = androidExecutor.runOnUiThread(() -> {
+			clearContactNotification();
+			clearGroupMessageNotification();
+			clearForumPostNotification();
+			clearBlogPostNotification();
+			clearIntroductionSuccessNotification();
+			return null;
 		});
 		try {
 			f.get();
@@ -236,44 +232,35 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 	}
 
 	private void loadSettings() {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		dbExecutor.execute(() -> {
+			try {
+				settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void showContactNotification(final ContactId c) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (blockContacts) return;
-				if (c.equals(blockedContact)) return;
-				Integer count = contactCounts.get(c);
-				if (count == null) contactCounts.put(c, 1);
-				else contactCounts.put(c, count + 1);
-				contactTotal++;
-				updateContactNotification(true);
-			}
+		androidExecutor.runOnUiThread(() -> {
+			if (blockContacts) return;
+			if (c.equals(blockedContact)) return;
+			Integer count = contactCounts.get(c);
+			if (count == null) contactCounts.put(c, 1);
+			else contactCounts.put(c, count + 1);
+			contactTotal++;
+			updateContactNotification(true);
 		});
 	}
 
 	@Override
 	public void clearContactNotification(final ContactId c) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				Integer count = contactCounts.remove(c);
-				if (count == null) return; // Already cleared
-				contactTotal -= count;
-				updateContactNotification(false);
-			}
+		androidExecutor.runOnUiThread(() -> {
+			Integer count = contactCounts.remove(c);
+			if (count == null) return; // Already cleared
+			contactTotal -= count;
+			updateContactNotification(false);
 		});
 	}
 
@@ -358,40 +345,30 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 
 	@Override
 	public void clearAllContactNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				clearContactNotification();
-			}
-		});
+		androidExecutor.runOnUiThread(
+				(Runnable) this::clearContactNotification);
 	}
 
 	@UiThread
 	private void showGroupMessageNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (blockGroups) return;
-				if (g.equals(blockedGroup)) return;
-				Integer count = groupCounts.get(g);
-				if (count == null) groupCounts.put(g, 1);
-				else groupCounts.put(g, count + 1);
-				groupTotal++;
-				updateGroupMessageNotification(true);
-			}
+		androidExecutor.runOnUiThread(() -> {
+			if (blockGroups) return;
+			if (g.equals(blockedGroup)) return;
+			Integer count = groupCounts.get(g);
+			if (count == null) groupCounts.put(g, 1);
+			else groupCounts.put(g, count + 1);
+			groupTotal++;
+			updateGroupMessageNotification(true);
 		});
 	}
 
 	@Override
 	public void clearGroupMessageNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				Integer count = groupCounts.remove(g);
-				if (count == null) return; // Already cleared
-				groupTotal -= count;
-				updateGroupMessageNotification(false);
-			}
+		androidExecutor.runOnUiThread(() -> {
+			Integer count = groupCounts.remove(g);
+			if (count == null) return; // Already cleared
+			groupTotal -= count;
+			updateGroupMessageNotification(false);
 		});
 	}
 
@@ -445,40 +422,30 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 
 	@Override
 	public void clearAllGroupMessageNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				clearGroupMessageNotification();
-			}
-		});
+		androidExecutor.runOnUiThread(
+				(Runnable) this::clearGroupMessageNotification);
 	}
 
 	@UiThread
 	private void showForumPostNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (blockForums) return;
-				if (g.equals(blockedGroup)) return;
-				Integer count = forumCounts.get(g);
-				if (count == null) forumCounts.put(g, 1);
-				else forumCounts.put(g, count + 1);
-				forumTotal++;
-				updateForumPostNotification(true);
-			}
+		androidExecutor.runOnUiThread(() -> {
+			if (blockForums) return;
+			if (g.equals(blockedGroup)) return;
+			Integer count = forumCounts.get(g);
+			if (count == null) forumCounts.put(g, 1);
+			else forumCounts.put(g, count + 1);
+			forumTotal++;
+			updateForumPostNotification(true);
 		});
 	}
 
 	@Override
 	public void clearForumPostNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				Integer count = forumCounts.remove(g);
-				if (count == null) return; // Already cleared
-				forumTotal -= count;
-				updateForumPostNotification(false);
-			}
+		androidExecutor.runOnUiThread(() -> {
+			Integer count = forumCounts.remove(g);
+			if (count == null) return; // Already cleared
+			forumTotal -= count;
+			updateForumPostNotification(false);
 		});
 	}
 
@@ -532,40 +499,30 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 
 	@Override
 	public void clearAllForumPostNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				clearForumPostNotification();
-			}
-		});
+		androidExecutor.runOnUiThread(
+				(Runnable) this::clearForumPostNotification);
 	}
 
 	@UiThread
 	private void showBlogPostNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (blockBlogs) return;
-				if (g.equals(blockedGroup)) return;
-				Integer count = blogCounts.get(g);
-				if (count == null) blogCounts.put(g, 1);
-				else blogCounts.put(g, count + 1);
-				blogTotal++;
-				updateBlogPostNotification(true);
-			}
+		androidExecutor.runOnUiThread(() -> {
+			if (blockBlogs) return;
+			if (g.equals(blockedGroup)) return;
+			Integer count = blogCounts.get(g);
+			if (count == null) blogCounts.put(g, 1);
+			else blogCounts.put(g, count + 1);
+			blogTotal++;
+			updateBlogPostNotification(true);
 		});
 	}
 
 	@Override
 	public void clearBlogPostNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				Integer count = blogCounts.remove(g);
-				if (count == null) return; // Already cleared
-				blogTotal -= count;
-				updateBlogPostNotification(false);
-			}
+		androidExecutor.runOnUiThread(() -> {
+			Integer count = blogCounts.remove(g);
+			if (count == null) return; // Already cleared
+			blogTotal -= count;
+			updateBlogPostNotification(false);
 		});
 	}
 
@@ -606,22 +563,15 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 
 	@Override
 	public void clearAllBlogPostNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				clearBlogPostNotification();
-			}
-		});
+		androidExecutor.runOnUiThread(
+				(Runnable) this::clearBlogPostNotification);
 	}
 
 	private void showIntroductionNotification() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (blockIntroductions) return;
-				introductionTotal++;
-				updateIntroductionNotification();
-			}
+		androidExecutor.runOnUiThread(() -> {
+			if (blockIntroductions) return;
+			introductionTotal++;
+			updateIntroductionNotification();
 		});
 	}
 
@@ -656,71 +606,41 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
 
 	@Override
 	public void clearAllIntroductionNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				clearIntroductionSuccessNotification();
-			}
-		});
+		androidExecutor.runOnUiThread(
+				this::clearIntroductionSuccessNotification);
 	}
 
 	@Override
 	public void blockNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				blockedGroup = g;
-			}
-		});
+		androidExecutor.runOnUiThread((Runnable) () -> blockedGroup = g);
 	}
 
 	@Override
 	public void unblockNotification(final GroupId g) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (g.equals(blockedGroup)) blockedGroup = null;
-			}
+		androidExecutor.runOnUiThread(() -> {
+			if (g.equals(blockedGroup)) blockedGroup = null;
 		});
 	}
 
 	@Override
 	public void blockContactNotification(final ContactId c) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				blockedContact = c;
-			}
-		});
+		androidExecutor.runOnUiThread((Runnable) () -> blockedContact = c);
 	}
 
 	@Override
 	public void unblockContactNotification(final ContactId c) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (c.equals(blockedContact)) blockedContact = null;
-			}
+		androidExecutor.runOnUiThread(() -> {
+			if (c.equals(blockedContact)) blockedContact = null;
 		});
 	}
 
 	@Override
 	public void blockAllBlogPostNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				blockBlogs = true;
-			}
-		});
+		androidExecutor.runOnUiThread((Runnable) () -> blockBlogs = true);
 	}
 
 	@Override
 	public void unblockAllBlogPostNotifications() {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				blockBlogs = false;
-			}
-		});
+		androidExecutor.runOnUiThread((Runnable) () -> blockBlogs = false);
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java
index 9c12a7ace5..576b00be5a 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java
@@ -112,33 +112,30 @@ public class BriarService extends Service {
 	}
 
 	private void showStartupFailureNotification(final StartResult result) {
-		androidExecutor.runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				NotificationCompat.Builder b =
-						new NotificationCompat.Builder(BriarService.this);
-				b.setSmallIcon(android.R.drawable.stat_notify_error);
-				b.setContentTitle(getText(
-						R.string.startup_failed_notification_title));
-				b.setContentText(getText(
-						R.string.startup_failed_notification_text));
-				Intent i = new Intent(BriarService.this,
-						StartupFailureActivity.class);
-				i.setFlags(FLAG_ACTIVITY_NEW_TASK);
-				i.putExtra("briar.START_RESULT", result);
-				i.putExtra("briar.FAILURE_NOTIFICATION_ID",
-						FAILURE_NOTIFICATION_ID);
-				b.setContentIntent(PendingIntent.getActivity(BriarService.this,
-						0, i, FLAG_UPDATE_CURRENT));
-				Object o = getSystemService(NOTIFICATION_SERVICE);
-				NotificationManager nm = (NotificationManager) o;
-				nm.notify(FAILURE_NOTIFICATION_ID, b.build());
-				// Bring the dashboard to the front to clear the back stack
-				i = new Intent(BriarService.this, NavDrawerActivity.class);
-				i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
-				i.putExtra("briar.STARTUP_FAILED", true);
-				startActivity(i);
-			}
+		androidExecutor.runOnUiThread(() -> {
+			NotificationCompat.Builder b =
+					new NotificationCompat.Builder(BriarService.this);
+			b.setSmallIcon(android.R.drawable.stat_notify_error);
+			b.setContentTitle(getText(
+					R.string.startup_failed_notification_title));
+			b.setContentText(getText(
+					R.string.startup_failed_notification_text));
+			Intent i = new Intent(BriarService.this,
+					StartupFailureActivity.class);
+			i.setFlags(FLAG_ACTIVITY_NEW_TASK);
+			i.putExtra("briar.START_RESULT", result);
+			i.putExtra("briar.FAILURE_NOTIFICATION_ID",
+					FAILURE_NOTIFICATION_ID);
+			b.setContentIntent(PendingIntent.getActivity(BriarService.this,
+					0, i, FLAG_UPDATE_CURRENT));
+			Object o = getSystemService(NOTIFICATION_SERVICE);
+			NotificationManager nm = (NotificationManager) o;
+			nm.notify(FAILURE_NOTIFICATION_ID, b.build());
+			// Bring the dashboard to the front to clear the back stack
+			i = new Intent(BriarService.this, NavDrawerActivity.class);
+			i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
+			i.putExtra("briar.STARTUP_FAILED", true);
+			startActivity(i);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java
index 628c9e646f..7bfd39fa5e 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BaseActivity.java
@@ -152,11 +152,8 @@ public abstract class BaseActivity extends AppCompatActivity
 
 	@Override
 	public void runOnUiThreadUnlessDestroyed(final Runnable r) {
-		runOnUiThread(new Runnable() {
-			@Override
-			public void run() {
-				if (!destroyed && !isFinishing()) r.run();
-			}
+		runOnUiThread(() -> {
+			if (!destroyed && !isFinishing()) r.run();
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java
index 33ed5bfc3a..663d8581f7 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java
@@ -13,7 +13,6 @@ import android.view.Window;
 import org.briarproject.briar.R;
 import org.briarproject.briar.android.controller.BriarController;
 import org.briarproject.briar.android.controller.DbController;
-import org.briarproject.briar.android.controller.handler.ResultHandler;
 import org.briarproject.briar.android.login.PasswordActivity;
 import org.briarproject.briar.android.panic.ExitActivity;
 
@@ -102,17 +101,8 @@ public abstract class BriarActivity extends BaseActivity {
 		if (briarController.hasEncryptionKey()) {
 			// Don't use UiResultHandler because we want the result even if
 			// this activity has been destroyed
-			briarController.signOut(new ResultHandler<Void>() {
-				@Override
-				public void onResult(Void result) {
-					runOnUiThread(new Runnable() {
-						@Override
-						public void run() {
-							exit(removeFromRecentApps);
-						}
-					});
-				}
-			});
+			briarController.signOut(result -> runOnUiThread(
+					() -> exit(removeFromRecentApps)));
 		} else {
 			exit(removeFromRecentApps);
 		}
@@ -146,11 +136,6 @@ public abstract class BriarActivity extends BaseActivity {
 
 	@Deprecated
 	protected void finishOnUiThread() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				supportFinishAfterTransition();
-			}
-		});
+		runOnUiThreadUnlessDestroyed(this::supportFinishAfterTransition);
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BaseControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BaseControllerImpl.java
index 457dd26fa1..cc326bef4b 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BaseControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BaseControllerImpl.java
@@ -85,38 +85,25 @@ abstract class BaseControllerImpl extends DbControllerImpl
 	}
 
 	void onBlogPostAdded(final BlogPostHeader h, final boolean local) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onBlogPostAdded(h, local);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onBlogPostAdded(h, local));
 	}
 
 	void onBlogRemoved() {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onBlogRemoved();
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogRemoved());
 	}
 
-
 	@Override
 	public void loadBlogPosts(final GroupId groupId,
 			final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<BlogPostItem> items = loadItems(groupId);
-					handler.onResult(items);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				Collection<BlogPostItem> items = loadItems(groupId);
+				handler.onResult(items);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -151,21 +138,18 @@ abstract class BaseControllerImpl extends DbControllerImpl
 			handler.onResult(new BlogPostItem(header, body));
 			return;
 		}
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					BlogPostItem item = getItem(header);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading body took " + duration + " ms");
-					handler.onResult(item);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				BlogPostItem item = getItem(header);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading body took " + duration + " ms");
+				handler.onResult(item);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -180,22 +164,19 @@ abstract class BaseControllerImpl extends DbControllerImpl
 			loadBlogPost(header, handler);
 			return;
 		}
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					BlogPostHeader header = getPostHeader(g, m);
-					BlogPostItem item = getItem(header);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading post took " + duration + " ms");
-					handler.onResult(item);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				BlogPostHeader header1 = getPostHeader(g, m);
+				BlogPostItem item = getItem(header1);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading post took " + duration + " ms");
+				handler.onResult(item);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -204,19 +185,16 @@ abstract class BaseControllerImpl extends DbControllerImpl
 	public void repeatPost(final BlogPostItem item,
 			final @Nullable String comment,
 			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor a = identityManager.getLocalAuthor();
-					Blog b = blogManager.getPersonalBlog(a);
-					BlogPostHeader h = item.getHeader();
-					blogManager.addLocalComment(a, b.getId(), comment, h);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor a = identityManager.getLocalAuthor();
+				Blog b = blogManager.getPersonalBlog(a);
+				BlogPostHeader h = item.getHeader();
+				blogManager.addLocalComment(a, b.getId(), comment, h);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java
index 222b7cae83..7817c5a3ae 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java
@@ -99,13 +99,10 @@ abstract class BasePostFragment extends BaseFragment {
 	}
 
 	private void startPeriodicUpdate() {
-		refresher = new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Updating Content...");
-				ui.updateDate(post.getTimestamp());
-				handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
-			}
+		refresher = () -> {
+			LOG.info("Updating Content...");
+			ui.updateDate(post.getTimestamp());
+			handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
 		};
 		LOG.info("Adding Handler Callback");
 		handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogActivity.java
index 5521b9bea4..dc4dff55d8 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogActivity.java
@@ -3,7 +3,6 @@ package org.briarproject.briar.android.blog;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.v7.widget.Toolbar;
-import android.view.View;
 
 import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
 import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
@@ -41,16 +40,12 @@ public class BlogActivity extends BriarActivity
 
 		// Open Sharing Status on Toolbar click
 		if (toolbar != null) {
-			toolbar.setOnClickListener(
-					new View.OnClickListener() {
-						@Override
-						public void onClick(View v) {
-							Intent i = new Intent(BlogActivity.this,
-									BlogSharingStatusActivity.class);
-							i.putExtra(GROUP_ID, groupId.getBytes());
-							startActivity(i);
-						}
-					});
+			toolbar.setOnClickListener(v -> {
+				Intent i1 = new Intent(BlogActivity.this,
+						BlogSharingStatusActivity.class);
+				i1.putExtra(GROUP_ID, groupId.getBytes());
+				startActivity(i1);
+			});
 		}
 
 		if (state == null) {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java
index 21d0856c22..de0e22356f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java
@@ -126,21 +126,12 @@ class BlogControllerImpl extends BaseControllerImpl
 	}
 
 	private void onBlogInvitationAccepted(final ContactId c) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onBlogInvitationAccepted(c);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onBlogInvitationAccepted(c));
 	}
 
 	private void onBlogLeft(final ContactId c) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onBlogLeft(c);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogLeft(c));
 	}
 
 	@Override
@@ -161,25 +152,22 @@ class BlogControllerImpl extends BaseControllerImpl
 	public void loadBlog(
 			final ResultExceptionHandler<BlogItem, DbException> handler) {
 		if (groupId == null) throw new IllegalStateException();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					LocalAuthor a = identityManager.getLocalAuthor();
-					Blog b = blogManager.getBlog(groupId);
-					boolean ours = a.getId().equals(b.getAuthor().getId());
-					boolean removable = blogManager.canBeRemoved(b);
-					BlogItem blog = new BlogItem(b, ours, removable);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading blog took " + duration + " ms");
-					handler.onResult(blog);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				LocalAuthor a = identityManager.getLocalAuthor();
+				Blog b = blogManager.getBlog(groupId);
+				boolean ours = a.getId().equals(b.getAuthor().getId());
+				boolean removable = blogManager.canBeRemoved(b);
+				BlogItem blog = new BlogItem(b, ours, removable);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading blog took " + duration + " ms");
+				handler.onResult(blog);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -188,22 +176,19 @@ class BlogControllerImpl extends BaseControllerImpl
 	public void deleteBlog(
 			final ResultExceptionHandler<Void, DbException> handler) {
 		if (groupId == null) throw new IllegalStateException();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Blog b = blogManager.getBlog(groupId);
-					blogManager.removeBlog(b);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Removing blog took " + duration + " ms");
-					handler.onResult(null);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Blog b = blogManager.getBlog(groupId);
+				blogManager.removeBlog(b);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Removing blog took " + duration + " ms");
+				handler.onResult(null);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -212,21 +197,18 @@ class BlogControllerImpl extends BaseControllerImpl
 	public void loadSharingContacts(
 			final ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
 		if (groupId == null) throw new IllegalStateException();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<Contact> contacts =
-							blogSharingManager.getSharedWith(groupId);
-					Collection<ContactId> contactIds =
-							new ArrayList<>(contacts.size());
-					for (Contact c : contacts) contactIds.add(c.getId());
-					handler.onResult(contactIds);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				Collection<Contact> contacts =
+						blogSharingManager.getSharedWith(groupId);
+				Collection<ContactId> contactIds =
+						new ArrayList<>(contacts.size());
+				for (Contact c : contacts) contactIds.add(c.getId());
+				handler.onResult(contactIds);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java
index d1fb275e55..b9ca60be5b 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogFragment.java
@@ -331,12 +331,7 @@ public class BlogFragment extends BaseFragment
 				Snackbar.make(list, stringId, Snackbar.LENGTH_LONG);
 		snackbar.getView().setBackgroundResource(R.color.briar_primary);
 		if (scroll) {
-			View.OnClickListener onClick = new View.OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					list.smoothScrollToPosition(0);
-				}
-			};
+			View.OnClickListener onClick = v -> list.smoothScrollToPosition(0);
 			snackbar.setActionTextColor(ContextCompat
 					.getColor(getContext(),
 							R.color.briar_button_positive));
@@ -347,12 +342,7 @@ public class BlogFragment extends BaseFragment
 
 	private void showDeleteDialog() {
 		DialogInterface.OnClickListener okListener =
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						deleteBlog();
-					}
-				};
+				(dialog, which) -> deleteBlog();
 		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),
 				R.style.BriarDialogTheme);
 		builder.setTitle(getString(R.string.blogs_remove_blog));
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogPostViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogPostViewHolder.java
index 484605f6e7..b76858c543 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogPostViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogPostViewHolder.java
@@ -13,7 +13,6 @@ import android.support.v7.widget.RecyclerView;
 import android.text.Spanned;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -95,12 +94,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 		setTransitionName(item.getId());
 		if (!fullText) {
 			layout.setClickable(true);
-			layout.setOnClickListener(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					listener.onBlogPostClick(item);
-				}
-			});
+			layout.setOnClickListener(v -> listener.onBlogPostClick(item));
 		}
 
 		// author and date
@@ -113,12 +107,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 				item.isRssFeed() ? AuthorView.RSS_FEED : AuthorView.NORMAL);
 		// TODO make author clickable more often #624
 		if (!fullText && item.getHeader().getType() == POST) {
-			author.setAuthorClickable(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					listener.onAuthorClick(item);
-				}
-			});
+			author.setAuthorClickable(v -> listener.onAuthorClick(item));
 		} else {
 			author.setAuthorNotClickable();
 		}
@@ -137,23 +126,20 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 		}
 
 		// reblog button
-		reblogButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				Intent i = new Intent(ctx, ReblogActivity.class);
-				i.putExtra(GROUP_ID, item.getGroupId().getBytes());
-				i.putExtra(POST_ID, item.getId().getBytes());
-
-				if (Build.VERSION.SDK_INT >= 23) {
-					ActivityOptionsCompat options =
-							makeSceneTransitionAnimation((Activity) ctx, layout,
-									getTransitionName(item.getId()));
-					ActivityCompat.startActivity((Activity) ctx, i,
-							options.toBundle());
-				} else {
-					// work-around for android bug #224270
-					ctx.startActivity(i);
-				}
+		reblogButton.setOnClickListener(v -> {
+			Intent i = new Intent(ctx, ReblogActivity.class);
+			i.putExtra(GROUP_ID, item.getGroupId().getBytes());
+			i.putExtra(POST_ID, item.getId().getBytes());
+
+			if (Build.VERSION.SDK_INT >= 23) {
+				ActivityOptionsCompat options =
+						makeSceneTransitionAnimation((Activity) ctx, layout,
+								getTransitionName(item.getId()));
+				ActivityCompat.startActivity((Activity) ctx, i,
+						options.toBundle());
+			} else {
+				// work-around for android bug #224270
+				ctx.startActivity(i);
 			}
 		});
 
@@ -172,12 +158,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 		reblogger.setAuthorStatus(item.getAuthorStatus());
 		reblogger.setDate(item.getTimestamp());
 		if (!fullText) {
-			reblogger.setAuthorClickable(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					listener.onAuthorClick(item);
-				}
-			});
+			reblogger.setAuthorClickable(v -> listener.onAuthorClick(item));
 		}
 		reblogger.setVisibility(VISIBLE);
 		reblogger.setPersona(AuthorView.REBLOGGER);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedControllerImpl.java
index 1d02c8fdc1..bd81d908be 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedControllerImpl.java
@@ -91,40 +91,31 @@ class FeedControllerImpl extends BaseControllerImpl
 	}
 
 	private void onBlogAdded() {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onBlogAdded();
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onBlogAdded());
 	}
 
 	@Override
 	public void loadBlogPosts(
 			final ResultExceptionHandler<Collection<BlogPostItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Collection<BlogPostItem> posts = new ArrayList<>();
-					for (Blog b : blogManager.getBlogs()) {
-						try {
-							posts.addAll(loadItems(b.getId()));
-						} catch (NoSuchGroupException | NoSuchMessageException e) {
-							if (LOG.isLoggable(WARNING))
-								LOG.log(WARNING, e.toString(), e);
-						}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Collection<BlogPostItem> posts = new ArrayList<>();
+				for (Blog b : blogManager.getBlogs()) {
+					try {
+						posts.addAll(loadItems(b.getId()));
+					} catch (NoSuchGroupException | NoSuchMessageException e) {
+						if (LOG.isLoggable(WARNING))
+							LOG.log(WARNING, e.toString(), e);
 					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading all posts took " + duration + " ms");
-					handler.onResult(posts);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading all posts took " + duration + " ms");
+				handler.onResult(posts);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -132,22 +123,18 @@ class FeedControllerImpl extends BaseControllerImpl
 	@Override
 	public void loadPersonalBlog(
 			final ResultExceptionHandler<Blog, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Author a = identityManager.getLocalAuthor();
-					Blog b = blogManager.getPersonalBlog(a);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading blog took " + duration + " ms");
-					handler.onResult(b);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Author a = identityManager.getLocalAuthor();
+				Blog b = blogManager.getPersonalBlog(a);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading blog took " + duration + " ms");
+				handler.onResult(b);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java
index 097de3921e..a3153ef4eb 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java
@@ -246,12 +246,7 @@ public class FeedFragment extends BaseFragment implements
 		Snackbar s = Snackbar.make(list, stringRes, LENGTH_LONG);
 		s.getView().setBackgroundResource(R.color.briar_primary);
 		if (scroll) {
-			OnClickListener onClick = new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					list.smoothScrollToPosition(0);
-				}
-			};
+			OnClickListener onClick = v -> list.smoothScrollToPosition(0);
 			s.setActionTextColor(ContextCompat
 					.getColor(getContext(),
 							R.color.briar_button_positive));
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/ReblogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/ReblogFragment.java
index 6029cd79f7..db6625bf7b 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/ReblogFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/ReblogFragment.java
@@ -114,12 +114,7 @@ public class ReblogFragment extends BaseFragment implements TextInputListener {
 
 		ui.input.setListener(this);
 		ui.input.setSendButtonEnabled(true);
-		ui.scrollView.post(new Runnable() {
-			@Override
-			public void run() {
-				ui.scrollView.fullScroll(FOCUS_DOWN);
-			}
-		});
+		ui.scrollView.post(() -> ui.scrollView.fullScroll(FOCUS_DOWN));
 	}
 
 	@Override
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java
index e4ed107b6a..d6727098b2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedAdapter.java
@@ -4,7 +4,6 @@ import android.content.Context;
 import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ImageButton;
 import android.widget.TextView;
@@ -42,12 +41,7 @@ class RssFeedAdapter extends BriarAdapter<Feed, RssFeedAdapter.FeedViewHolder> {
 		ui.title.setText(item.getTitle());
 
 		// Delete Button
-		ui.delete.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				listener.onDeleteClick(item);
-			}
-		});
+		ui.delete.setOnClickListener(v -> listener.onDeleteClick(item));
 
 		// Author
 		if (item.getAuthor() != null) {
@@ -72,12 +66,7 @@ class RssFeedAdapter extends BriarAdapter<Feed, RssFeedAdapter.FeedViewHolder> {
 		}
 
 		// Open feed's blog when clicked
-		ui.layout.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				listener.onFeedClick(item);
-			}
-		});
+		ui.layout.setOnClickListener(v -> listener.onFeedClick(item));
 	}
 
 	@Override
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java
index c382f1a8cb..bc20c8fe9c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.blog;
 
-import android.content.DialogInterface;
 import android.os.Bundle;
 import android.support.v7.app.AlertDialog;
 import android.text.Editable;
@@ -8,7 +7,6 @@ import android.text.TextWatcher;
 import android.util.Patterns;
 import android.view.Menu;
 import android.view.MenuItem;
-import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
@@ -75,12 +73,7 @@ public class RssFeedImportActivity extends BriarActivity {
 		});
 
 		importButton = (Button) findViewById(R.id.importButton);
-		importButton.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				publish();
-			}
-		});
+		importButton.setOnClickListener(v -> publish());
 
 		progressBar = (ProgressBar) findViewById(R.id.progressBar);
 	}
@@ -126,54 +119,37 @@ public class RssFeedImportActivity extends BriarActivity {
 	}
 
 	private void importFeed(final String url) {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					feedManager.addFeed(url);
-					feedImported();
-				} catch (DbException | IOException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					importFailed();
-				}
+		ioExecutor.execute(() -> {
+			try {
+				feedManager.addFeed(url);
+				feedImported();
+			} catch (DbException | IOException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				importFailed();
 			}
 		});
 	}
 
 	private void feedImported() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				supportFinishAfterTransition();
-			}
-		});
+		runOnUiThreadUnlessDestroyed(this::supportFinishAfterTransition);
 	}
 
 	private void importFailed() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				// hide progress bar, show publish button
-				progressBar.setVisibility(GONE);
-				importButton.setVisibility(VISIBLE);
-
-				// show error dialog
-				AlertDialog.Builder builder =
-						new AlertDialog.Builder(RssFeedImportActivity.this,
-								R.style.BriarDialogTheme);
-				builder.setMessage(R.string.blogs_rss_feeds_import_error);
-				builder.setNegativeButton(R.string.cancel, null);
-				builder.setPositiveButton(R.string.try_again_button,
-						new DialogInterface.OnClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog, int which) {
-								publish();
-							}
-						});
-				AlertDialog dialog = builder.create();
-				dialog.show();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			// hide progress bar, show publish button
+			progressBar.setVisibility(GONE);
+			importButton.setVisibility(VISIBLE);
+
+			// show error dialog
+			AlertDialog.Builder builder =
+					new AlertDialog.Builder(RssFeedImportActivity.this,
+							R.style.BriarDialogTheme);
+			builder.setMessage(R.string.blogs_rss_feeds_import_error);
+			builder.setNegativeButton(R.string.cancel, null);
+			builder.setPositiveButton(R.string.try_again_button,
+					(dialog, which) -> publish());
+			AlertDialog dialog = builder.create();
+			dialog.show();
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java
index 8525f1f653..b3edc82bdc 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java
@@ -105,12 +105,7 @@ public class RssFeedManageActivity extends BriarActivity
 	@Override
 	public void onDeleteClick(final Feed feed) {
 		DialogInterface.OnClickListener okListener =
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						deleteFeed(feed);
-					}
-				};
+				(dialog, which) -> deleteFeed(feed);
 		AlertDialog.Builder builder = new AlertDialog.Builder(this,
 				R.style.BriarDialogTheme);
 		builder.setTitle(getString(R.string.blogs_rss_remove_feed));
@@ -124,81 +119,59 @@ public class RssFeedManageActivity extends BriarActivity
 
 	private void loadFeeds() {
 		final int revision = adapter.getRevision();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					displayFeeds(revision, feedManager.getFeeds());
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					onLoadError();
-				}
+		runOnDbThread(() -> {
+			try {
+				displayFeeds(revision, feedManager.getFeeds());
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				onLoadError();
 			}
 		});
 	}
 
 	private void displayFeeds(final int revision, final List<Feed> feeds) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (revision == adapter.getRevision()) {
-					adapter.incrementRevision();
-					if (feeds.isEmpty()) list.showData();
-					else adapter.addAll(feeds);
-				} else {
-					LOG.info("Concurrent update, reloading");
-					loadFeeds();
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (revision == adapter.getRevision()) {
+				adapter.incrementRevision();
+				if (feeds.isEmpty()) list.showData();
+				else adapter.addAll(feeds);
+			} else {
+				LOG.info("Concurrent update, reloading");
+				loadFeeds();
 			}
 		});
 	}
 
 	private void deleteFeed(final Feed feed) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					feedManager.removeFeed(feed);
-					onFeedDeleted(feed);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					onDeleteError();
-				}
+		runOnDbThread(() -> {
+			try {
+				feedManager.removeFeed(feed);
+				onFeedDeleted(feed);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				onDeleteError();
 			}
 		});
 	}
 
 	private void onLoadError() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				list.setEmptyText(R.string.blogs_rss_feeds_manage_error);
-				list.showData();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			list.setEmptyText(R.string.blogs_rss_feeds_manage_error);
+			list.showData();
 		});
 	}
 
 	private void onFeedDeleted(final Feed feed) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				adapter.remove(feed);
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			adapter.remove(feed);
 		});
 	}
 
 	private void onDeleteError() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				Snackbar.make(list,
-						R.string.blogs_rss_feeds_manage_delete_error,
-						LENGTH_LONG).show();
-			}
-		});
+		runOnUiThreadUnlessDestroyed(() -> Snackbar.make(list,
+				R.string.blogs_rss_feeds_manage_delete_error,
+				LENGTH_LONG).show());
 	}
 }
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java
index 1217d94b71..c5f2eb3c16 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/WriteBlogPostActivity.java
@@ -141,44 +141,35 @@ public class WriteBlogPostActivity extends BriarActivity
 	}
 
 	private void storePost(final String body) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				long now = System.currentTimeMillis();
-				try {
-					LocalAuthor author = identityManager.getLocalAuthor();
-					BlogPost p = blogPostFactory
-							.createBlogPost(groupId, now, null, author, body);
-					blogManager.addLocalPost(p);
-					postPublished();
-				} catch (DbException | GeneralSecurityException | FormatException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					postFailedToPublish();
-				}
+		runOnDbThread(() -> {
+			long now = System.currentTimeMillis();
+			try {
+				LocalAuthor author = identityManager.getLocalAuthor();
+				BlogPost p = blogPostFactory
+						.createBlogPost(groupId, now, null, author, body);
+				blogManager.addLocalPost(p);
+				postPublished();
+			} catch (DbException | GeneralSecurityException
+					| FormatException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				postFailedToPublish();
 			}
 		});
 	}
 
 	private void postPublished() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				setResult(RESULT_OK);
-				supportFinishAfterTransition();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			setResult(RESULT_OK);
+			supportFinishAfterTransition();
 		});
 	}
 
 	private void postFailedToPublish() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				// hide progress bar, show publish button
-				progressBar.setVisibility(GONE);
-				input.setVisibility(VISIBLE);
-				// TODO show error
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			// hide progress bar, show publish button
+			progressBar.setVisibility(GONE);
+			input.setVisibility(VISIBLE);
+			// TODO show error
 		});
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java
index 839c0563b7..b381e3dfab 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java
@@ -54,11 +54,8 @@ public class ContactItemViewHolder<I extends ContactItem>
 			}
 		}
 
-		layout.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				if (listener != null) listener.onItemClick(avatar, item);
-			}
+		layout.setOnClickListener(v -> {
+			if (listener != null) listener.onItemClick(avatar, item);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java
index 0faca23414..0882f623d0 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java
@@ -114,36 +114,32 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 		View contentView = inflater.inflate(R.layout.list, container, false);
 
 		OnContactClickListener<ContactListItem> onContactClickListener =
-				new OnContactClickListener<ContactListItem>() {
-					@Override
-					public void onItemClick(View view, ContactListItem item) {
-						Intent i = new Intent(getActivity(),
-								ConversationActivity.class);
-						ContactId contactId = item.getContact().getId();
-						i.putExtra(CONTACT_ID, contactId.getInt());
+				(view, item) -> {
+					Intent i = new Intent(getActivity(),
+							ConversationActivity.class);
+					ContactId contactId = item.getContact().getId();
+					i.putExtra(CONTACT_ID, contactId.getInt());
 
-						if (Build.VERSION.SDK_INT >= 23) {
-							ContactListItemViewHolder holder =
-									(ContactListItemViewHolder) list
-											.getRecyclerView()
-											.findViewHolderForAdapterPosition(
-													adapter.findItemPosition(
-															item));
-							Pair<View, String> avatar =
-									Pair.create((View) holder.avatar,
-											getTransitionName(holder.avatar));
-							Pair<View, String> bulb =
-									Pair.create((View) holder.bulb,
-											getTransitionName(holder.bulb));
-							ActivityOptionsCompat options =
-									makeSceneTransitionAnimation(getActivity(),
-											avatar, bulb);
-							ActivityCompat.startActivity(getActivity(), i,
-									options.toBundle());
-						} else {
-							// work-around for android bug #224270
-							startActivity(i);
-						}
+					if (Build.VERSION.SDK_INT >= 23) {
+						ContactListItemViewHolder holder =
+								(ContactListItemViewHolder) list
+										.getRecyclerView()
+										.findViewHolderForAdapterPosition(
+												adapter.findItemPosition(item));
+						Pair<View, String> avatar =
+								Pair.create(holder.avatar,
+										getTransitionName(holder.avatar));
+						Pair<View, String> bulb =
+								Pair.create(holder.bulb,
+										getTransitionName(holder.bulb));
+						ActivityOptionsCompat options =
+								makeSceneTransitionAnimation(getActivity(),
+										avatar, bulb);
+						ActivityCompat.startActivity(getActivity(), i,
+								options.toBundle());
+					} else {
+						// work-around for android bug #224270
+						startActivity(i);
 					}
 				};
 		adapter = new ContactListAdapter(getContext(), onContactClickListener);
@@ -196,50 +192,42 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 
 	private void loadContacts() {
 		final int revision = adapter.getRevision();
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					List<ContactListItem> contacts = new ArrayList<>();
-					for (Contact c : contactManager.getActiveContacts()) {
-						try {
-							ContactId id = c.getId();
-							GroupCount count =
-									conversationManager.getGroupCount(id);
-							boolean connected =
-									connectionRegistry.isConnected(c.getId());
-							contacts.add(new ContactListItem(c, connected,
-									count));
-						} catch (NoSuchContactException e) {
-							// Continue
-						}
+		listener.runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				List<ContactListItem> contacts = new ArrayList<>();
+				for (Contact c : contactManager.getActiveContacts()) {
+					try {
+						ContactId id = c.getId();
+						GroupCount count =
+								conversationManager.getGroupCount(id);
+						boolean connected =
+								connectionRegistry.isConnected(c.getId());
+						contacts.add(new ContactListItem(c, connected, count));
+					} catch (NoSuchContactException e) {
+						// Continue
 					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Full load took " + duration + " ms");
-					displayContacts(revision, contacts);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Full load took " + duration + " ms");
+				displayContacts(revision, contacts);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void displayContacts(final int revision,
 			final List<ContactListItem> contacts) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (revision == adapter.getRevision()) {
-					adapter.incrementRevision();
-					if (contacts.isEmpty()) list.showData();
-					else adapter.addAll(contacts);
-				} else {
-					LOG.info("Concurrent update, reloading");
-					loadContacts();
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (revision == adapter.getRevision()) {
+				adapter.incrementRevision();
+				if (contacts.isEmpty()) list.showData();
+				else adapter.addAll(contacts);
+			} else {
+				LOG.info("Concurrent update, reloading");
+				loadContacts();
 			}
 		});
 	}
@@ -295,44 +283,35 @@ public class ContactListFragment extends BaseFragment implements EventListener {
 	}
 
 	private void updateItem(final ContactId c, final BaseMessageHeader h) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				int position = adapter.findItemPosition(c);
-				ContactListItem item = adapter.getItemAt(position);
-				if (item != null) {
-					ConversationItem i = ConversationItem.from(getContext(), h);
-					item.addMessage(i);
-					adapter.updateItemAt(position, item);
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			int position = adapter.findItemPosition(c);
+			ContactListItem item = adapter.getItemAt(position);
+			if (item != null) {
+				ConversationItem i = ConversationItem.from(getContext(), h);
+				item.addMessage(i);
+				adapter.updateItemAt(position, item);
 			}
 		});
 	}
 
 	private void removeItem(final ContactId c) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				int position = adapter.findItemPosition(c);
-				ContactListItem item = adapter.getItemAt(position);
-				if (item != null) adapter.remove(item);
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			int position = adapter.findItemPosition(c);
+			ContactListItem item = adapter.getItemAt(position);
+			if (item != null) adapter.remove(item);
 		});
 	}
 
 	private void setConnected(final ContactId c, final boolean connected) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				int position = adapter.findItemPosition(c);
-				ContactListItem item = adapter.getItemAt(position);
-				if (item != null) {
-					item.setConnected(connected);
-					adapter.notifyItemChanged(position);
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			int position = adapter.findItemPosition(c);
+			ContactListItem item = adapter.getItemAt(position);
+			if (item != null) {
+				item.setConnected(connected);
+				adapter.notifyItemChanged(position);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java
index 1bebf0c537..3768c83058 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java
@@ -289,102 +289,83 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void loadContactDetailsAndMessages() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					if (contactName == null || contactAuthorId == null) {
-						Contact contact = contactManager.getContact(contactId);
-						contactName = contact.getAuthor().getName();
-						contactAuthorId = contact.getAuthor().getId();
-					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading contact took " + duration + " ms");
-					loadMessages();
-					displayContactDetails();
-				} catch (NoSuchContactException e) {
-					finishOnUiThread();
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				if (contactName == null || contactAuthorId == null) {
+					Contact contact = contactManager.getContact(contactId);
+					contactName = contact.getAuthor().getName();
+					contactAuthorId = contact.getAuthor().getId();
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading contact took " + duration + " ms");
+				loadMessages();
+				displayContactDetails();
+			} catch (NoSuchContactException e) {
+				finishOnUiThread();
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void displayContactDetails() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				//noinspection ConstantConditions
-				toolbarAvatar.setImageDrawable(
-						new IdenticonDrawable(contactAuthorId.getBytes()));
-				toolbarTitle.setText(contactName);
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			//noinspection ConstantConditions
+			toolbarAvatar.setImageDrawable(
+					new IdenticonDrawable(contactAuthorId.getBytes()));
+			toolbarTitle.setText(contactName);
 		});
 	}
 
 	private void displayContactOnlineStatus() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (connectionRegistry.isConnected(contactId)) {
-					toolbarStatus.setImageDrawable(ContextCompat
-							.getDrawable(ConversationActivity.this,
-									R.drawable.contact_online));
-					toolbarStatus
-							.setContentDescription(getString(R.string.online));
-				} else {
-					toolbarStatus.setImageDrawable(ContextCompat
-							.getDrawable(ConversationActivity.this,
-									R.drawable.contact_offline));
-					toolbarStatus
-							.setContentDescription(getString(R.string.offline));
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (connectionRegistry.isConnected(contactId)) {
+				toolbarStatus.setImageDrawable(ContextCompat
+						.getDrawable(ConversationActivity.this,
+								R.drawable.contact_online));
+				toolbarStatus
+						.setContentDescription(getString(R.string.online));
+			} else {
+				toolbarStatus.setImageDrawable(ContextCompat
+						.getDrawable(ConversationActivity.this,
+								R.drawable.contact_offline));
+				toolbarStatus
+						.setContentDescription(getString(R.string.offline));
 			}
 		});
 	}
 
 	private void loadMessages() {
 		final int revision = adapter.getRevision();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Collection<PrivateMessageHeader> headers =
-							messagingManager.getMessageHeaders(contactId);
-					Collection<IntroductionMessage> introductions =
-							introductionManager
-									.getIntroductionMessages(contactId);
-					Collection<InvitationMessage> forumInvitations =
-							forumSharingManager
-									.getInvitationMessages(contactId);
-					Collection<InvitationMessage> blogInvitations =
-							blogSharingManager
-									.getInvitationMessages(contactId);
-					Collection<InvitationMessage> groupInvitations =
-							groupInvitationManager
-									.getInvitationMessages(contactId);
-					List<InvitationMessage> invitations = new ArrayList<>(
-							forumInvitations.size() + blogInvitations.size() +
-									groupInvitations.size());
-					invitations.addAll(forumInvitations);
-					invitations.addAll(blogInvitations);
-					invitations.addAll(groupInvitations);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading messages took " + duration + " ms");
-					displayMessages(revision, headers, introductions,
-							invitations);
-				} catch (NoSuchContactException e) {
-					finishOnUiThread();
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Collection<PrivateMessageHeader> headers =
+						messagingManager.getMessageHeaders(contactId);
+				Collection<IntroductionMessage> introductions =
+						introductionManager.getIntroductionMessages(contactId);
+				Collection<InvitationMessage> forumInvitations =
+						forumSharingManager.getInvitationMessages(contactId);
+				Collection<InvitationMessage> blogInvitations =
+						blogSharingManager.getInvitationMessages(contactId);
+				Collection<InvitationMessage> groupInvitations =
+						groupInvitationManager.getInvitationMessages(contactId);
+				List<InvitationMessage> invitations = new ArrayList<>(
+						forumInvitations.size() + blogInvitations.size() +
+								groupInvitations.size());
+				invitations.addAll(forumInvitations);
+				invitations.addAll(blogInvitations);
+				invitations.addAll(groupInvitations);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading messages took " + duration + " ms");
+				displayMessages(revision, headers, introductions, invitations);
+			} catch (NoSuchContactException e) {
+				finishOnUiThread();
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -393,22 +374,19 @@ public class ConversationActivity extends BriarActivity
 			final Collection<PrivateMessageHeader> headers,
 			final Collection<IntroductionMessage> introductions,
 			final Collection<InvitationMessage> invitations) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (revision == adapter.getRevision()) {
-					adapter.incrementRevision();
-					textInputView.setSendButtonEnabled(true);
-					List<ConversationItem> items = createItems(headers,
-							introductions, invitations);
-					if (items.isEmpty()) list.showData();
-					else adapter.addAll(items);
-					// Scroll to the bottom
-					list.scrollToPosition(adapter.getItemCount() - 1);
-				} else {
-					LOG.info("Concurrent update, reloading");
-					loadMessages();
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (revision == adapter.getRevision()) {
+				adapter.incrementRevision();
+				textInputView.setSendButtonEnabled(true);
+				List<ConversationItem> items = createItems(headers,
+						introductions, invitations);
+				if (items.isEmpty()) list.showData();
+				else adapter.addAll(items);
+				// Scroll to the bottom
+				list.scrollToPosition(adapter.getItemCount() - 1);
+			} else {
+				LOG.info("Concurrent update, reloading");
+				loadMessages();
 			}
 		});
 	}
@@ -459,39 +437,32 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void loadMessageBody(final MessageId m) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					String body = messagingManager.getMessageBody(m);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading body took " + duration + " ms");
-					displayMessageBody(m, body);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				String body = messagingManager.getMessageBody(m);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading body took " + duration + " ms");
+				displayMessageBody(m, body);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void displayMessageBody(final MessageId m, final String body) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				bodyCache.put(m, body);
-				SparseArray<ConversationItem> messages =
-						adapter.getPrivateMessages();
-				for (int i = 0; i < messages.size(); i++) {
-					ConversationItem item = messages.valueAt(i);
-					if (item.getId().equals(m)) {
-						item.setBody(body);
-						adapter.notifyItemChanged(messages.keyAt(i));
-						list.scrollToPosition(adapter.getItemCount() - 1);
-						return;
-					}
+		runOnUiThreadUnlessDestroyed(() -> {
+			bodyCache.put(m, body);
+			SparseArray<ConversationItem> messages =
+					adapter.getPrivateMessages();
+			for (int i = 0; i < messages.size(); i++) {
+				ConversationItem item = messages.valueAt(i);
+				if (item.getId().equals(m)) {
+					item.setBody(body);
+					adapter.notifyItemChanged(messages.keyAt(i));
+					list.scrollToPosition(adapter.getItemCount() - 1);
+					return;
 				}
 			}
 		});
@@ -573,14 +544,11 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void addConversationItem(final ConversationItem item) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				adapter.add(item);
-				// Scroll to the bottom
-				list.scrollToPosition(adapter.getItemCount() - 1);
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			adapter.add(item);
+			// Scroll to the bottom
+			list.scrollToPosition(adapter.getItemCount() - 1);
 		});
 	}
 
@@ -588,24 +556,16 @@ public class ConversationActivity extends BriarActivity
 		getContactNameTask().addListener(new FutureTaskListener<String>() {
 			@Override
 			public void onSuccess(final String contactName) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						ConversationItem item = ConversationItem
-								.from(ConversationActivity.this, contactName,
-										m);
-						addConversationItem(item);
-					}
+				runOnUiThreadUnlessDestroyed(() -> {
+					ConversationItem item = ConversationItem
+							.from(ConversationActivity.this, contactName, m);
+					addConversationItem(item);
 				});
 			}
 			@Override
 			public void onFailure(final Throwable exception) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						handleDbException((DbException) exception);
-					}
-				});
+				runOnUiThreadUnlessDestroyed(
+						() -> handleDbException((DbException) exception));
 			}
 		});
 	}
@@ -614,24 +574,16 @@ public class ConversationActivity extends BriarActivity
 		getContactNameTask().addListener(new FutureTaskListener<String>() {
 			@Override
 			public void onSuccess(final String contactName) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						ConversationItem item = ConversationItem
-								.from(ConversationActivity.this, contactName,
-										m);
-						addConversationItem(item);
-					}
+				runOnUiThreadUnlessDestroyed(() -> {
+					ConversationItem item = ConversationItem
+							.from(ConversationActivity.this, contactName, m);
+					addConversationItem(item);
 				});
 			}
 			@Override
 			public void onFailure(final Throwable exception) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						handleDbException((DbException) exception);
-					}
-				});
+				runOnUiThreadUnlessDestroyed(
+						() -> handleDbException((DbException) exception));
 			}
 		});
 	}
@@ -640,24 +592,16 @@ public class ConversationActivity extends BriarActivity
 		getContactNameTask().addListener(new FutureTaskListener<String>() {
 			@Override
 			public void onSuccess(final String contactName) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						ConversationItem item = ConversationItem
-								.from(ConversationActivity.this, contactName,
-										m);
-						addConversationItem(item);
-					}
+				runOnUiThreadUnlessDestroyed(() -> {
+					ConversationItem item = ConversationItem
+							.from(ConversationActivity.this, contactName, m);
+					addConversationItem(item);
 				});
 			}
 			@Override
 			public void onFailure(final Throwable exception) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						handleDbException((DbException) exception);
-					}
-				});
+				runOnUiThreadUnlessDestroyed(
+						() -> handleDbException((DbException) exception));
 			}
 		});
 	}
@@ -666,44 +610,33 @@ public class ConversationActivity extends BriarActivity
 		getContactNameTask().addListener(new FutureTaskListener<String>() {
 			@Override
 			public void onSuccess(final String contactName) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						ConversationItem item = ConversationItem
-								.from(ConversationActivity.this, contactName,
-										m);
-						addConversationItem(item);
-					}
+				runOnUiThreadUnlessDestroyed(() -> {
+					ConversationItem item = ConversationItem
+							.from(ConversationActivity.this, contactName, m);
+					addConversationItem(item);
 				});
 			}
 			@Override
 			public void onFailure(final Throwable exception) {
-				runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						handleDbException((DbException) exception);
-					}
-				});
+				runOnUiThreadUnlessDestroyed(
+						() -> handleDbException((DbException) exception));
 			}
 		});
 	}
 
 	private void markMessages(final Collection<MessageId> messageIds,
 			final boolean sent, final boolean seen) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				Set<MessageId> messages = new HashSet<>(messageIds);
-				SparseArray<ConversationOutItem> list =
-						adapter.getOutgoingMessages();
-				for (int i = 0; i < list.size(); i++) {
-					ConversationOutItem item = list.valueAt(i);
-					if (messages.contains(item.getId())) {
-						item.setSent(sent);
-						item.setSeen(seen);
-						adapter.notifyItemChanged(list.keyAt(i));
-					}
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			Set<MessageId> messages = new HashSet<>(messageIds);
+			SparseArray<ConversationOutItem> list =
+					adapter.getOutgoingMessages();
+			for (int i = 0; i < list.size(); i++) {
+				ConversationOutItem item = list.valueAt(i);
+				if (messages.contains(item.getId())) {
+					item.setSent(sent);
+					item.setSeen(seen);
+					adapter.notifyItemChanged(list.keyAt(i));
 				}
 			}
 		});
@@ -727,71 +660,54 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void loadGroupId(final String body, final long timestamp) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					messagingGroupId =
-							messagingManager.getConversationId(contactId);
-					createMessage(body, timestamp);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
-
+		runOnDbThread(() -> {
+			try {
+				messagingGroupId =
+						messagingManager.getConversationId(contactId);
+				createMessage(body, timestamp);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
+
 		});
 	}
 
 	private void createMessage(final String body, final long timestamp) {
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					//noinspection ConstantConditions init in loadGroupId()
-					storeMessage(privateMessageFactory.createPrivateMessage(
-							messagingGroupId, timestamp, body), body);
-				} catch (FormatException e) {
-					throw new RuntimeException(e);
-				}
+		cryptoExecutor.execute(() -> {
+			try {
+				//noinspection ConstantConditions init in loadGroupId()
+				storeMessage(privateMessageFactory.createPrivateMessage(
+						messagingGroupId, timestamp, body), body);
+			} catch (FormatException e) {throw new RuntimeException(e);
 			}
 		});
 	}
 
 	private void storeMessage(final PrivateMessage m, final String body) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					messagingManager.addLocalMessage(m);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Storing message took " + duration + " ms");
-					Message message = m.getMessage();
-					PrivateMessageHeader h = new PrivateMessageHeader(
-							message.getId(), message.getGroupId(),
-							message.getTimestamp(), true, false, false, false);
-					ConversationItem item = ConversationItem.from(h);
-					item.setBody(body);
-					bodyCache.put(message.getId(), body);
-					addConversationItem(item);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				messagingManager.addLocalMessage(m);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Storing message took " + duration + " ms");
+				Message message = m.getMessage();
+				PrivateMessageHeader h = new PrivateMessageHeader(
+						message.getId(), message.getGroupId(),
+						message.getTimestamp(), true, false, false, false);
+				ConversationItem item = ConversationItem.from(h);
+				item.setBody(body);
+				bodyCache.put(message.getId(), body);
+				addConversationItem(item);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void askToRemoveContact() {
 		DialogInterface.OnClickListener okListener =
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						removeContact();
-					}
-				};
+				(dialog, which) -> removeContact();
 		AlertDialog.Builder builder =
 				new AlertDialog.Builder(ConversationActivity.this,
 						R.style.BriarDialogTheme);
@@ -803,118 +719,95 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void removeContact() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					contactManager.removeContact(contactId);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				} finally {
-					finishAfterContactRemoved();
-				}
+		runOnDbThread(() -> {
+			try {
+				contactManager.removeContact(contactId);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+			} finally {
+				finishAfterContactRemoved();
 			}
 		});
 	}
 
 	private void finishAfterContactRemoved() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				String deleted = getString(R.string.contact_deleted_toast);
-				Toast.makeText(ConversationActivity.this, deleted, LENGTH_SHORT)
-						.show();
-				supportFinishAfterTransition();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			String deleted = getString(R.string.contact_deleted_toast);
+			Toast.makeText(ConversationActivity.this, deleted, LENGTH_SHORT)
+					.show();
+			supportFinishAfterTransition();
 		});
 	}
 
 	private void enableIntroductionActionIfAvailable(final MenuItem item) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					if (contactManager.getActiveContacts().size() > 1) {
-						enableIntroductionAction(item);
-						Settings settings =
-								settingsManager.getSettings(SETTINGS_NAMESPACE);
-						if (settings.getBoolean(SHOW_ONBOARDING_INTRODUCTION,
-								true)) {
-							showIntroductionOnboarding();
-						}
+		runOnDbThread(() -> {
+			try {
+				if (contactManager.getActiveContacts().size() > 1) {
+					enableIntroductionAction(item);
+					Settings settings =
+							settingsManager.getSettings(SETTINGS_NAMESPACE);
+					if (settings.getBoolean(SHOW_ONBOARDING_INTRODUCTION,
+							true)) {
+						showIntroductionOnboarding();
 					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void enableIntroductionAction(final MenuItem item) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				item.setEnabled(true);
-			}
-		});
+		runOnUiThreadUnlessDestroyed(() -> item.setEnabled(true));
 	}
 
 	private void showIntroductionOnboarding() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				// find view of overflow icon
-				View target = null;
-				for (int i = 0; i < toolbar.getChildCount(); i++) {
-					if (toolbar.getChildAt(i) instanceof ActionMenuView) {
-						ActionMenuView menu =
-								(ActionMenuView) toolbar.getChildAt(i);
-						target = menu.getChildAt(menu.getChildCount() - 1);
-						break;
-					}
-				}
-				if (target == null) {
-					LOG.warning("No Overflow Icon found!");
-					return;
+		runOnUiThreadUnlessDestroyed(() -> {
+			// find view of overflow icon
+			View target = null;
+			for (int i = 0; i < toolbar.getChildCount(); i++) {
+				if (toolbar.getChildAt(i) instanceof ActionMenuView) {
+					ActionMenuView menu =
+							(ActionMenuView) toolbar.getChildAt(i);
+					target = menu.getChildAt(menu.getChildCount() - 1);
+					break;
 				}
+			}
+			if (target == null) {
+				LOG.warning("No Overflow Icon found!");
+				return;
+			}
 
-				OnHidePromptListener listener = new OnHidePromptListener() {
-					@Override
-					public void onHidePrompt(MotionEvent motionEvent,
-							boolean focalClicked) {
-						introductionOnboardingSeen();
-					}
+			OnHidePromptListener listener = new OnHidePromptListener() {
+				@Override
+				public void onHidePrompt(MotionEvent motionEvent,
+						boolean focalClicked) {
+					introductionOnboardingSeen();
+				}
 
-					@Override
-					public void onHidePromptComplete() {
-					}
-				};
-				new MaterialTapTargetPrompt.Builder(ConversationActivity.this)
-						.setTarget(target)
-						.setPrimaryText(R.string.introduction_onboarding_title)
-						.setSecondaryText(R.string.introduction_onboarding_text)
-						.setBackgroundColourFromRes(R.color.briar_primary)
-						.setIcon(R.drawable.ic_more_vert_accent)
-						.setOnHidePromptListener(listener)
-						.show();
-			}
+				@Override
+				public void onHidePromptComplete() {
+				}
+			};
+			new MaterialTapTargetPrompt.Builder(ConversationActivity.this)
+					.setTarget(target)
+					.setPrimaryText(R.string.introduction_onboarding_title)
+					.setSecondaryText(R.string.introduction_onboarding_text)
+					.setBackgroundColourFromRes(R.color.briar_primary)
+					.setIcon(R.drawable.ic_more_vert_accent)
+					.setOnHidePromptListener(listener)
+					.show();
 		});
 	}
 
 	private void introductionOnboardingSeen() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings settings = new Settings();
-					settings.putBoolean(SHOW_ONBOARDING_INTRODUCTION, false);
-					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		runOnDbThread(() -> {
+			try {
+				Settings settings = new Settings();
+				settings.putBoolean(SHOW_ONBOARDING_INTRODUCTION, false);
+				settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -925,19 +818,15 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void markMessageRead(final GroupId g, final MessageId m) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					messagingManager.setReadFlag(g, m, true);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Marking read took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				messagingManager.setReadFlag(g, m, true);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Marking read took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -951,36 +840,33 @@ public class ConversationActivity extends BriarActivity
 		if (position != INVALID_POSITION) {
 			adapter.notifyItemChanged(position, item);
 		}
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				long timestamp = System.currentTimeMillis();
-				timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
-				try {
-					switch (item.getRequestType()) {
-						case INTRODUCTION:
-							respondToIntroductionRequest(item.getSessionId(),
-									accept, timestamp);
-							break;
-						case FORUM:
-							respondToForumRequest(item.getSessionId(), accept);
-							break;
-						case BLOG:
-							respondToBlogRequest(item.getSessionId(), accept);
-							break;
-						case GROUP:
-							respondToGroupRequest(item.getSessionId(), accept);
-							break;
-						default:
-							throw new IllegalArgumentException(
-									"Unknown Request Type");
-					}
-					loadMessages();
-				} catch (DbException | FormatException e) {
-					introductionResponseError();
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+		runOnDbThread(() -> {
+			long timestamp = System.currentTimeMillis();
+			timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
+			try {
+				switch (item.getRequestType()) {
+					case INTRODUCTION:
+						respondToIntroductionRequest(item.getSessionId(),
+								accept, timestamp);
+						break;
+					case FORUM:
+						respondToForumRequest(item.getSessionId(), accept);
+						break;
+					case BLOG:
+						respondToBlogRequest(item.getSessionId(), accept);
+						break;
+					case GROUP:
+						respondToGroupRequest(item.getSessionId(), accept);
+						break;
+					default:
+						throw new IllegalArgumentException(
+								"Unknown Request Type");
 				}
+				loadMessages();
+			} catch (DbException | FormatException e) {
+				introductionResponseError();
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -1041,14 +927,10 @@ public class ConversationActivity extends BriarActivity
 	}
 
 	private void introductionResponseError() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
+		runOnUiThreadUnlessDestroyed(() ->
 				Toast.makeText(ConversationActivity.this,
 						R.string.introduction_response_error,
-						Toast.LENGTH_SHORT).show();
-			}
-		});
+						Toast.LENGTH_SHORT).show());
 	}
 
 	private ListenableFutureTask<String> getContactNameTask() {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestViewHolder.java
index 492324a847..c115a20c69 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestViewHolder.java
@@ -2,7 +2,6 @@ package org.briarproject.briar.android.contact;
 
 import android.support.annotation.UiThread;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.widget.Button;
 
 import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -35,12 +34,8 @@ class ConversationRequestViewHolder extends ConversationNoticeInViewHolder {
 		if (item.wasAnswered() && item.canBeOpened()) {
 			acceptButton.setVisibility(VISIBLE);
 			acceptButton.setText(R.string.open);
-			acceptButton.setOnClickListener(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					listener.openRequestedShareable(item);
-				}
-			});
+			acceptButton.setOnClickListener(
+					v -> listener.openRequestedShareable(item));
 			declineButton.setVisibility(GONE);
 		} else if (item.wasAnswered()) {
 			acceptButton.setVisibility(GONE);
@@ -48,22 +43,16 @@ class ConversationRequestViewHolder extends ConversationNoticeInViewHolder {
 		} else {
 			acceptButton.setVisibility(VISIBLE);
 			acceptButton.setText(R.string.accept);
-			acceptButton.setOnClickListener(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					acceptButton.setEnabled(false);
-					declineButton.setEnabled(false);
-					listener.respondToRequest(item, true);
-				}
+			acceptButton.setOnClickListener(v -> {
+				acceptButton.setEnabled(false);
+				declineButton.setEnabled(false);
+				listener.respondToRequest(item, true);
 			});
 			declineButton.setVisibility(VISIBLE);
-			declineButton.setOnClickListener(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					acceptButton.setEnabled(false);
-					declineButton.setEnabled(false);
-					listener.respondToRequest(item, false);
-				}
+			declineButton.setOnClickListener(v -> {
+				acceptButton.setEnabled(false);
+				declineButton.setEnabled(false);
+				listener.respondToRequest(item, false);
 			});
 		}
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java
index 3cd744d154..83a3cc28c1 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java
@@ -41,26 +41,21 @@ public abstract class ContactSelectorControllerImpl
 	public void loadContacts(final GroupId g,
 			final Collection<ContactId> selection,
 			final ResultExceptionHandler<Collection<SelectableContactItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<SelectableContactItem> contacts =
-							new ArrayList<>();
-					for (Contact c : contactManager.getActiveContacts()) {
-						// was this contact already selected?
-						boolean selected = selection.contains(c.getId());
-						// can this contact be selected?
-						boolean disabled = isDisabled(g, c);
-						contacts.add(new SelectableContactItem(c, selected,
-								disabled));
-					}
-					handler.onResult(contacts);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
+		runOnDbThread(() -> {
+			try {
+				Collection<SelectableContactItem> contacts = new ArrayList<>();
+				for (Contact c : contactManager.getActiveContacts()) {
+					// was this contact already selected?
+					boolean selected = selection.contains(c.getId());
+					// can this contact be selected?
+					boolean disabled = isDisabled(g, c);
+					contacts.add(new SelectableContactItem(c, selected,
+							disabled));
 				}
+				handler.onResult(contacts);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java
index 6ae01b8a53..468bfd8658 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java
@@ -29,16 +29,13 @@ public class DbControllerImpl implements DbController {
 
 	@Override
 	public void runOnDbThread(final Runnable task) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					lifecycleManager.waitForDatabase();
-					task.run();
-				} catch (InterruptedException e) {
-					LOG.warning("Interrupted while waiting for database");
-					Thread.currentThread().interrupt();
-				}
+		dbExecutor.execute(() -> {
+			try {
+				lifecycleManager.waitForDatabase();
+				task.run();
+			} catch (InterruptedException e) {
+				LOG.warning("Interrupted while waiting for database");
+				Thread.currentThread().interrupt();
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java
index 5c83206e50..b6091a097f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/SharingControllerImpl.java
@@ -60,13 +60,10 @@ public class SharingControllerImpl implements SharingController, EventListener {
 
 	private void setConnected(final ContactId c) {
 		if (listener == null) return;
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (contacts.contains(c)) {
-					int online = getOnlineCount();
-					listener.onSharingInfoUpdated(contacts.size(), online);
-				}
+		listener.runOnUiThreadUnlessDestroyed(() -> {
+			if (contacts.contains(c)) {
+				int online = getOnlineCount();
+				listener.onSharingInfoUpdated(contacts.size(), online);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiExceptionHandler.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiExceptionHandler.java
index 98ea082ee3..c3d6ae5471 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiExceptionHandler.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiExceptionHandler.java
@@ -20,12 +20,7 @@ public abstract class UiExceptionHandler<E extends Exception>
 
 	@Override
 	public void onException(final E exception) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				onExceptionUi(exception);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> onExceptionUi(exception));
 	}
 
 	@UiThread
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultExceptionHandler.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultExceptionHandler.java
index d3ee2d7c83..783713c2e1 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultExceptionHandler.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultExceptionHandler.java
@@ -18,12 +18,7 @@ public abstract class UiResultExceptionHandler<R, E extends Exception>
 
 	@Override
 	public void onResult(final R result) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				onResultUi(result);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> onResultUi(result));
 	}
 
 	@UiThread
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultHandler.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultHandler.java
index 89bd919d4d..277952c405 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultHandler.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/handler/UiResultHandler.java
@@ -14,12 +14,7 @@ public abstract class UiResultHandler<R> implements ResultHandler<R> {
 
 	@Override
 	public void onResult(final R result) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				onResultUi(result);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> onResultUi(result));
 	}
 
 	@UiThread
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java
index 44087e109e..1eea0e84bb 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/CreateForumActivity.java
@@ -5,14 +5,9 @@ import android.os.Bundle;
 import android.support.design.widget.TextInputLayout;
 import android.text.Editable;
 import android.text.TextWatcher;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
 import android.widget.Toast;
 
 import org.briarproject.bramble.api.db.DbException;
@@ -79,22 +74,13 @@ public class CreateForumActivity extends BriarActivity {
 			public void afterTextChanged(Editable s) {
 			}
 		});
-		nameEntry.setOnEditorActionListener(new OnEditorActionListener() {
-			@Override
-			public boolean onEditorAction(TextView v, int actionId,
-					KeyEvent e) {
-				createForum();
-				return true;
-			}
+		nameEntry.setOnEditorActionListener((v, actionId, e) -> {
+			createForum();
+			return true;
 		});
 
 		createForumButton = (Button) findViewById(R.id.createForumButton);
-		createForumButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				createForum();
-			}
-		});
+		createForumButton.setOnClickListener(v -> createForum());
 
 		progress = (ProgressBar) findViewById(R.id.createForumProgressBar);
 	}
@@ -135,38 +121,31 @@ public class CreateForumActivity extends BriarActivity {
 	}
 
 	private void storeForum(final String name) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Forum f = forumManager.addForum(name);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Storing forum took " + duration + " ms");
-					displayForum(f);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					finishOnUiThread();
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Forum f = forumManager.addForum(name);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Storing forum took " + duration + " ms");
+				displayForum(f);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				finishOnUiThread();
 			}
 		});
 	}
 
 	private void displayForum(final Forum f) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				Intent i = new Intent(CreateForumActivity.this,
-						ForumActivity.class);
-				i.putExtra(GROUP_ID, f.getId().getBytes());
-				i.putExtra(GROUP_NAME, f.getName());
-				startActivity(i);
-				Toast.makeText(CreateForumActivity.this,
-						R.string.forum_created_toast, LENGTH_LONG).show();
-				supportFinishAfterTransition();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			Intent i = new Intent(CreateForumActivity.this,
+					ForumActivity.class);
+			i.putExtra(GROUP_ID, f.getId().getBytes());
+			i.putExtra(GROUP_NAME, f.getName());
+			startActivity(i);
+			Toast.makeText(CreateForumActivity.this,
+					R.string.forum_created_toast, LENGTH_LONG).show();
+			supportFinishAfterTransition();
 		});
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java
index ccff1a6ce3..5f4ce44ae0 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.forum;
 
-import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.os.Bundle;
@@ -11,7 +10,6 @@ import android.support.v7.widget.Toolbar;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 import android.widget.Toast;
 
 import org.briarproject.bramble.api.contact.ContactId;
@@ -69,16 +67,12 @@ public class ForumActivity extends
 
 		// Open member list on Toolbar click
 		if (toolbar != null) {
-			toolbar.setOnClickListener(
-					new View.OnClickListener() {
-						@Override
-						public void onClick(View v) {
-							Intent i = new Intent(ForumActivity.this,
-									ForumSharingStatusActivity.class);
-							i.putExtra(GROUP_ID, groupId.getBytes());
-							startActivity(i);
-						}
-					});
+			toolbar.setOnClickListener(v -> {
+				Intent i1 = new Intent(ForumActivity.this,
+						ForumSharingStatusActivity.class);
+				i1.putExtra(GROUP_ID, groupId.getBytes());
+				startActivity(i1);
+			});
 		}
 	}
 
@@ -147,12 +141,7 @@ public class ForumActivity extends
 	}
 
 	private void showUnsubscribeDialog() {
-		OnClickListener okListener = new OnClickListener() {
-			@Override
-			public void onClick(DialogInterface dialog, int which) {
-				deleteForum();
-			}
-		};
+		OnClickListener okListener = (dialog, which) -> deleteForum();
 		AlertDialog.Builder builder = new AlertDialog.Builder(this,
 				R.style.BriarDialogTheme);
 		builder.setTitle(getString(R.string.dialog_title_leave_forum));
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java
index dde424f7b8..faddfa1c9e 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java
@@ -121,21 +121,17 @@ class ForumControllerImpl extends
 	@Override
 	public void loadSharingContacts(
 			final ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<Contact> contacts =
-							forumSharingManager.getSharedWith(getGroupId());
-					Collection<ContactId> contactIds =
-							new ArrayList<>(contacts.size());
-					for (Contact c : contacts) contactIds.add(c.getId());
-					handler.onResult(contactIds);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				Collection<Contact> contacts =
+						forumSharingManager.getSharedWith(getGroupId());
+				Collection<ContactId> contactIds =
+						new ArrayList<>(contacts.size());
+				for (Contact c : contacts) contactIds.add(c.getId());
+				handler.onResult(contactIds);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -144,22 +140,18 @@ class ForumControllerImpl extends
 	public void createAndStoreMessage(final String body,
 			@Nullable final ForumItem parentItem,
 			final ResultExceptionHandler<ForumItem, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor author = identityManager.getLocalAuthor();
-					GroupCount count = forumManager.getGroupCount(getGroupId());
-					long timestamp = max(count.getLatestMsgTime() + 1,
-							clock.currentTimeMillis());
-					MessageId parentId = parentItem != null ?
-							parentItem.getId() : null;
-					createMessage(body, timestamp, parentId, author, handler);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor author = identityManager.getLocalAuthor();
+				GroupCount count = forumManager.getGroupCount(getGroupId());
+				long timestamp = max(count.getLatestMsgTime() + 1,
+						clock.currentTimeMillis());
+				MessageId parentId = parentItem != null ?
+						parentItem.getId() : null;
+				createMessage(body, timestamp, parentId, author, handler);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -167,15 +159,11 @@ class ForumControllerImpl extends
 	private void createMessage(final String body, final long timestamp,
 			final @Nullable MessageId parentId, final LocalAuthor author,
 			final ResultExceptionHandler<ForumItem, DbException> handler) {
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Creating forum post...");
-				ForumPost msg = forumManager
-						.createLocalPost(getGroupId(), body, timestamp,
-								parentId, author);
-				storePost(msg, body, handler);
-			}
+		cryptoExecutor.execute(() -> {
+			LOG.info("Creating forum post...");
+			ForumPost msg = forumManager.createLocalPost(getGroupId(), body,
+					timestamp, parentId, author);
+			storePost(msg, body, handler);
 		});
 	}
 
@@ -197,30 +185,17 @@ class ForumControllerImpl extends
 
 	private void onForumPostReceived(ForumPostHeader h, String body) {
 		final ForumItem item = buildItem(h, body);
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onItemReceived(item);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onItemReceived(item));
 	}
 
 	private void onForumInvitationAccepted(final ContactId c) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onInvitationAccepted(c);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onInvitationAccepted(c));
 	}
 
 	private void onForumLeft(final ContactId c) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onForumLeft(c);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onForumLeft(c));
 	}
 
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListAdapter.java
index 46d8007fbe..0eecfd509c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListAdapter.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListAdapter.java
@@ -77,15 +77,12 @@ class ForumListAdapter
 		}
 
 		// Open Forum on Click
-		ui.layout.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				Intent i = new Intent(ctx, ForumActivity.class);
-				Forum f = item.getForum();
-				i.putExtra(GROUP_ID, f.getId().getBytes());
-				i.putExtra(GROUP_NAME, f.getName());
-				ctx.startActivity(i);
-			}
+		ui.layout.setOnClickListener(v -> {
+			Intent i = new Intent(ctx, ForumActivity.class);
+			Forum f = item.getForum();
+			i.putExtra(GROUP_ID, f.getId().getBytes());
+			i.putExtra(GROUP_NAME, f.getName());
+			ctx.startActivity(i);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java
index a1d88d8845..89c0645b02 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java
@@ -155,82 +155,67 @@ public class ForumListFragment extends BaseEventFragment implements
 
 	private void loadForums() {
 		final int revision = adapter.getRevision();
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Collection<ForumListItem> forums = new ArrayList<>();
-					for (Forum f : forumManager.getForums()) {
-						try {
-							GroupCount count =
-									forumManager.getGroupCount(f.getId());
-							forums.add(new ForumListItem(f, count));
-						} catch (NoSuchGroupException e) {
-							// Continue
-						}
+		listener.runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Collection<ForumListItem> forums = new ArrayList<>();
+				for (Forum f : forumManager.getForums()) {
+					try {
+						GroupCount count =
+								forumManager.getGroupCount(f.getId());
+						forums.add(new ForumListItem(f, count));
+					} catch (NoSuchGroupException e) {
+						// Continue
 					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Full load took " + duration + " ms");
-					displayForums(revision, forums);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Full load took " + duration + " ms");
+				displayForums(revision, forums);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void displayForums(final int revision,
 			final Collection<ForumListItem> forums) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (revision == adapter.getRevision()) {
-					adapter.incrementRevision();
-					if (forums.isEmpty()) list.showData();
-					else adapter.addAll(forums);
-				} else {
-					LOG.info("Concurrent update, reloading");
-					loadForums();
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (revision == adapter.getRevision()) {
+				adapter.incrementRevision();
+				if (forums.isEmpty()) list.showData();
+				else adapter.addAll(forums);
+			} else {
+				LOG.info("Concurrent update, reloading");
+				loadForums();
 			}
 		});
 	}
 
 	private void loadAvailableForums() {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					int available =
-							forumSharingManager.getInvitations().size();
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading available took " + duration + " ms");
-					displayAvailableForums(available);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		listener.runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				int available = forumSharingManager.getInvitations().size();
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading available took " + duration + " ms");
+				displayAvailableForums(available);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void displayAvailableForums(final int availableCount) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (availableCount == 0) {
-					snackbar.dismiss();
-				} else {
-					snackbar.setText(getResources().getQuantityString(
-							R.plurals.forums_shared, availableCount,
-							availableCount));
-					if (!snackbar.isShownOrQueued()) snackbar.show();
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (availableCount == 0) {
+				snackbar.dismiss();
+			} else {
+				snackbar.setText(getResources().getQuantityString(
+						R.plurals.forums_shared, availableCount,
+						availableCount));
+				if (!snackbar.isShownOrQueued()) snackbar.show();
 			}
 		});
 	}
@@ -263,29 +248,23 @@ public class ForumListFragment extends BaseEventFragment implements
 	}
 
 	private void updateItem(final GroupId g, final ForumPostHeader m) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				int position = adapter.findItemPosition(g);
-				ForumListItem item = adapter.getItemAt(position);
-				if (item != null) {
-					item.addHeader(m);
-					adapter.updateItemAt(position, item);
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			int position = adapter.findItemPosition(g);
+			ForumListItem item = adapter.getItemAt(position);
+			if (item != null) {
+				item.addHeader(m);
+				adapter.updateItemAt(position, item);
 			}
 		});
 	}
 
 	private void removeForum(final GroupId g) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				adapter.incrementRevision();
-				int position = adapter.findItemPosition(g);
-				ForumListItem item = adapter.getItemAt(position);
-				if (item != null) adapter.remove(item);
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			adapter.incrementRevision();
+			int position = adapter.findItemPosition(g);
+			ForumListItem item = adapter.getItemAt(position);
+			if (item != null) adapter.remove(item);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/fragment/BaseFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/fragment/BaseFragment.java
index 7273a7f54f..c8857e1cac 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/fragment/BaseFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/fragment/BaseFragment.java
@@ -82,14 +82,11 @@ public abstract class BaseFragment extends Fragment
 	public void runOnUiThreadUnlessDestroyed(final Runnable r) {
 		final Activity activity = getActivity();
 		if (activity != null) {
-			activity.runOnUiThread(new Runnable() {
-				@Override
-				public void run() {
-					// Note that we don't have to check if the activity has
-					// been destroyed as the Fragment has not been detached yet
-					if (!isDetached() && !activity.isFinishing()) {
-						r.run();
-					}
+			activity.runOnUiThread(() -> {
+				// Note that we don't have to check if the activity has
+				// been destroyed as the Fragment has not been detached yet
+				if (!isDetached() && !activity.isFinishing()) {
+					r.run();
 				}
 			});
 		}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java
index 242aaed31b..b1e644e96a 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/fragment/ScreenFilterDialogFragment.java
@@ -1,7 +1,6 @@
 package org.briarproject.briar.android.fragment;
 
 import android.app.Dialog;
-import android.content.DialogInterface;
 import android.os.Bundle;
 import android.support.v4.app.DialogFragment;
 import android.support.v7.app.AlertDialog;
@@ -35,12 +34,7 @@ public class ScreenFilterDialogFragment extends DialogFragment {
 		builder.setMessage(getString(R.string.screen_filter_body,
 				TextUtils.join("\n", apps)));
 		builder.setNeutralButton(R.string.continue_button,
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						dialog.dismiss();
-					}
-				});
+				(dialog, which) -> dialog.dismiss());
 		return builder.create();
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java
index 7bfa80f969..2fa90c0dd7 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java
@@ -71,13 +71,10 @@ public class ContactChooserFragment extends BaseFragment {
 		View contentView = inflater.inflate(R.layout.list, container, false);
 
 		OnContactClickListener<ContactListItem> onContactClickListener =
-				new OnContactClickListener<ContactListItem>() {
-					@Override
-					public void onItemClick(View view, ContactListItem item) {
-						if (c1 == null) throw new IllegalStateException();
-						Contact c2 = item.getContact();
-						showMessageScreen(c1, c2);
-					}
+				(view, item) -> {
+					if (c1 == null) throw new IllegalStateException();
+					Contact c2 = item.getContact();
+					showMessageScreen(c1, c2);
 				};
 		adapter = new ContactListAdapter(getActivity(), onContactClickListener);
 
@@ -115,40 +112,32 @@ public class ContactChooserFragment extends BaseFragment {
 	}
 
 	private void loadContacts() {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					List<ContactListItem> contacts = new ArrayList<>();
-					for (Contact c : contactManager.getActiveContacts()) {
-						if (c.getId().equals(contactId)) {
-							c1 = c;
-						} else {
-							ContactId id = c.getId();
-							GroupCount count =
-									conversationManager.getGroupCount(id);
-							boolean connected =
-									connectionRegistry.isConnected(c.getId());
-							contacts.add(new ContactListItem(c, connected,
-									count));
-						}
+		listener.runOnDbThread(() -> {
+			try {
+				List<ContactListItem> contacts = new ArrayList<>();
+				for (Contact c : contactManager.getActiveContacts()) {
+					if (c.getId().equals(contactId)) {
+						c1 = c;
+					} else {
+						ContactId id = c.getId();
+						GroupCount count =
+								conversationManager.getGroupCount(id);
+						boolean connected =
+								connectionRegistry.isConnected(c.getId());
+						contacts.add(new ContactListItem(c, connected, count));
 					}
-					displayContacts(contacts);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
 				}
+				displayContacts(contacts);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void displayContacts(final List<ContactListItem> contacts) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (contacts.isEmpty()) list.showData();
-				else adapter.addAll(contacts);
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (contacts.isEmpty()) list.showData();
+			else adapter.addAll(contacts);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java
index ddf70e4f2a..af90a665f2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java
@@ -120,48 +120,41 @@ public class IntroductionMessageFragment extends BaseFragment
 
 	private void prepareToSetUpViews(final int contactId1,
 			final int contactId2) {
-		introductionActivity.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Contact c1 = contactManager.getContact(
-							new ContactId(contactId1));
-					Contact c2 = contactManager.getContact(
-							new ContactId(contactId2));
-					setUpViews(c1, c2);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		introductionActivity.runOnDbThread(() -> {
+			try {
+				Contact c1 = contactManager.getContact(
+						new ContactId(contactId1));
+				Contact c2 = contactManager.getContact(
+						new ContactId(contactId2));
+				setUpViews(c1, c2);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void setUpViews(final Contact c1, final Contact c2) {
-		introductionActivity.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				contact1 = c1;
-				contact2 = c2;
-
-				// set avatars
-				ui.avatar1.setImageDrawable(new IdenticonDrawable(
-						c1.getAuthor().getId().getBytes()));
-				ui.avatar2.setImageDrawable(new IdenticonDrawable(
-						c2.getAuthor().getId().getBytes()));
-
-				// set contact names
-				ui.contactName1.setText(c1.getAuthor().getName());
-				ui.contactName2.setText(c2.getAuthor().getName());
-
-				// set button action
-				ui.message.setListener(IntroductionMessageFragment.this);
-
-				// hide progress bar and show views
-				ui.progressBar.setVisibility(GONE);
-				ui.message.setSendButtonEnabled(true);
-				ui.message.showSoftKeyboard();
-			}
+		introductionActivity.runOnUiThreadUnlessDestroyed(() -> {
+			contact1 = c1;
+			contact2 = c2;
+
+			// set avatars
+			ui.avatar1.setImageDrawable(new IdenticonDrawable(
+					c1.getAuthor().getId().getBytes()));
+			ui.avatar2.setImageDrawable(new IdenticonDrawable(
+					c2.getAuthor().getId().getBytes()));
+
+			// set contact names
+			ui.contactName1.setText(c1.getAuthor().getName());
+			ui.contactName2.setText(c2.getAuthor().getName());
+
+			// set button action
+			ui.message.setListener(IntroductionMessageFragment.this);
+
+			// hide progress bar and show views
+			ui.progressBar.setVisibility(GONE);
+			ui.message.setSendButtonEnabled(true);
+			ui.message.showSoftKeyboard();
 		});
 	}
 
@@ -194,31 +187,22 @@ public class IntroductionMessageFragment extends BaseFragment
 
 	private void makeIntroduction(final Contact c1, final Contact c2,
 			final String msg) {
-		introductionActivity.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				// actually make the introduction
-				try {
-					long timestamp = System.currentTimeMillis();
-					introductionManager.makeIntroduction(c1, c2, msg,
-							timestamp);
-				} catch (DbException | FormatException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					introductionError();
-				}
+		introductionActivity.runOnDbThread(() -> {
+			// actually make the introduction
+			try {
+				long timestamp = System.currentTimeMillis();
+				introductionManager.makeIntroduction(c1, c2, msg, timestamp);
+			} catch (DbException | FormatException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				introductionError();
 			}
 		});
 	}
 
 	private void introductionError() {
-		introductionActivity.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				Toast.makeText(introductionActivity,
-						R.string.introduction_error, LENGTH_SHORT).show();
-			}
-		});
+		introductionActivity.runOnUiThreadUnlessDestroyed(
+				() -> Toast.makeText(introductionActivity,
+						R.string.introduction_error, LENGTH_SHORT).show());
 	}
 
 	private static class ViewHolder {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/CameraView.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/CameraView.java
index 4ea6ad2460..5b17d52b2c 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/CameraView.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/CameraView.java
@@ -353,15 +353,11 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 
 	@Override
 	public void surfaceCreated(final SurfaceHolder holder) {
-		post(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					surfaceCreatedUi(holder);
-				} catch (CameraException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		post(() -> {
+			try {
+				surfaceCreatedUi(holder);
+			} catch (CameraException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -381,15 +377,11 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 	@Override
 	public void surfaceChanged(final SurfaceHolder holder, int format,
 			final int w, final int h) {
-		post(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					surfaceChangedUi(holder, w, h);
-				} catch (CameraException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		post(() -> {
+			try {
+				surfaceChangedUi(holder, w, h);
+			} catch (CameraException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -420,12 +412,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 
 	@Override
 	public void surfaceDestroyed(final SurfaceHolder holder) {
-		post(new Runnable() {
-			@Override
-			public void run() {
-				surfaceDestroyedUi(holder);
-			}
-		});
+		post(() -> surfaceDestroyedUi(holder));
 	}
 
 	@UiThread
@@ -442,12 +429,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 	@Override
 	public void onAutoFocus(boolean success, final Camera camera) {
 		LOG.info("Auto focus succeeded: " + success);
-		postDelayed(new Runnable() {
-			@Override
-			public void run() {
-				retryAutoFocus();
-			}
-		}, AUTO_FOCUS_RETRY_DELAY);
+		postDelayed(this::retryAutoFocus, AUTO_FOCUS_RETRY_DELAY);
 	}
 
 	@UiThread
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/IntroFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/IntroFragment.java
index db37ed9330..f111272979 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/IntroFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/IntroFragment.java
@@ -4,7 +4,6 @@ import android.content.Context;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ScrollView;
 
@@ -66,24 +65,14 @@ public class IntroFragment extends BaseFragment {
 				false);
 		scrollView = (ScrollView) v.findViewById(R.id.scrollView);
 		View button = v.findViewById(R.id.continueButton);
-		button.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View view) {
-				screenSeenListener.showNextScreen();
-			}
-		});
+		button.setOnClickListener(view -> screenSeenListener.showNextScreen());
 		return v;
 	}
 
 	@Override
 	public void onStart() {
 		super.onStart();
-		scrollView.post(new Runnable() {
-			@Override
-			public void run() {
-				scrollView.fullScroll(FOCUS_DOWN);
-			}
-		});
+		scrollView.post(() -> scrollView.fullScroll(FOCUS_DOWN));
 	}
 
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java
index 59203041a7..a87c882614 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/KeyAgreementActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.keyagreement;
 
-import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.os.Bundle;
 import android.support.annotation.UiThread;
@@ -144,12 +143,8 @@ public class KeyAgreementActivity extends BriarActivity implements
 			// Should we show an explanation?
 			if (ActivityCompat.shouldShowRequestPermissionRationale(this,
 					CAMERA)) {
-				OnClickListener continueListener = new OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						requestPermission();
-					}
-				};
+				OnClickListener continueListener =
+						(dialog, which) -> requestPermission();
 				Builder builder = new Builder(this, style.BriarDialogTheme);
 				builder.setTitle(string.permission_camera_title);
 				builder.setMessage(string.permission_camera_request_body);
@@ -183,12 +178,8 @@ public class KeyAgreementActivity extends BriarActivity implements
 				if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
 						CAMERA)) {
 					// The user has permanently denied the request
-					OnClickListener cancelListener = new OnClickListener() {
-						@Override
-						public void onClick(DialogInterface dialog, int which) {
-							supportFinishAfterTransition();
-						}
-					};
+					OnClickListener cancelListener =
+							(dialog, which) -> supportFinishAfterTransition();
 					Builder builder = new Builder(this, style.BriarDialogTheme);
 					builder.setTitle(string.permission_camera_title);
 					builder.setMessage(string.permission_camera_denied_body);
@@ -214,77 +205,57 @@ public class KeyAgreementActivity extends BriarActivity implements
 	}
 
 	private void keyAgreementFinished(final KeyAgreementResult result) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				startContactExchange(result);
-			}
-		});
+		runOnUiThreadUnlessDestroyed(() -> startContactExchange(result));
 	}
 
 	private void startContactExchange(final KeyAgreementResult result) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				LocalAuthor localAuthor;
-				// Load the local pseudonym
-				try {
-					localAuthor = identityManager.getLocalAuthor();
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					contactExchangeFailed();
-					return;
-				}
-
-				// Exchange contact details
-				contactExchangeTask.startExchange(KeyAgreementActivity.this,
-						localAuthor, result.getMasterKey(),
-						result.getConnection(), result.getTransportId(),
-						result.wasAlice());
+		runOnDbThread(() -> {
+			LocalAuthor localAuthor;
+			// Load the local pseudonym
+			try {
+				localAuthor = identityManager.getLocalAuthor();
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				contactExchangeFailed();
+				return;
 			}
+
+			// Exchange contact details
+			contactExchangeTask.startExchange(KeyAgreementActivity.this,
+					localAuthor, result.getMasterKey(),
+					result.getConnection(), result.getTransportId(),
+					result.wasAlice());
 		});
 	}
 
 	@Override
 	public void contactExchangeSucceeded(final Author remoteAuthor) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				String contactName = remoteAuthor.getName();
-				String format = getString(R.string.contact_added_toast);
-				String text = String.format(format, contactName);
-				Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG)
-						.show();
-				supportFinishAfterTransition();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			String contactName = remoteAuthor.getName();
+			String format = getString(string.contact_added_toast);
+			String text = String.format(format, contactName);
+			Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG).show();
+			supportFinishAfterTransition();
 		});
 	}
 
 	@Override
 	public void duplicateContact(final Author remoteAuthor) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				String contactName = remoteAuthor.getName();
-				String format = getString(R.string.contact_already_exists);
-				String text = String.format(format, contactName);
-				Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG)
-						.show();
-				finish();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			String contactName = remoteAuthor.getName();
+			String format = getString(string.contact_already_exists);
+			String text = String.format(format, contactName);
+			Toast.makeText(KeyAgreementActivity.this, text, LENGTH_LONG).show();
+			finish();
 		});
 	}
 
 	@Override
 	public void contactExchangeFailed() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				Toast.makeText(KeyAgreementActivity.this,
-						R.string.contact_exchange_failed, LENGTH_LONG).show();
-				finish();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			Toast.makeText(KeyAgreementActivity.this,
+					string.contact_exchange_failed, LENGTH_LONG).show();
+			finish();
 		});
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java
index fbf6f53e41..413ffb9452 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/ShowQrCodeFragment.java
@@ -192,23 +192,17 @@ public class ShowQrCodeFragment extends BaseEventFragment
 		final KeyAgreementTask oldTask = task;
 		final KeyAgreementTask newTask = keyAgreementTaskFactory.createTask();
 		task = newTask;
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (oldTask != null) oldTask.stopListening();
-				newTask.listen();
-			}
+		ioExecutor.execute(() -> {
+			if (oldTask != null) oldTask.stopListening();
+			newTask.listen();
 		});
 	}
 
 	@UiThread
 	private void stopListening() {
 		final KeyAgreementTask oldTask = task;
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				if (oldTask != null) oldTask.stopListening();
-			}
+		ioExecutor.execute(() -> {
+			if (oldTask != null) oldTask.stopListening();
 		});
 	}
 
@@ -255,13 +249,9 @@ public class ShowQrCodeFragment extends BaseEventFragment
 			KeyAgreementAbortedEvent event = (KeyAgreementAbortedEvent) e;
 			keyAgreementAborted(event.didRemoteAbort());
 		} else if (e instanceof KeyAgreementFinishedEvent) {
-			runOnUiThreadUnlessDestroyed(new Runnable() {
-				@Override
-				public void run() {
-					mainProgressContainer.setVisibility(VISIBLE);
-					mainProgressTitle.setText(
-							R.string.exchanging_contact_details);
-				}
+			runOnUiThreadUnlessDestroyed(() -> {
+				mainProgressContainer.setVisibility(VISIBLE);
+				mainProgressTitle.setText(R.string.exchanging_contact_details);
 			});
 		}
 	}
@@ -297,75 +287,54 @@ public class ShowQrCodeFragment extends BaseEventFragment
 	}
 
 	private void setQrCode(final Payload localPayload) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				generateBitmapQR(localPayload);
-			}
-		});
+		runOnUiThreadUnlessDestroyed(() -> generateBitmapQR(localPayload));
 	}
 
 	private void keyAgreementFailed() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				reset();
-				// TODO show failure somewhere persistent?
-				Toast.makeText(getActivity(), R.string.connection_failed,
-						LENGTH_LONG).show();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			reset();
+			// TODO show failure somewhere persistent?
+			Toast.makeText(getActivity(), R.string.connection_failed,
+					LENGTH_LONG).show();
 		});
 	}
 
 	private void keyAgreementWaiting() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				status.setText(R.string.waiting_for_contact_to_scan);
-			}
-		});
+		runOnUiThreadUnlessDestroyed(
+				() -> status.setText(R.string.waiting_for_contact_to_scan));
 	}
 
 	private void keyAgreementStarted() {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				mainProgressContainer.setVisibility(VISIBLE);
-				mainProgressTitle.setText(R.string.authenticating_with_device);
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			mainProgressContainer.setVisibility(VISIBLE);
+			mainProgressTitle.setText(R.string.authenticating_with_device);
 		});
 	}
 
 	private void keyAgreementAborted(final boolean remoteAborted) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				reset();
-				mainProgressContainer.setVisibility(INVISIBLE);
-				mainProgressTitle.setText("");
-				// TODO show abort somewhere persistent?
-				Toast.makeText(getActivity(),
-						remoteAborted ? R.string.connection_aborted_remote :
-								R.string.connection_aborted_local, LENGTH_LONG)
-						.show();
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			reset();
+			mainProgressContainer.setVisibility(INVISIBLE);
+			mainProgressTitle.setText("");
+			// TODO show abort somewhere persistent?
+			Toast.makeText(getActivity(),
+					remoteAborted ? R.string.connection_aborted_remote :
+							R.string.connection_aborted_local, LENGTH_LONG)
+					.show();
 		});
 	}
 
 	@Override
 	public void handleResult(final Result result) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Got result from decoder");
-				// Ignore results until the KeyAgreementTask is ready
-				if (!gotLocalPayload) {
-					return;
-				}
-				if (!gotRemotePayload) {
-					gotRemotePayload = true;
-					qrCodeScanned(result.getText());
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			LOG.info("Got result from decoder");
+			// Ignore results until the KeyAgreementTask is ready
+			if (!gotLocalPayload) {
+				return;
+			}
+			if (!gotRemotePayload) {
+				gotRemotePayload = true;
+				qrCodeScanned(result.getText());
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java
index 26a5847a04..ec0ccb5721 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.login;
 
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
@@ -8,13 +7,10 @@ import android.support.design.widget.TextInputLayout;
 import android.support.v7.app.AlertDialog;
 import android.text.Editable;
 import android.text.TextWatcher;
-import android.view.KeyEvent;
 import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
 
 import org.briarproject.briar.R;
 import org.briarproject.briar.android.activity.ActivityComponent;
@@ -61,13 +57,9 @@ public class PasswordActivity extends BaseActivity {
 		progress = (ProgressBar) findViewById(R.id.progress_wheel);
 		input = (TextInputLayout) findViewById(R.id.password_layout);
 		password = (EditText) findViewById(R.id.edit_password);
-		password.setOnEditorActionListener(new OnEditorActionListener() {
-			@Override
-			public boolean onEditorAction(TextView v, int actionId,
-					KeyEvent event) {
-				validatePassword();
-				return true;
-			}
+		password.setOnEditorActionListener((v, actionId, event) -> {
+			validatePassword();
+			return true;
 		});
 		password.addTextChangedListener(new TextWatcher() {
 
@@ -131,12 +123,7 @@ public class PasswordActivity extends BaseActivity {
 		builder.setMessage(R.string.dialog_message_lost_password);
 		builder.setPositiveButton(R.string.cancel, null);
 		builder.setNegativeButton(R.string.delete,
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog, int which) {
-						deleteAccount();
-					}
-				});
+				(dialog, which) -> deleteAccount());
 		AlertDialog dialog = builder.create();
 		dialog.show();
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordControllerImpl.java
index e2a921d30e..fe3710b011 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/login/PasswordControllerImpl.java
@@ -50,16 +50,13 @@ public class PasswordControllerImpl extends ConfigControllerImpl
 	public void validatePassword(final String password,
 			final ResultHandler<Boolean> resultHandler) {
 		final byte[] encrypted = getEncryptedKey();
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				byte[] key = crypto.decryptWithPassword(encrypted, password);
-				if (key == null) {
-					resultHandler.onResult(false);
-				} else {
-					databaseConfig.setEncryptionKey(new SecretKey(key));
-					resultHandler.onResult(true);
-				}
+		cryptoExecutor.execute(() -> {
+			byte[] key = crypto.decryptWithPassword(encrypted, password);
+			if (key == null) {
+				resultHandler.onResult(false);
+			} else {
+				databaseConfig.setEncryptionKey(new SecretKey(key));
+				resultHandler.onResult(true);
 			}
 		});
 	}
@@ -68,18 +65,15 @@ public class PasswordControllerImpl extends ConfigControllerImpl
 	public void changePassword(final String password, final String newPassword,
 			final ResultHandler<Boolean> resultHandler) {
 		final byte[] encrypted = getEncryptedKey();
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				byte[] key = crypto.decryptWithPassword(encrypted, password);
-				if (key == null) {
-					resultHandler.onResult(false);
-				} else {
-					String hex =
-							encryptDatabaseKey(new SecretKey(key), newPassword);
-					storeEncryptedDatabaseKey(hex);
-					resultHandler.onResult(true);
-				}
+		cryptoExecutor.execute(() -> {
+			byte[] key = crypto.decryptWithPassword(encrypted, password);
+			if (key == null) {
+				resultHandler.onResult(false);
+			} else {
+				String hex =
+						encryptDatabaseKey(new SecretKey(key), newPassword);
+				storeEncryptedDatabaseKey(hex);
+				resultHandler.onResult(true);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java
index 7fb8a7f7c0..731cae02a7 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java
@@ -86,16 +86,13 @@ public class SetupControllerImpl extends PasswordControllerImpl
 	public void createAccount(final ResultHandler<Void> resultHandler) {
 		if (authorName == null || password == null)
 			throw new IllegalStateException();
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				databaseConfig.setLocalAuthorName(authorName);
-				SecretKey key = crypto.generateSecretKey();
-				databaseConfig.setEncryptionKey(key);
-				String hex = encryptDatabaseKey(key, password);
-				storeEncryptedDatabaseKey(hex);
-				resultHandler.onResult(null);
-			}
+		cryptoExecutor.execute(() -> {
+			databaseConfig.setLocalAuthorName(authorName);
+			SecretKey key = crypto.generateSecretKey();
+			databaseConfig.setEncryptionKey(key);
+			String hex = encryptDatabaseKey(key, password);
+			storeEncryptedDatabaseKey(hex);
+			resultHandler.onResult(null);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java
index b6557a693a..33c45d5552 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java
@@ -307,12 +307,9 @@ public class NavDrawerActivity extends BriarActivity implements
 							daysUntilExpiry, daysUntilExpiry));
 		}
 
-		expiryWarningClose.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				controller.expiryWarningDismissed();
-				expiryWarning.setVisibility(GONE);
-			}
+		expiryWarningClose.setOnClickListener(v -> {
+			controller.expiryWarningDismissed();
+			expiryWarning.setVisibility(GONE);
 		});
 
 		expiryWarning.setVisibility(VISIBLE);
@@ -411,16 +408,13 @@ public class NavDrawerActivity extends BriarActivity implements
 	}
 
 	private void setTransport(final TransportId id, final boolean enabled) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (transports == null || transportsAdapter == null) return;
-				for (Transport t : transports) {
-					if (t.id.equals(id)) {
-						t.enabled = enabled;
-						transportsAdapter.notifyDataSetChanged();
-						break;
-					}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (transports == null || transportsAdapter == null) return;
+			for (Transport t : transports) {
+				if (t.id.equals(id)) {
+					t.enabled = enabled;
+					transportsAdapter.notifyDataSetChanged();
+					break;
 				}
 			}
 		});
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerControllerImpl.java
index a47b158cc9..0fc85bb1c8 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerControllerImpl.java
@@ -98,71 +98,59 @@ public class NavDrawerControllerImpl extends DbControllerImpl
 
 	private void transportStateUpdate(final TransportId id,
 			final boolean enabled) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.stateUpdate(id, enabled);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.stateUpdate(id, enabled));
 	}
 
 	@Override
 	public void showExpiryWarning(final ResultHandler<ExpiryWarning> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings settings =
-							settingsManager.getSettings(SETTINGS_NAMESPACE);
-					int warningInt = settings.getInt(EXPIRY_DATE_WARNING, 0);
-					boolean showUpdate =
-							settings.getBoolean(EXPIRY_SHOW_UPDATE, true);
-
-					if (warningInt == 0) {
-						// we have not warned before
+		runOnDbThread(() -> {
+			try {
+				Settings settings =
+						settingsManager.getSettings(SETTINGS_NAMESPACE);
+				int warningInt = settings.getInt(EXPIRY_DATE_WARNING, 0);
+				boolean showUpdate =
+						settings.getBoolean(EXPIRY_SHOW_UPDATE, true);
+
+				if (warningInt == 0) {
+					// we have not warned before
+					handler.onResult(SHOW);
+				} else {
+					long warningLong = warningInt * 1000L;
+					long now = System.currentTimeMillis();
+					long daysSinceLastWarning =
+							(now - warningLong) / 1000 / 60 / 60 / 24;
+					long daysBeforeExpiry =
+							(EXPIRY_DATE - now) / 1000 / 60 / 60 / 24;
+
+					if (showUpdate) {
+						handler.onResult(UPDATE);
+					} else if (daysSinceLastWarning >= 30) {
+						handler.onResult(SHOW);
+					} else if (daysBeforeExpiry <= 3 &&
+							daysSinceLastWarning > 0) {
 						handler.onResult(SHOW);
 					} else {
-						long warningLong = warningInt * 1000L;
-						long now = System.currentTimeMillis();
-						long daysSinceLastWarning =
-								(now - warningLong) / 1000 / 60 / 60 / 24;
-						long daysBeforeExpiry =
-								(EXPIRY_DATE - now) / 1000 / 60 / 60 / 24;
-
-						if (showUpdate) {
-							handler.onResult(UPDATE);
-						} else if (daysSinceLastWarning >= 30) {
-							handler.onResult(SHOW);
-						} else if (daysBeforeExpiry <= 3 &&
-								daysSinceLastWarning > 0) {
-							handler.onResult(SHOW);
-						} else {
-							handler.onResult(NO);
-						}
+						handler.onResult(NO);
 					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	@Override
 	public void expiryWarningDismissed() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings settings = new Settings();
-					int date = (int) (System.currentTimeMillis() / 1000L);
-					settings.putInt(EXPIRY_DATE_WARNING, date);
-					settings.putBoolean(EXPIRY_SHOW_UPDATE, false);
-					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		runOnDbThread(() -> {
+			try {
+				Settings settings = new Settings();
+				int date = (int) (System.currentTimeMillis() / 1000L);
+				settings.putInt(EXPIRY_DATE_WARNING, date);
+				settings.putBoolean(EXPIRY_SHOW_UPDATE, false);
+				settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicPreferencesFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicPreferencesFragment.java
index f5184f5d80..010f5ecbf2 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicPreferencesFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicPreferencesFragment.java
@@ -12,7 +12,6 @@ import android.os.Bundle;
 import android.support.v7.app.AlertDialog;
 import android.support.v7.preference.CheckBoxPreference;
 import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceFragmentCompat;
 import android.text.TextUtils;
 
@@ -92,51 +91,39 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
 				entryValues.toArray(new CharSequence[entryValues.size()]));
 		panicAppPref.setDefaultValue(Panic.PACKAGE_NAME_NONE);
 
-		panicAppPref.setOnPreferenceChangeListener(
-				new Preference.OnPreferenceChangeListener() {
-					@Override
-					public boolean onPreferenceChange(Preference preference,
-							Object newValue) {
-						String packageName = (String) newValue;
-						PanicResponder.setTriggerPackageName(getActivity(),
-								packageName);
-						showPanicApp(packageName);
-
-						if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
-							lockPref.setEnabled(false);
-							purgePref.setChecked(false);
-							purgePref.setEnabled(false);
-							uninstallPref.setChecked(false);
-							uninstallPref.setEnabled(false);
-							getActivity().setResult(Activity.RESULT_CANCELED);
-						} else {
-							lockPref.setEnabled(true);
-							purgePref.setEnabled(true);
-							uninstallPref.setEnabled(true);
-						}
-
-						return true;
-					}
-				});
+		panicAppPref.setOnPreferenceChangeListener((preference, newValue) -> {
+			String packageName = (String) newValue;
+			PanicResponder.setTriggerPackageName(getActivity(), packageName);
+			showPanicApp(packageName);
+
+			if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
+				lockPref.setEnabled(false);
+				purgePref.setChecked(false);
+				purgePref.setEnabled(false);
+				uninstallPref.setChecked(false);
+				uninstallPref.setEnabled(false);
+				getActivity().setResult(Activity.RESULT_CANCELED);
+			} else {
+				lockPref.setEnabled(true);
+				purgePref.setEnabled(true);
+				uninstallPref.setEnabled(true);
+			}
+
+			return true;
+		});
 
 		if (entries.size() <= 1) {
-			panicAppPref.setOnPreferenceClickListener(
-					new Preference.OnPreferenceClickListener() {
-						@Override
-						public boolean onPreferenceClick(
-								Preference preference) {
-							Intent intent = new Intent(Intent.ACTION_VIEW);
-							intent.setData(Uri.parse(
-									"market://details?id=info.guardianproject.ripple"));
-							intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-							if (intent.resolveActivity(
-									getActivity().getPackageManager()) !=
-									null) {
-								startActivity(intent);
-							}
-							return true;
-						}
-					});
+			panicAppPref.setOnPreferenceClickListener(preference -> {
+				Intent intent = new Intent(Intent.ACTION_VIEW);
+				intent.setData(Uri.parse(
+						"market://details?id=info.guardianproject.ripple"));
+				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+				if (intent.resolveActivity(getActivity().getPackageManager())
+						!= null) {
+					startActivity(intent);
+				}
+				return true;
+			});
 		}
 	}
 
@@ -219,26 +206,15 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
 	}
 
 	private void showOptInDialog() {
-		DialogInterface.OnClickListener okListener =
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog,
-							int which) {
-						PanicResponder.setTriggerPackageName(getActivity());
-						showPanicApp(PanicResponder
-								.getTriggerPackageName(getActivity()));
-						getActivity().setResult(Activity.RESULT_OK);
-					}
-				};
-		DialogInterface.OnClickListener cancelListener =
-				new DialogInterface.OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialog,
-							int which) {
-						getActivity().setResult(Activity.RESULT_CANCELED);
-						getActivity().finish();
-					}
-				};
+		DialogInterface.OnClickListener okListener = (dialog, which) -> {
+			PanicResponder.setTriggerPackageName(getActivity());
+			showPanicApp(PanicResponder.getTriggerPackageName(getActivity()));
+			getActivity().setResult(Activity.RESULT_OK);
+		};
+		DialogInterface.OnClickListener cancelListener = (dialog, which) -> {
+			getActivity().setResult(Activity.RESULT_CANCELED);
+			getActivity().finish();
+		};
 
 		AlertDialog.Builder builder = new AlertDialog.Builder(getContext(),
 				R.style.BriarDialogTheme);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicResponderActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicResponderActivity.java
index 82534f99f7..dd122e1498 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicResponderActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/panic/PanicResponderActivity.java
@@ -93,18 +93,15 @@ public class PanicResponderActivity extends BriarActivity {
 	}
 
 	private void deleteAllData() {
-		androidExecutor.runOnBackgroundThread(new Runnable() {
-			@Override
-			public void run() {
-				configController.deleteAccount(PanicResponderActivity.this);
-				// TODO somehow delete/shred the database more thoroughly
-				PanicResponder.deleteAllAppData(PanicResponderActivity.this);
-
-				// nothing left to do after everything is deleted,
-				// so still sign out
-				LOG.info("Signing out...");
-				signOut(true);
-			}
+		androidExecutor.runOnBackgroundThread(() -> {
+			configController.deleteAccount(PanicResponderActivity.this);
+			// TODO somehow delete/shred the database more thoroughly
+			PanicResponder.deleteAllAppData(PanicResponderActivity.this);
+
+			// nothing left to do after everything is deleted,
+			// so still sign out
+			LOG.info("Signing out...");
+			signOut(true);
 		});
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java
index 4a8d1c83fa..8c5e503b2a 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupActivity.java
@@ -11,7 +11,6 @@ import android.support.v7.widget.Toolbar;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 
 import org.briarproject.bramble.api.contact.ContactId;
 import org.briarproject.bramble.api.db.DbException;
@@ -76,16 +75,12 @@ public class GroupActivity extends
 
 		// Open member list on Toolbar click
 		if (toolbar != null) {
-			toolbar.setOnClickListener(
-					new View.OnClickListener() {
-						@Override
-						public void onClick(View v) {
-							Intent i = new Intent(GroupActivity.this,
-									GroupMemberListActivity.class);
-							i.putExtra(GROUP_ID, groupId.getBytes());
-							startActivity(i);
-						}
-					});
+			toolbar.setOnClickListener(v -> {
+				Intent i1 = new Intent(GroupActivity.this,
+						GroupMemberListActivity.class);
+				i1.putExtra(GROUP_ID, groupId.getBytes());
+				startActivity(i1);
+			});
 		}
 
 		setGroupEnabled(false);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java
index a3e5c60e26..3d31ee5351 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java
@@ -85,24 +85,16 @@ class GroupControllerImpl extends
 				LOG.info("Group message received, adding...");
 				final GroupMessageItem item =
 						buildItem(g.getHeader(), g.getBody());
-				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						listener.onItemReceived(item);
-					}
-				});
+				listener.runOnUiThreadUnlessDestroyed(
+						() -> listener.onItemReceived(item));
 			}
 		} else if (e instanceof ContactRelationshipRevealedEvent) {
 			final ContactRelationshipRevealedEvent c =
 					(ContactRelationshipRevealedEvent) e;
 			if (getGroupId().equals(c.getGroupId())) {
-				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
+				listener.runOnUiThreadUnlessDestroyed(() ->
 						listener.onContactRelationshipRevealed(c.getMemberId(),
-								c.getContactId(), c.getVisibility());
-					}
-				});
+								c.getContactId(), c.getVisibility()));
 			}
 		} else if (e instanceof GroupInvitationResponseReceivedEvent) {
 			GroupInvitationResponseReceivedEvent g =
@@ -110,22 +102,14 @@ class GroupControllerImpl extends
 			final GroupInvitationResponse r =
 					(GroupInvitationResponse) g.getResponse();
 			if (getGroupId().equals(r.getShareableId()) && r.wasAccepted()) {
-				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						listener.onInvitationAccepted(r.getContactId());
-					}
-				});
+				listener.runOnUiThreadUnlessDestroyed(
+						() -> listener.onInvitationAccepted(r.getContactId()));
 			}
 		} else if (e instanceof GroupDissolvedEvent) {
 			GroupDissolvedEvent g = (GroupDissolvedEvent) e;
 			if (getGroupId().equals(g.getGroupId())) {
-				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						listener.onGroupDissolved();
-					}
-				});
+				listener.runOnUiThreadUnlessDestroyed(
+						() -> listener.onGroupDissolved());
 			}
 		}
 	}
@@ -158,23 +142,19 @@ class GroupControllerImpl extends
 	@Override
 	public void loadSharingContacts(
 			final ResultExceptionHandler<Collection<ContactId>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<GroupMember> members =
-							privateGroupManager.getMembers(getGroupId());
-					Collection<ContactId> contactIds = new ArrayList<>();
-					for (GroupMember m : members) {
-						if (m.getContactId() != null)
-							contactIds.add(m.getContactId());
-					}
-					handler.onResult(contactIds);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
+		runOnDbThread(() -> {
+			try {
+				Collection<GroupMember> members =
+						privateGroupManager.getMembers(getGroupId());
+				Collection<ContactId> contactIds = new ArrayList<>();
+				for (GroupMember m : members) {
+					if (m.getContactId() != null)
+						contactIds.add(m.getContactId());
 				}
+				handler.onResult(contactIds);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -183,26 +163,22 @@ class GroupControllerImpl extends
 	public void createAndStoreMessage(final String body,
 			@Nullable final GroupMessageItem parentItem,
 			final ResultExceptionHandler<GroupMessageItem, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor author = identityManager.getLocalAuthor();
-					MessageId parentId = null;
-					MessageId previousMsgId =
-							privateGroupManager.getPreviousMsgId(getGroupId());
-					GroupCount count =
-							privateGroupManager.getGroupCount(getGroupId());
-					long timestamp = count.getLatestMsgTime();
-					if (parentItem != null) parentId = parentItem.getId();
-					timestamp = max(clock.currentTimeMillis(), timestamp + 1);
-					createMessage(body, timestamp, parentId, author,
-							previousMsgId, handler);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor author = identityManager.getLocalAuthor();
+				MessageId parentId = null;
+				MessageId previousMsgId =
+						privateGroupManager.getPreviousMsgId(getGroupId());
+				GroupCount count =
+						privateGroupManager.getGroupCount(getGroupId());
+				long timestamp = count.getLatestMsgTime();
+				if (parentItem != null) parentId = parentItem.getId();
+				timestamp = max(clock.currentTimeMillis(), timestamp + 1);
+				createMessage(body, timestamp, parentId, author, previousMsgId,
+						handler);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -211,15 +187,12 @@ class GroupControllerImpl extends
 			final @Nullable MessageId parentId, final LocalAuthor author,
 			final MessageId previousMsgId,
 			final ResultExceptionHandler<GroupMessageItem, DbException> handler) {
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Creating group message...");
-				GroupMessage msg = groupMessageFactory
-						.createGroupMessage(getGroupId(), timestamp,
-								parentId, author, body, previousMsgId);
-				storePost(msg, body, handler);
-			}
+		cryptoExecutor.execute(() -> {
+			LOG.info("Creating group message...");
+			GroupMessage msg = groupMessageFactory
+					.createGroupMessage(getGroupId(), timestamp,
+							parentId, author, body, previousMsgId);
+			storePost(msg, body, handler);
 		});
 	}
 
@@ -246,17 +219,13 @@ class GroupControllerImpl extends
 	@Override
 	public void loadLocalAuthor(
 			final ResultExceptionHandler<LocalAuthor, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor author = identityManager.getLocalAuthor();
-					handler.onResult(author);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor author = identityManager.getLocalAuthor();
+				handler.onResult(author);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -264,18 +233,14 @@ class GroupControllerImpl extends
 	@Override
 	public void isDissolved(final
 	ResultExceptionHandler<Boolean, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					boolean isDissolved =
-							privateGroupManager.isDissolved(getGroupId());
-					handler.onResult(isDissolved);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				boolean isDissolved =
+						privateGroupManager.isDissolved(getGroupId());
+				handler.onResult(isDissolved);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java
index 2a694c55a2..b25fb0f963 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java
@@ -76,17 +76,13 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
 	@Override
 	public void createGroup(final String name,
 			final ResultExceptionHandler<GroupId, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor author = identityManager.getLocalAuthor();
-					createGroupAndMessages(author, name, handler);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor author = identityManager.getLocalAuthor();
+				createGroupAndMessages(author, name, handler);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -94,36 +90,29 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
 	private void createGroupAndMessages(final LocalAuthor author,
 			final String name,
 			final ResultExceptionHandler<GroupId, DbException> handler) {
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Creating group...");
-				PrivateGroup group =
-						groupFactory.createPrivateGroup(name, author);
-				LOG.info("Creating new join announcement...");
-				GroupMessage joinMsg = groupMessageFactory
-						.createJoinMessage(group.getId(),
-								clock.currentTimeMillis(), author);
-				storeGroup(group, joinMsg, handler);
-			}
+		cryptoExecutor.execute(() -> {
+			LOG.info("Creating group...");
+			PrivateGroup group =
+					groupFactory.createPrivateGroup(name, author);
+			LOG.info("Creating new join announcement...");
+			GroupMessage joinMsg =
+					groupMessageFactory.createJoinMessage(group.getId(),
+							clock.currentTimeMillis(), author);
+			storeGroup(group, joinMsg, handler);
 		});
 	}
 
 	private void storeGroup(final PrivateGroup group,
 			final GroupMessage joinMsg,
 			final ResultExceptionHandler<GroupId, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Adding group to database...");
-				try {
-					groupManager.addPrivateGroup(group, joinMsg, true);
-					handler.onResult(group.getId());
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			LOG.info("Adding group to database...");
+			try {
+				groupManager.addPrivateGroup(group, joinMsg, true);
+				handler.onResult(group.getId());
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -137,25 +126,21 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
 	public void sendInvitation(final GroupId g,
 			final Collection<ContactId> contactIds, final String message,
 			final ResultExceptionHandler<Void, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					LocalAuthor localAuthor = identityManager.getLocalAuthor();
-					List<Contact> contacts = new ArrayList<>();
-					for (ContactId c : contactIds) {
-						try {
-							contacts.add(contactManager.getContact(c));
-						} catch (NoSuchContactException e) {
-							// Continue
-						}
+		runOnDbThread(() -> {
+			try {
+				LocalAuthor localAuthor = identityManager.getLocalAuthor();
+				List<Contact> contacts = new ArrayList<>();
+				for (ContactId c : contactIds) {
+					try {
+						contacts.add(contactManager.getContact(c));
+					} catch (NoSuchContactException e) {
+						// Continue
 					}
-					signInvitations(g, localAuthor, contacts, message, handler);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+				signInvitations(g, localAuthor, contacts, message, handler);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -163,46 +148,39 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
 	private void signInvitations(final GroupId g, final LocalAuthor localAuthor,
 			final Collection<Contact> contacts, final String message,
 			final ResultExceptionHandler<Void, DbException> handler) {
-		cryptoExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				long timestamp = clock.currentTimeMillis();
-				List<InvitationContext> contexts = new ArrayList<>();
-				for (Contact c : contacts) {
-					byte[] signature = groupInvitationFactory.signInvitation(c,
-							g, timestamp, localAuthor.getPrivateKey());
-					contexts.add(new InvitationContext(c.getId(), timestamp,
-							signature));
-				}
-				sendInvitations(g, contexts, message, handler);
+		cryptoExecutor.execute(() -> {
+			long timestamp = clock.currentTimeMillis();
+			List<InvitationContext> contexts = new ArrayList<>();
+			for (Contact c : contacts) {
+				byte[] signature = groupInvitationFactory.signInvitation(c, g,
+						timestamp, localAuthor.getPrivateKey());
+				contexts.add(new InvitationContext(c.getId(), timestamp,
+						signature));
 			}
+			sendInvitations(g, contexts, message, handler);
 		});
 	}
 
 	private void sendInvitations(final GroupId g,
 			final Collection<InvitationContext> contexts, final String message,
 			final ResultExceptionHandler<Void, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					String msg = message.isEmpty() ? null : message;
-					for (InvitationContext context : contexts) {
-						try {
-							groupInvitationManager.sendInvitation(g,
-									context.contactId, msg, context.timestamp,
-									context.signature);
-						} catch (NoSuchContactException e) {
-							// Continue
-						}
+		runOnDbThread(() -> {
+			try {
+				String msg = message.isEmpty() ? null : message;
+				for (InvitationContext context : contexts) {
+					try {
+						groupInvitationManager.sendInvitation(g,
+								context.contactId, msg, context.timestamp,
+								context.signature);
+					} catch (NoSuchContactException e) {
+						// Continue
 					}
-					//noinspection ConstantConditions
-					handler.onResult(null);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+				//noinspection ConstantConditions
+				handler.onResult(null);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java
index f89db336bb..c8a6bac35d 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupFragment.java
@@ -5,16 +5,12 @@ import android.os.Bundle;
 import android.support.design.widget.TextInputLayout;
 import android.text.Editable;
 import android.text.TextWatcher;
-import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
 
 import org.briarproject.bramble.util.StringUtils;
 import org.briarproject.briar.R;
@@ -65,24 +61,15 @@ public class CreateGroupFragment extends BaseFragment {
 			public void afterTextChanged(Editable s) {
 			}
 		});
-		nameEntry.setOnEditorActionListener(new OnEditorActionListener() {
-			@Override
-			public boolean onEditorAction(TextView v, int actionId,
-					KeyEvent e) {
-				createGroup();
-				return true;
-			}
+		nameEntry.setOnEditorActionListener((v1, actionId, e) -> {
+			createGroup();
+			return true;
 		});
 
 		nameLayout = (TextInputLayout) v.findViewById(R.id.nameLayout);
 
 		createGroupButton = (Button) v.findViewById(R.id.button);
-		createGroupButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				createGroup();
-			}
-		});
+		createGroupButton.setOnClickListener(v1 -> createGroup());
 
 		progress = (ProgressBar) v.findViewById(R.id.progressBar);
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationControllerImpl.java
index b3b3f4c590..a7aa2a4a87 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/invitation/GroupInvitationControllerImpl.java
@@ -67,18 +67,14 @@ class GroupInvitationControllerImpl
 	public void respondToInvitation(final GroupInvitationItem item,
 			final boolean accept,
 			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					PrivateGroup g = item.getShareable();
-					ContactId c = item.getCreator().getId();
-					groupInvitationManager.respondToInvitation(c, g, accept);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				PrivateGroup g = item.getShareable();
+				ContactId c = item.getCreator().getId();
+				groupInvitationManager.respondToInvitation(c, g, accept);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java
index cbe85631eb..1e85778c81 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java
@@ -120,80 +120,54 @@ class GroupListControllerImpl extends DbControllerImpl
 	}
 
 	private void onGroupMessageAdded(final GroupMessageHeader h) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onGroupMessageAdded(h);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onGroupMessageAdded(h));
 	}
 
 	private void onGroupInvitationReceived() {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onGroupInvitationReceived();
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onGroupInvitationReceived());
 	}
 
 	private void onGroupAdded(final GroupId g) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onGroupAdded(g);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onGroupAdded(g));
 	}
 
 	private void onGroupRemoved(final GroupId g) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onGroupRemoved(g);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(() -> listener.onGroupRemoved(g));
 	}
 
 	private void onGroupDissolved(final GroupId g) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				listener.onGroupDissolved(g);
-			}
-		});
+		listener.runOnUiThreadUnlessDestroyed(
+				() -> listener.onGroupDissolved(g));
 	}
 
 	@Override
 	public void loadGroups(
 			final ResultExceptionHandler<Collection<GroupItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					Collection<PrivateGroup> groups =
-							groupManager.getPrivateGroups();
-					List<GroupItem> items = new ArrayList<>(groups.size());
-					for (PrivateGroup g : groups) {
-						try {
-							GroupId id = g.getId();
-							GroupCount count = groupManager.getGroupCount(id);
-							boolean dissolved = groupManager.isDissolved(id);
-							items.add(new GroupItem(g, count, dissolved));
-						} catch (NoSuchGroupException e) {
-							// Continue
-						}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				Collection<PrivateGroup> groups =
+						groupManager.getPrivateGroups();
+				List<GroupItem> items = new ArrayList<>(groups.size());
+				for (PrivateGroup g : groups) {
+					try {
+						GroupId id = g.getId();
+						GroupCount count = groupManager.getGroupCount(id);
+						boolean dissolved = groupManager.isDissolved(id);
+						items.add(new GroupItem(g, count, dissolved));
+					} catch (NoSuchGroupException e) {
+						// Continue
 					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading groups took " + duration + " ms");
-					handler.onResult(items);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading groups took " + duration + " ms");
+				handler.onResult(items);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -201,20 +175,16 @@ class GroupListControllerImpl extends DbControllerImpl
 	@Override
 	public void removeGroup(final GroupId g,
 			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					groupManager.removePrivateGroup(g);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Removing group took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				groupManager.removePrivateGroup(g);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Removing group took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -222,17 +192,13 @@ class GroupListControllerImpl extends DbControllerImpl
 	@Override
 	public void loadAvailableGroups(
 			final ResultExceptionHandler<Integer, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					handler.onResult(
-							groupInvitationManager.getInvitations().size());
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				handler.onResult(
+						groupInvitationManager.getInvitations().size());
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupViewHolder.java
index c137ad072d..3fa2d5ab4e 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupViewHolder.java
@@ -4,7 +4,6 @@ import android.content.Context;
 import android.content.Intent;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.TextView;
@@ -107,25 +106,17 @@ class GroupViewHolder extends RecyclerView.ViewHolder {
 			status
 					.setText(ctx.getString(R.string.groups_group_is_dissolved));
 			status.setVisibility(VISIBLE);
-			remove.setOnClickListener(new OnClickListener() {
-				@Override
-				public void onClick(View v) {
-					listener.onGroupRemoveClick(group);
-				}
-			});
+			remove.setOnClickListener(v -> listener.onGroupRemoveClick(group));
 			remove.setVisibility(VISIBLE);
 		}
 
 		// Open Group on Click
-		layout.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				Intent i = new Intent(ctx, GroupActivity.class);
-				GroupId id = group.getId();
-				i.putExtra(GROUP_ID, id.getBytes());
-				i.putExtra(GROUP_NAME, group.getName());
-				ctx.startActivity(i);
-			}
+		layout.setOnClickListener(v -> {
+			Intent i = new Intent(ctx, GroupActivity.class);
+			GroupId id = group.getId();
+			i.putExtra(GROUP_ID, id.getBytes());
+			i.putExtra(GROUP_NAME, group.getName());
+			ctx.startActivity(i);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java
index 69bc9ac519..0be3e5d072 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/memberlist/GroupMemberListControllerImpl.java
@@ -42,26 +42,22 @@ class GroupMemberListControllerImpl extends DbControllerImpl
 	@Override
 	public void loadMembers(final GroupId groupId, final
 			ResultExceptionHandler<Collection<MemberListItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<MemberListItem> items = new ArrayList<>();
-					Collection<GroupMember> members =
-							privateGroupManager.getMembers(groupId);
-					for (GroupMember m : members) {
-						ContactId c = m.getContactId();
-						boolean online = false;
-						if (c != null)
-							online = connectionRegistry.isConnected(c);
-						items.add(new MemberListItem(m, online));
-					}
-					handler.onResult(items);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
+		runOnDbThread(() -> {
+			try {
+				Collection<MemberListItem> items = new ArrayList<>();
+				Collection<GroupMember> members =
+						privateGroupManager.getMembers(groupId);
+				for (GroupMember m : members) {
+					ContactId c = m.getContactId();
+					boolean online = false;
+					if (c != null)
+						online = connectionRegistry.isConnected(c);
+					items.add(new MemberListItem(m, online));
 				}
+				handler.onResult(items);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsActivity.java
index 778802f726..79a287755b 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.privategroup.reveal;
 
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.annotation.LayoutRes;
@@ -110,19 +109,8 @@ public class RevealContactsActivity extends ContactSelectorActivity
 		new AlertDialog.Builder(this, R.style.OnboardingDialogTheme)
 				.setMessage(getString(R.string.groups_reveal_dialog_message))
 				.setNeutralButton(R.string.got_it,
-						new DialogInterface.OnClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog,
-									int which) {
-								dialog.cancel();
-							}
-						})
-				.setOnCancelListener(new DialogInterface.OnCancelListener() {
-					@Override
-					public void onCancel(DialogInterface dialog) {
-						onboardingShown();
-					}
-				})
+						(dialog, which) -> dialog.cancel())
+				.setOnCancelListener(dialog -> onboardingShown())
 				.show();
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java
index 279b80710a..5c181f2104 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java
@@ -62,18 +62,12 @@ class RevealContactsControllerImpl extends DbControllerImpl
 	public void loadContacts(final GroupId g,
 			final Collection<ContactId> selection,
 			final ResultExceptionHandler<Collection<RevealableContactItem>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Collection<RevealableContactItem> items =
-							getItems(g, selection);
-					handler.onResult(items);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				handler.onResult(getItems(g, selection));
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -105,38 +99,31 @@ class RevealContactsControllerImpl extends DbControllerImpl
 	@Override
 	public void isOnboardingNeeded(
 			final ResultExceptionHandler<Boolean, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings settings =
-							settingsManager.getSettings(SETTINGS_NAMESPACE);
-					handler.onResult(
-							settings.getBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS,
-									true));
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
-
+		runOnDbThread(() -> {
+			try {
+				Settings settings =
+						settingsManager.getSettings(SETTINGS_NAMESPACE);
+				handler.onResult(
+						settings.getBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS,
+								true));
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
+
 		});
 	}
 
 	@Override
 	public void onboardingShown(ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings settings = new Settings();
-					settings.putBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS, false);
-					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		runOnDbThread(() -> {
+			try {
+				Settings settings = new Settings();
+				settings.putBoolean(SHOW_ONBOARDING_REVEAL_CONTACTS, false);
+				settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -144,22 +131,19 @@ class RevealContactsControllerImpl extends DbControllerImpl
 	@Override
 	public void reveal(final GroupId g, final Collection<ContactId> contacts,
 			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				for (ContactId c : contacts) {
-					try {
-						groupInvitationManager.revealRelationship(c, g);
-					} catch (ProtocolStateException e) {
-						// action is outdated, move to next contact
-						if (LOG.isLoggable(INFO))
-							LOG.log(INFO, e.toString(), e);
-					} catch (DbException e) {
-						if (LOG.isLoggable(WARNING))
-							LOG.log(WARNING, e.toString(), e);
-						handler.onException(e);
-						break;
-					}
+		runOnDbThread(() -> {
+			for (ContactId c : contacts) {
+				try {
+					groupInvitationManager.revealRelationship(c, g);
+				} catch (ProtocolStateException e) {
+					// action is outdated, move to next contact
+					if (LOG.isLoggable(INFO))
+						LOG.log(INFO, e.toString(), e);
+				} catch (DbException e) {
+					if (LOG.isLoggable(WARNING))
+						LOG.log(WARNING, e.toString(), e);
+					handler.onException(e);
+					break;
 				}
 			}
 		});
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportPrimer.java b/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportPrimer.java
index 4d08fcb6a6..f74647eba6 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportPrimer.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportPrimer.java
@@ -256,12 +256,9 @@ public class BriarReportPrimer implements ReportPrimer {
 			Looper.prepare();
 			Handler handler = new Handler();
 			handler.post(runnable);
-			handler.post(new Runnable() {
-				@Override
-				public void run() {
-					Looper looper = Looper.myLooper();
-					if (looper != null) looper.quit();
-				}
+			handler.post(() -> {
+				Looper looper = Looper.myLooper();
+				if (looper != null) looper.quit();
 			});
 			Looper.loop();
 		}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/reporting/DevReportActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/reporting/DevReportActivity.java
index 82c21c0891..dab9165611 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/reporting/DevReportActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/reporting/DevReportActivity.java
@@ -1,6 +1,5 @@
 package org.briarproject.briar.android.reporting;
 
-import android.content.Context;
 import android.content.res.Configuration;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -37,6 +36,7 @@ import java.util.logging.Logger;
 import static android.view.View.GONE;
 import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
+import static android.view.inputmethod.InputMethodManager.SHOW_FORCED;
 import static java.util.logging.Level.WARNING;
 import static org.acra.ACRAConstants.EXTRA_REPORT_FILE;
 import static org.acra.ReportField.ANDROID_VERSION;
@@ -115,37 +115,22 @@ public class DevReportActivity extends BaseCrashReportDialog
 			includeDebugReport.setChecked(true);
 		}
 
-		findViewById(R.id.acceptButton).setOnClickListener(
-				new View.OnClickListener() {
-					@Override
-					public void onClick(View v) {
-						reviewing = true;
-						requestReport.setVisibility(GONE);
-						((InputMethodManager) getSystemService(
-								Context.INPUT_METHOD_SERVICE))
-								.showSoftInput(userCommentView,
-										InputMethodManager.SHOW_FORCED);
-					}
-				});
-		findViewById(R.id.declineButton).setOnClickListener(
-				new View.OnClickListener() {
-					@Override
-					public void onClick(View v) {
-						closeReport();
-					}
-				});
-		chevron.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				boolean show =
-						chevron.getText().equals(getString(R.string.show));
-				if (show) {
-					chevron.setText(R.string.hide);
-					refresh();
-				} else {
-					chevron.setText(R.string.show);
-					report.setVisibility(GONE);
-				}
+		findViewById(R.id.acceptButton).setOnClickListener(v -> {
+			reviewing = true;
+			requestReport.setVisibility(GONE);
+			((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
+					.showSoftInput(userCommentView, SHOW_FORCED);
+		});
+		findViewById(R.id.declineButton).setOnClickListener(v -> closeReport());
+		chevron.setOnClickListener(v -> {
+			boolean show =
+					chevron.getText().equals(getString(R.string.show));
+			if (show) {
+				chevron.setText(R.string.hide);
+				refresh();
+			} else {
+				chevron.setText(R.string.show);
+				report.setVisibility(GONE);
 			}
 		});
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java
index cff44bb8a5..baa0771e7f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java
@@ -141,54 +141,39 @@ public class SettingsFragment extends PreferenceFragmentCompat
 			notifyLockscreen.setVisible(true);
 			notifyLockscreen.setOnPreferenceChangeListener(this);
 		}
-		notifySound.setOnPreferenceClickListener(
-				new Preference.OnPreferenceClickListener() {
-					@Override
-					public boolean onPreferenceClick(Preference preference) {
-						String title =
-								getString(R.string.choose_ringtone_title);
-						Intent i = new Intent(ACTION_RINGTONE_PICKER);
-						i.putExtra(EXTRA_RINGTONE_TYPE, TYPE_NOTIFICATION);
-						i.putExtra(EXTRA_RINGTONE_TITLE, title);
-						i.putExtra(EXTRA_RINGTONE_DEFAULT_URI,
-								DEFAULT_NOTIFICATION_URI);
-						i.putExtra(EXTRA_RINGTONE_SHOW_SILENT, true);
-						if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) {
-							Uri uri;
-							String ringtoneUri =
-									settings.get(PREF_NOTIFY_RINGTONE_URI);
-							if (StringUtils.isNullOrEmpty(ringtoneUri))
-								uri = DEFAULT_NOTIFICATION_URI;
-							else uri = Uri.parse(ringtoneUri);
-							i.putExtra(EXTRA_RINGTONE_EXISTING_URI, uri);
-						}
-						startActivityForResult(i, REQUEST_RINGTONE);
-						return true;
-					}
-				});
+		notifySound.setOnPreferenceClickListener(preference -> {
+			String title = getString(R.string.choose_ringtone_title);
+			Intent i = new Intent(ACTION_RINGTONE_PICKER);
+			i.putExtra(EXTRA_RINGTONE_TYPE, TYPE_NOTIFICATION);
+			i.putExtra(EXTRA_RINGTONE_TITLE, title);
+			i.putExtra(EXTRA_RINGTONE_DEFAULT_URI, DEFAULT_NOTIFICATION_URI);
+			i.putExtra(EXTRA_RINGTONE_SHOW_SILENT, true);
+			if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) {
+				Uri uri;
+				String ringtoneUri = settings.get(PREF_NOTIFY_RINGTONE_URI);
+				if (StringUtils.isNullOrEmpty(ringtoneUri))
+					uri = DEFAULT_NOTIFICATION_URI;
+				else uri = Uri.parse(ringtoneUri);
+				i.putExtra(EXTRA_RINGTONE_EXISTING_URI, uri);
+			}
+			startActivityForResult(i, REQUEST_RINGTONE);
+			return true;
+		});
 
 		findPreference("pref_key_send_feedback").setOnPreferenceClickListener(
-				new Preference.OnPreferenceClickListener() {
-					@Override
-					public boolean onPreferenceClick(Preference preference) {
-						triggerFeedback();
-						return true;
-					}
+				preference -> {
+					triggerFeedback();
+					return true;
 				});
 
 		Preference testData = findPreference("pref_key_test_data");
 		if (IS_DEBUG_BUILD) {
-			testData.setOnPreferenceClickListener(
-					new Preference.OnPreferenceClickListener() {
-						@Override
-						public boolean onPreferenceClick(
-								Preference preference) {
-							LOG.info("Creating test data");
-							testDataCreator.createTestData();
-							getActivity().finish();
-							return true;
-						}
-					});
+			testData.setOnPreferenceClickListener(preference -> {
+				LOG.info("Creating test data");
+				testDataCreator.createTestData();
+				getActivity().finish();
+				return true;
+			});
 		} else {
 			testData.setVisible(false);
 		}
@@ -209,83 +194,69 @@ public class SettingsFragment extends PreferenceFragmentCompat
 	}
 
 	private void loadSettings() {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
-					Settings btSettings =
-							settingsManager.getSettings(BT_NAMESPACE);
-					Settings torSettings =
-							settingsManager.getSettings(TOR_NAMESPACE);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading settings took " + duration + " ms");
-					boolean btSetting =
-							btSettings.getBoolean(PREF_BT_ENABLE, false);
-					int torSetting = torSettings.getInt(PREF_TOR_NETWORK,
-							PREF_TOR_NETWORK_ALWAYS);
-					displaySettings(btSetting, torSetting);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		listener.runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
+				Settings btSettings = settingsManager.getSettings(BT_NAMESPACE);
+				Settings torSettings =
+						settingsManager.getSettings(TOR_NAMESPACE);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading settings took " + duration + " ms");
+				boolean btSetting =
+						btSettings.getBoolean(PREF_BT_ENABLE, false);
+				int torSetting = torSettings.getInt(PREF_TOR_NETWORK,
+						PREF_TOR_NETWORK_ALWAYS);
+				displaySettings(btSetting, torSetting);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void displaySettings(final boolean btSetting,
 			final int torSetting) {
-		listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				enableBluetooth.setValue(Boolean.toString(btSetting));
-				torNetwork.setValue(Integer.toString(torSetting));
-
-				notifyPrivateMessages.setChecked(settings.getBoolean(
-						PREF_NOTIFY_PRIVATE, true));
-
-				notifyGroupMessages.setChecked(settings.getBoolean(
-						PREF_NOTIFY_GROUP, true));
-
-				notifyForumPosts.setChecked(settings.getBoolean(
-						PREF_NOTIFY_FORUM, true));
-
-				notifyBlogPosts.setChecked(settings.getBoolean(
-						PREF_NOTIFY_BLOG, true));
-
-				notifyVibration.setChecked(settings.getBoolean(
-						PREF_NOTIFY_VIBRATION, true));
-
-				notifyLockscreen.setChecked(settings.getBoolean(
-						PREF_NOTIFY_LOCK_SCREEN, false));
-
-				String text;
-				if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) {
-					String ringtoneName =
-							settings.get(PREF_NOTIFY_RINGTONE_NAME);
-					if (StringUtils.isNullOrEmpty(ringtoneName)) {
-						text = getString(R.string.notify_sound_setting_default);
-					} else {
-						text = ringtoneName;
-					}
+		listener.runOnUiThreadUnlessDestroyed(() -> {
+			enableBluetooth.setValue(Boolean.toString(btSetting));
+			torNetwork.setValue(Integer.toString(torSetting));
+
+			notifyPrivateMessages.setChecked(settings.getBoolean(
+					PREF_NOTIFY_PRIVATE, true));
+
+			notifyGroupMessages.setChecked(settings.getBoolean(
+					PREF_NOTIFY_GROUP, true));
+
+			notifyForumPosts.setChecked(settings.getBoolean(
+					PREF_NOTIFY_FORUM, true));
+
+			notifyBlogPosts.setChecked(settings.getBoolean(
+					PREF_NOTIFY_BLOG, true));
+
+			notifyVibration.setChecked(settings.getBoolean(
+					PREF_NOTIFY_VIBRATION, true));
+
+			notifyLockscreen.setChecked(settings.getBoolean(
+					PREF_NOTIFY_LOCK_SCREEN, false));
+
+			String text;
+			if (settings.getBoolean(PREF_NOTIFY_SOUND, true)) {
+				String ringtoneName = settings.get(PREF_NOTIFY_RINGTONE_NAME);
+				if (StringUtils.isNullOrEmpty(ringtoneName)) {
+					text = getString(R.string.notify_sound_setting_default);
 				} else {
-					text = getString(R.string.notify_sound_setting_disabled);
+					text = ringtoneName;
 				}
-				notifySound.setSummary(text);
+			} else {
+				text = getString(R.string.notify_sound_setting_disabled);
 			}
+			notifySound.setSummary(text);
 		});
 	}
 
 	private void triggerFeedback() {
-		androidExecutor.runOnBackgroundThread(new Runnable() {
-			@Override
-			public void run() {
-				ACRA.getErrorReporter().handleException(new UserFeedback(),
-						false);
-			}
-		});
+		androidExecutor.runOnBackgroundThread(() -> ACRA.getErrorReporter()
+				.handleException(new UserFeedback(), false));
 	}
 
 	@Override
@@ -331,59 +302,47 @@ public class SettingsFragment extends PreferenceFragmentCompat
 	}
 
 	private void storeTorSettings(final int torSetting) {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings s = new Settings();
-					s.putInt(PREF_TOR_NETWORK, torSetting);
-					long now = System.currentTimeMillis();
-					settingsManager.mergeSettings(s, TOR_NAMESPACE);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Merging settings took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		listener.runOnDbThread(() -> {
+			try {
+				Settings s = new Settings();
+				s.putInt(PREF_TOR_NETWORK, torSetting);
+				long now = System.currentTimeMillis();
+				settingsManager.mergeSettings(s, TOR_NAMESPACE);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Merging settings took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void storeBluetoothSettings(final boolean btSetting) {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Settings s = new Settings();
-					s.putBoolean(PREF_BT_ENABLE, btSetting);
-					long now = System.currentTimeMillis();
-					settingsManager.mergeSettings(s, BT_NAMESPACE);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Merging settings took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		listener.runOnDbThread(() -> {
+			try {
+				Settings s = new Settings();
+				s.putBoolean(PREF_BT_ENABLE, btSetting);
+				long now = System.currentTimeMillis();
+				settingsManager.mergeSettings(s, BT_NAMESPACE);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Merging settings took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void storeSettings(final Settings settings) {
-		listener.runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Merging settings took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		listener.runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Merging settings took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogInvitationControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogInvitationControllerImpl.java
index 66adb424c4..609c5a0b03 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogInvitationControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/BlogInvitationControllerImpl.java
@@ -61,20 +61,16 @@ class BlogInvitationControllerImpl
 	public void respondToInvitation(final SharingInvitationItem item,
 			final boolean accept,
 			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Blog f = (Blog) item.getShareable();
-					for (Contact c : item.getNewSharers()) {
-						// TODO: What happens if a contact has been removed?
-						blogSharingManager.respondToInvitation(f, c, accept);
-					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
+		runOnDbThread(() -> {
+			try {
+				Blog f = (Blog) item.getShareable();
+				for (Contact c : item.getNewSharers()) {
+					// TODO: What happens if a contact has been removed?
+					blogSharingManager.respondToInvitation(f, c, accept);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumInvitationControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumInvitationControllerImpl.java
index 14e669f424..f6ce57adcb 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumInvitationControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ForumInvitationControllerImpl.java
@@ -62,20 +62,16 @@ class ForumInvitationControllerImpl
 	public void respondToInvitation(final SharingInvitationItem item,
 			final boolean accept,
 			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					Forum f = (Forum) item.getShareable();
-					for (Contact c : item.getNewSharers()) {
-						// TODO: What happens if a contact has been removed?
-						forumSharingManager.respondToInvitation(f, c, accept);
-					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
+		runOnDbThread(() -> {
+			try {
+				Forum f = (Forum) item.getShareable();
+				for (Contact c : item.getNewSharers()) {
+					// TODO: What happens if a contact has been removed?
+					forumSharingManager.respondToInvitation(f, c, accept);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationActivity.java
index 6f57eed9fe..dda2dee6b8 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationActivity.java
@@ -123,20 +123,17 @@ public abstract class InvitationActivity<I extends InvitationItem>
 
 	protected void displayInvitations(final int revision,
 			final Collection<I> invitations, final boolean clear) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (invitations.isEmpty()) {
-					LOG.info("No more invitations available, finishing");
-					supportFinishAfterTransition();
-				} else if (revision == adapter.getRevision()) {
-					adapter.incrementRevision();
-					if (clear) adapter.setItems(invitations);
-					else adapter.addAll(invitations);
-				} else {
-					LOG.info("Concurrent update, reloading");
-					loadInvitations(clear);
-				}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (invitations.isEmpty()) {
+				LOG.info("No more invitations available, finishing");
+				supportFinishAfterTransition();
+			} else if (revision == adapter.getRevision()) {
+				adapter.incrementRevision();
+				if (clear) adapter.setItems(invitations);
+				else adapter.addAll(invitations);
+			} else {
+				LOG.info("Concurrent update, reloading");
+				loadInvitations(clear);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationControllerImpl.java
index 0c0a9f426d..b0e7f99787 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationControllerImpl.java
@@ -93,23 +93,18 @@ public abstract class InvitationControllerImpl<I extends InvitationItem>
 	@Override
 	public void loadInvitations(final boolean clear,
 			final ResultExceptionHandler<Collection<I>, DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				Collection<I> invitations = new ArrayList<>();
-				try {
-					long now = System.currentTimeMillis();
-					invitations.addAll(getInvitations());
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info(
-								"Loading invitations took " + duration + " ms");
-					handler.onResult(invitations);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			Collection<I> invitations = new ArrayList<>();
+			try {
+				long now = System.currentTimeMillis();
+				invitations.addAll(getInvitations());
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading invitations took " + duration + " ms");
+				handler.onResult(invitations);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationViewHolder.java
index 80adcfce29..00262f0dbf 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/InvitationViewHolder.java
@@ -53,18 +53,8 @@ public class InvitationViewHolder<I extends InvitationItem>
 			subscribed.setVisibility(GONE);
 		}
 
-		accept.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				listener.onItemClick(item, true);
-			}
-		});
-		decline.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				listener.onItemClick(item, false);
-			}
-		});
+		accept.setOnClickListener(v -> listener.onItemClick(item, true));
+		decline.setOnClickListener(v -> listener.onItemClick(item, false));
 	}
 
 }
\ No newline at end of file
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java
index 4f19691f78..1bd0d8f3b8 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java
@@ -58,27 +58,23 @@ class ShareBlogControllerImpl extends ContactSelectorControllerImpl
 	public void share(final GroupId g, final Collection<ContactId> contacts,
 			final String message,
 			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					String msg = isNullOrEmpty(message) ? null : message;
-					for (ContactId c : contacts) {
-						try {
-							long time = Math.max(clock.currentTimeMillis(),
-									conversationManager.getGroupCount(c)
-											.getLatestMsgTime() + 1);
-							blogSharingManager.sendInvitation(g, c, msg, time);
-						} catch (NoSuchContactException | NoSuchGroupException e) {
-							if (LOG.isLoggable(WARNING))
-								LOG.log(WARNING, e.toString(), e);
-						}
+		runOnDbThread(() -> {
+			try {
+				String msg = isNullOrEmpty(message) ? null : message;
+				for (ContactId c : contacts) {
+					try {
+						long time = Math.max(clock.currentTimeMillis(),
+								conversationManager.getGroupCount(c)
+										.getLatestMsgTime() + 1);
+						blogSharingManager.sendInvitation(g, c, msg, time);
+					} catch (NoSuchContactException | NoSuchGroupException e) {
+						if (LOG.isLoggable(WARNING))
+							LOG.log(WARNING, e.toString(), e);
 					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java
index 9770d3bc18..e8fb5a4be7 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java
@@ -58,27 +58,23 @@ class ShareForumControllerImpl extends ContactSelectorControllerImpl
 	public void share(final GroupId g, final Collection<ContactId> contacts,
 			final String message,
 			final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					String msg = isNullOrEmpty(message) ? null : message;
-					for (ContactId c : contacts) {
-						try {
-							long time = Math.max(clock.currentTimeMillis(),
-									conversationManager.getGroupCount(c)
-											.getLatestMsgTime() + 1);
-							forumSharingManager.sendInvitation(g, c, msg, time);
-						} catch (NoSuchContactException | NoSuchGroupException e) {
-							if (LOG.isLoggable(WARNING))
-								LOG.log(WARNING, e.toString(), e);
-						}
+		runOnDbThread(() -> {
+			try {
+				String msg = isNullOrEmpty(message) ? null : message;
+				for (ContactId c : contacts) {
+					try {
+						long time = Math.max(clock.currentTimeMillis(),
+								conversationManager.getGroupCount(c)
+										.getLatestMsgTime() + 1);
+						forumSharingManager.sendInvitation(g, c, msg, time);
+					} catch (NoSuchContactException | NoSuchGroupException e) {
+						if (LOG.isLoggable(WARNING))
+							LOG.log(WARNING, e.toString(), e);
 					}
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java
index b07895d939..1b62d59220 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java
@@ -100,33 +100,25 @@ abstract class SharingStatusActivity extends BriarActivity {
 	}
 
 	private void loadSharedWith() {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					List<ContactItem> contactItems = new ArrayList<>();
-					for (Contact c : getSharedWith()) {
-						boolean online =
-								connectionRegistry.isConnected(c.getId());
-						ContactItem item = new ContactItem(c, online);
-						contactItems.add(item);
-					}
-					displaySharedWith(contactItems);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+		runOnDbThread(() -> {
+			try {
+				List<ContactItem> contactItems = new ArrayList<>();
+				for (Contact c : getSharedWith()) {
+					boolean online = connectionRegistry.isConnected(c.getId());
+					ContactItem item = new ContactItem(c, online);
+					contactItems.add(item);
 				}
+				displaySharedWith(contactItems);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
 
 	private void displaySharedWith(final List<ContactItem> contacts) {
-		runOnUiThreadUnlessDestroyed(new Runnable() {
-			@Override
-			public void run() {
-				if (contacts.isEmpty()) list.showData();
-				else adapter.addAll(contacts);
-			}
+		runOnUiThreadUnlessDestroyed(() -> {
+			if (contacts.isEmpty()) list.showData();
+			else adapter.addAll(contacts);
 		});
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java
index 04fffbaf10..7c19f3c780 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java
@@ -43,12 +43,9 @@ public class SplashScreenActivity extends BaseActivity {
 
 		setContentView(R.layout.splash);
 
-		new Handler().postDelayed(new Runnable() {
-			@Override
-			public void run() {
-				startNextActivity();
-				supportFinishAfterTransition();
-			}
+		new Handler().postDelayed(() -> {
+			startNextActivity();
+			supportFinishAfterTransition();
 		}, 500);
 	}
 
@@ -72,12 +69,8 @@ public class SplashScreenActivity extends BaseActivity {
 	}
 
 	private void setPreferencesDefaults() {
-		androidExecutor.runOnBackgroundThread(new Runnable() {
-			@Override
-			public void run() {
+		androidExecutor.runOnBackgroundThread(() ->
 				PreferenceManager.setDefaultValues(SplashScreenActivity.this,
-						R.xml.panic_preferences, false);
-			}
-		});
+						R.xml.panic_preferences, false));
 	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java
index b7fdeff1af..6f99a54cdf 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/BaseThreadItemViewHolder.java
@@ -85,13 +85,8 @@ public abstract class BaseThreadItemViewHolder<I extends ThreadItem>
 			public void onAnimationRepeat(Animator animation) {
 			}
 		});
-		anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-			@Override
-			public void onAnimationUpdate(ValueAnimator valueAnimator) {
-				layout.setBackgroundColor(
-						(Integer) valueAnimator.getAnimatedValue());
-			}
-		});
+		anim.addUpdateListener(valueAnimator -> layout.setBackgroundColor(
+				(Integer) valueAnimator.getAnimatedValue()));
 		anim.setDuration(ANIMATION_DURATION);
 		anim.start();
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java
index 829ba292cc..525f26fc2d 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListActivity.java
@@ -10,7 +10,6 @@ import android.support.v7.app.ActionBar;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.view.MenuItem;
-import android.view.View;
 
 import org.briarproject.bramble.api.contact.ContactId;
 import org.briarproject.bramble.api.db.DbException;
@@ -117,22 +116,16 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
 				});
 		upButton = (UnreadMessageButton) findViewById(R.id.upButton);
 		downButton = (UnreadMessageButton) findViewById(R.id.downButton);
-		upButton.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				int position = adapter.getVisibleUnreadPosTop();
-				if (position != NO_POSITION) {
-					list.getRecyclerView().scrollToPosition(position);
-				}
+		upButton.setOnClickListener(v -> {
+			int position = adapter.getVisibleUnreadPosTop();
+			if (position != NO_POSITION) {
+				list.getRecyclerView().scrollToPosition(position);
 			}
 		});
-		downButton.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				int position = adapter.getVisibleUnreadPosBottom();
-				if (position != NO_POSITION) {
-					list.getRecyclerView().scrollToPosition(position);
-				}
+		downButton.setOnClickListener(v -> {
+			int position = adapter.getVisibleUnreadPosBottom();
+			if (position != NO_POSITION) {
+				list.getRecyclerView().scrollToPosition(position);
 			}
 		});
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java
index 26bb1aff32..d58a536284 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadListControllerImpl.java
@@ -101,16 +101,12 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 	public void onActivityDestroy() {
 		final MessageId messageId = listener.getFirstVisibleMessageId();
 		if (messageId != null) {
-			dbExecutor.execute(new Runnable() {
-				@Override
-				public void run() {
-					try {
-						messageTracker
-								.storeMessageId(groupId, messageId);
-					} catch (DbException e) {
-						if (LOG.isLoggable(WARNING))
-							LOG.log(WARNING, e.toString(), e);
-					}
+			dbExecutor.execute(() -> {
+				try {
+					messageTracker.storeMessageId(groupId, messageId);
+				} catch (DbException e) {
+					if (LOG.isLoggable(WARNING))
+						LOG.log(WARNING, e.toString(), e);
 				}
 			});
 		}
@@ -123,12 +119,8 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 			GroupRemovedEvent s = (GroupRemovedEvent) e;
 			if (s.getGroup().getId().equals(getGroupId())) {
 				LOG.info("Group removed");
-				listener.runOnUiThreadUnlessDestroyed(new Runnable() {
-					@Override
-					public void run() {
-						listener.onGroupRemoved();
-					}
-				});
+				listener.runOnUiThreadUnlessDestroyed(
+						() -> listener.onGroupRemoved());
 			}
 		}
 	}
@@ -137,21 +129,18 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 	public void loadNamedGroup(
 			final ResultExceptionHandler<G, DbException> handler) {
 		checkGroupId();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					G groupItem = loadNamedGroup();
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading group took " + duration + " ms");
-					handler.onResult(groupItem);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				G groupItem = loadNamedGroup();
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading group took " + duration + " ms");
+				handler.onResult(groupItem);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -163,36 +152,32 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 	public void loadItems(
 			final ResultExceptionHandler<ThreadItemList<I>, DbException> handler) {
 		checkGroupId();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					// Load headers
-					long now = System.currentTimeMillis();
-					Collection<H> headers = loadHeaders();
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading headers took " + duration + " ms");
-
-					// Load bodies into cache
-					now = System.currentTimeMillis();
-					for (H header : headers) {
-						if (!bodyCache.containsKey(header.getId())) {
-							bodyCache.put(header.getId(),
-									loadMessageBody(header));
-						}
+		runOnDbThread(() -> {
+			try {
+				// Load headers
+				long now = System.currentTimeMillis();
+				Collection<H> headers = loadHeaders();
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading headers took " + duration + " ms");
+
+				// Load bodies into cache
+				now = System.currentTimeMillis();
+				for (H header : headers) {
+					if (!bodyCache.containsKey(header.getId())) {
+						bodyCache.put(header.getId(),
+								loadMessageBody(header));
 					}
-					duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading bodies took " + duration + " ms");
-
-					// Build and hand over items
-					handler.onResult(buildItems(headers));
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
 				}
+				duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading bodies took " + duration + " ms");
+
+				// Build and hand over items
+				handler.onResult(buildItems(headers));
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
@@ -210,21 +195,17 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 
 	@Override
 	public void markItemsRead(final Collection<I> items) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					for (I i : items) {
-						markRead(i.getId());
-					}
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Marking read took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				for (I i : items) {
+					markRead(i.getId());
 				}
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Marking read took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
@@ -234,22 +215,18 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 
 	protected void storePost(final M msg, final String body,
 			final ResultExceptionHandler<I, DbException> resultHandler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					H header = addLocalMessage(msg);
-					bodyCache.put(msg.getMessage().getId(), body);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Storing message took " + duration + " ms");
-					resultHandler.onResult(buildItem(header, body));
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					resultHandler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				H header = addLocalMessage(msg);
+				bodyCache.put(msg.getMessage().getId(), body);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Storing message took " + duration + " ms");
+				resultHandler.onResult(buildItem(header, body));
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				resultHandler.onException(e);
 			}
 		});
 	}
@@ -259,21 +236,17 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
 
 	@Override
 	public void deleteNamedGroup(final ExceptionHandler<DbException> handler) {
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					long now = System.currentTimeMillis();
-					G groupItem = loadNamedGroup();
-					deleteNamedGroup(groupItem);
-					long duration = System.currentTimeMillis() - now;
-					if (LOG.isLoggable(INFO))
-						LOG.info("Removing group took " + duration + " ms");
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
+		runOnDbThread(() -> {
+			try {
+				long now = System.currentTimeMillis();
+				G groupItem = loadNamedGroup();
+				deleteNamedGroup(groupItem);
+				long duration = System.currentTimeMillis() - now;
+				if (LOG.isLoggable(INFO))
+					LOG.info("Removing group took " + duration + " ms");
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+				handler.onException(e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java
index 5719f9a0e0..08a2dcb8ae 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/threaded/ThreadPostViewHolder.java
@@ -50,12 +50,7 @@ public class ThreadPostViewHolder<I extends ThreadItem>
 			lvlText.setVisibility(GONE);
 		}
 
-		replyButton.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				listener.onReplyClick(item);
-			}
-		});
+		replyButton.setOnClickListener(v -> listener.onReplyClick(item));
 	}
 
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
index 61991d6e66..b94420a959 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java
@@ -3,7 +3,6 @@ package org.briarproject.briar.android.util;
 import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.net.Uri;
@@ -143,16 +142,13 @@ public class UiUtils {
 
 	public static OnClickListener getGoToSettingsListener(
 			final Context context) {
-		return new OnClickListener() {
-			@Override
-			public void onClick(DialogInterface dialog, int which) {
-				Intent i = new Intent();
-				i.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
-				i.addCategory(CATEGORY_DEFAULT);
-				i.setData(Uri.parse("package:" + APPLICATION_ID));
-				i.addFlags(FLAG_ACTIVITY_NEW_TASK);
-				context.startActivity(i);
-			}
+		return (dialog, which) -> {
+			Intent i = new Intent();
+			i.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
+			i.addCategory(CATEGORY_DEFAULT);
+			i.setData(Uri.parse("package:" + APPLICATION_ID));
+			i.addFlags(FLAG_ACTIVITY_NEW_TASK);
+			context.startActivity(i);
 		};
 	}
 
@@ -160,13 +156,7 @@ public class UiUtils {
 		new AlertDialog.Builder(ctx, R.style.OnboardingDialogTheme)
 				.setMessage(text)
 				.setNeutralButton(R.string.got_it,
-						new DialogInterface.OnClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog,
-									int which) {
-								dialog.cancel();
-							}
-						})
+						(dialog, which) -> dialog.cancel())
 				.show();
 	}
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java b/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java
index cd3db7420e..d90b7f2c62 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java
@@ -94,24 +94,13 @@ public class BriarRecyclerView extends FrameLayout {
 	}
 
 	private void addLayoutChangeListener() {
-		recyclerView.addOnLayoutChangeListener(
-				new OnLayoutChangeListener() {
-					@Override
-					public void onLayoutChange(View v, int left, int top,
-							int right, int bottom, int oldLeft, int oldTop,
-							int oldRight, int oldBottom) {
-						if (bottom < oldBottom) {
-							recyclerView.postDelayed(new Runnable() {
-								@Override
-								public void run() {
-									scrollToPosition(
-											recyclerView.getAdapter()
-													.getItemCount() - 1);
-								}
-							}, 100);
-						}
-					}
-				});
+		recyclerView.addOnLayoutChangeListener((v, left, top, right, bottom,
+				oldLeft, oldTop, oldRight, oldBottom) -> {
+			if (bottom < oldBottom) {
+				recyclerView.postDelayed(() -> scrollToPosition(
+						recyclerView.getAdapter().getItemCount() - 1), 100);
+			}
+		});
 	}
 
 	public void setLayoutManager(RecyclerView.LayoutManager layout) {
@@ -191,14 +180,11 @@ public class BriarRecyclerView extends FrameLayout {
 		if (recyclerView == null || recyclerView.getAdapter() == null) {
 			throw new IllegalStateException("Need to call setAdapter() first!");
 		}
-		refresher = new Runnable() {
-			@Override
-			public void run() {
-				LOG.info("Updating Content...");
-				Adapter adapter = recyclerView.getAdapter();
-				adapter.notifyItemRangeChanged(0, adapter.getItemCount());
-				handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
-			}
+		refresher = () -> {
+			LOG.info("Updating Content...");
+			Adapter adapter = recyclerView.getAdapter();
+			adapter.notifyItemRangeChanged(0, adapter.getItemCount());
+			handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
 		};
 		LOG.info("Adding Handler Callback");
 		handler.postDelayed(refresher, MIN_DATE_RESOLUTION);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java b/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java
index 033747179f..ce97e11fb8 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/view/TextInputView.java
@@ -75,34 +75,18 @@ public class TextInputView extends KeyboardAwareLinearLayout
 		}
 
 		ui.emojiToggle.attach(ui.emojiDrawer);
-		ui.emojiToggle.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				onEmojiToggleClicked();
+		ui.emojiToggle.setOnClickListener(v -> onEmojiToggleClicked());
+		ui.editText.setOnClickListener(v -> showSoftKeyboard());
+		ui.editText.setOnKeyListener((v, keyCode, event) -> {
+			if (keyCode == KEYCODE_BACK && isEmojiDrawerOpen()) {
+				hideEmojiDrawer();
+				return true;
 			}
+			return false;
 		});
-		ui.editText.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				showSoftKeyboard();
-			}
-		});
-		ui.editText.setOnKeyListener(new OnKeyListener() {
-			@Override
-			public boolean onKey(View v, int keyCode, KeyEvent event) {
-				if (keyCode == KEYCODE_BACK && isEmojiDrawerOpen()) {
-					hideEmojiDrawer();
-					return true;
-				}
-				return false;
-			}
-		});
-		ui.sendButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				if (listener != null) {
-					listener.onSendClick(ui.editText.getText().toString());
-				}
+		ui.sendButton.setOnClickListener(v -> {
+			if (listener != null) {
+				listener.onSendClick(ui.editText.getText().toString());
 			}
 		});
 		ui.emojiDrawer.setEmojiEventListener(this);
@@ -167,22 +151,13 @@ public class TextInputView extends KeyboardAwareLinearLayout
 		if (isKeyboardOpen()) return;
 
 		if (ui.emojiDrawer.isShowing()) {
-			postOnKeyboardOpen(new Runnable() {
-				@Override
-				public void run() {
-					hideEmojiDrawer();
-				}
-			});
+			postOnKeyboardOpen(this::hideEmojiDrawer);
 		}
-		ui.editText.post(new Runnable() {
-			@Override
-			public void run() {
-				ui.editText.requestFocus();
-				InputMethodManager imm =
-						(InputMethodManager) getContext()
-								.getSystemService(INPUT_METHOD_SERVICE);
-				imm.showSoftInput(ui.editText, SHOW_IMPLICIT);
-			}
+		ui.editText.post(() -> {
+			ui.editText.requestFocus();
+			InputMethodManager imm = (InputMethodManager)
+					getContext().getSystemService(INPUT_METHOD_SERVICE);
+			imm.showSoftInput(ui.editText, SHOW_IMPLICIT);
 		});
 	}
 
@@ -194,11 +169,7 @@ public class TextInputView extends KeyboardAwareLinearLayout
 
 	public void showEmojiDrawer() {
 		if (isKeyboardOpen()) {
-			postOnKeyboardClose(new Runnable() {
-				@Override public void run() {
-					ui.emojiDrawer.show(getKeyboardHeight());
-				}
-			});
+			postOnKeyboardClose(() -> ui.emojiDrawer.show(getKeyboardHeight()));
 			hideSoftKeyboard();
 		} else {
 			ui.emojiDrawer.show(getKeyboardHeight());
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/widget/LinkDialogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/widget/LinkDialogFragment.java
index 1370574f37..7f3cec5264 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/widget/LinkDialogFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/widget/LinkDialogFragment.java
@@ -8,7 +8,6 @@ import android.os.Bundle;
 import android.support.v4.app.DialogFragment;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.TextView;
@@ -62,21 +61,13 @@ public class LinkDialogFragment extends DialogFragment {
 				getString(R.string.link_warning_open_link)) : i;
 
 		Button openButton = (Button) v.findViewById(R.id.openButton);
-		openButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				startActivity(intent);
-				getDialog().dismiss();
-			}
+		openButton.setOnClickListener(v1 -> {
+			startActivity(intent);
+			getDialog().dismiss();
 		});
 
 		Button cancelButton = (Button) v.findViewById(R.id.cancelButton);
-		cancelButton.setOnClickListener(new OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				getDialog().cancel();
-			}
-		});
+		cancelButton.setOnClickListener(v1 -> getDialog().cancel());
 
 		return v;
 	}
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java
index 44c959184d..8061b80819 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java
@@ -18,7 +18,6 @@ import com.astuetz.PagerSlidingTabStrip.CustomTabProvider;
 
 import org.briarproject.briar.R;
 import org.thoughtcrime.securesms.components.RepeatableImageKey;
-import org.thoughtcrime.securesms.components.RepeatableImageKey.KeyEventListener;
 import org.thoughtcrime.securesms.components.emoji.EmojiPageView.EmojiSelectionListener;
 
 import java.util.LinkedList;
@@ -78,11 +77,8 @@ public class EmojiDrawer extends LinearLayout {
 
 		RepeatableImageKey backspace =
 				(RepeatableImageKey) v.findViewById(R.id.backspace);
-		backspace.setOnKeyEventListener(new KeyEventListener() {
-			@Override
-			public void onKeyEvent() {
-				if (listener != null) listener.onKeyEvent(DELETE_KEY_EVENT);
-			}
+		backspace.setOnKeyEventListener(() -> {
+			if (listener != null) listener.onKeyEvent(DELETE_KEY_EVENT);
 		});
 	}
 
@@ -107,14 +103,10 @@ public class EmojiDrawer extends LinearLayout {
 	}
 
 	private void initializeEmojiGrid() {
-		pager.setAdapter(new EmojiPagerAdapter(getContext(),
-				models,
-				new EmojiSelectionListener() {
-					@Override
-					public void onEmojiSelected(String emoji) {
-						recentModel.onCodePointSelected(emoji);
-						if (listener != null) listener.onEmojiSelected(emoji);
-					}
+		pager.setAdapter(new EmojiPagerAdapter(getContext(), models,
+				emoji -> {
+					recentModel.onCodePointSelected(emoji);
+					if (listener != null) listener.onEmojiSelected(emoji);
 				}));
 
 		if (recentModel.getEmoji().length == 0) {
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java
index c006793018..12c9e74b31 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/emoji/EmojiPageView.java
@@ -7,8 +7,6 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AbsListView;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
 import android.widget.BaseAdapter;
 import android.widget.FrameLayout;
 import android.widget.GridView;
@@ -42,13 +40,9 @@ public class EmojiPageView extends FrameLayout {
 				.getDimensionPixelSize(R.dimen.emoji_drawer_size) + 2 *
 				getResources().getDimensionPixelSize(
 						R.dimen.emoji_drawer_item_padding));
-		grid.setOnItemClickListener(new OnItemClickListener() {
-			@Override
-			public void onItemClick(AdapterView<?> parent, View view,
-					int position, long id) {
-				if (listener != null)
-					listener.onEmojiSelected(((EmojiView) view).getEmoji());
-			}
+		grid.setOnItemClickListener((parent, view1, position, id) -> {
+			if (listener != null)
+				listener.onEmojiSelected(((EmojiView) view1).getEmoji());
 		});
 	}
 
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 c479ee1685..f6dfa241d4 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
@@ -139,12 +139,7 @@ public class EmojiProvider {
 		drawInfo.page.get().addListener(new FutureTaskListener<Bitmap>() {
 			@Override
 			public void onSuccess(final Bitmap result) {
-				androidExecutor.runOnUiThread(new Runnable() {
-					@Override
-					public void run() {
-						drawable.setBitmap(result);
-					}
-				});
+				androidExecutor.runOnUiThread(() -> drawable.setBitmap(result));
 			}
 
 			@Override
@@ -260,14 +255,10 @@ public class EmojiProvider {
 				if (bitmap != null) return new ListenableFutureTask<>(bitmap);
 			}
 			if (task != null) return task;
-			Callable<Bitmap> callable = new Callable<Bitmap>() {
-				@Override
-				@Nullable
-				public Bitmap call() throws Exception {
-					if (LOG.isLoggable(INFO))
-						LOG.info("Loading page " + model.getSprite());
-					return loadPage();
-				}
+			Callable<Bitmap> callable = () -> {
+				if (LOG.isLoggable(INFO))
+					LOG.info("Loading page " + model.getSprite());
+				return loadPage();
 			};
 			task = new ListenableFutureTask<>(callable);
 			new AsyncTask<Void, Void, Void>() {
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 9b5780b252..d409204ab0 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
@@ -110,17 +110,13 @@ public class RecentEmojiPageModel implements EmojiPageModel {
 	}
 
 	private void save(final String serialized) {
-		dbExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				Settings settings = new Settings();
-				settings.put(EMOJI_LRU_PREFERENCE, serialized);
-				try {
-					settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-				}
+		dbExecutor.execute(() -> {
+			Settings settings = new Settings();
+			settings.put(EMOJI_LRU_PREFERENCE, serialized);
+			try {
+				settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
 			}
 		});
 	}
diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java
index d9651770df..f7fd464448 100644
--- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java
+++ b/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 Open Whisper Systems
  *
  * This program is free software: you can redistribute it and/or modify
@@ -46,12 +46,7 @@ public class ListenableFutureTask<V> extends FutureTask<V> {
 	}
 
 	private ListenableFutureTask(final V result, @Nullable Object identifier) {
-		super(new Callable<V>() {
-			@Override
-			public V call() throws Exception {
-				return result;
-			}
-		});
+		super(() -> result);
 		this.identifier = identifier;
 		this.run();
 	}
diff --git a/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java b/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java
index fb4c7f9a71..05c345dbc3 100644
--- a/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/client/MessageTreeImpl.java
@@ -23,12 +23,8 @@ public class MessageTreeImpl<T extends MessageTree.MessageNode>
 	private final List<T> roots = new ArrayList<>();
 	private final List<List<T>> unsortedLists = new ArrayList<>();
 
-	private Comparator<T> comparator = new Comparator<T>() {
-		@Override
-		public int compare(T o1, T o2) {
-			return Long.valueOf(o1.getTimestamp()).compareTo(o2.getTimestamp());
-		}
-	};
+	private Comparator<T> comparator = (o1, o2) ->
+			Long.valueOf(o1.getTimestamp()).compareTo(o2.getTimestamp());
 
 	@Override
 	public synchronized void clear() {
diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java
index 4f7f104e11..5218ecf2e5 100644
--- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java
@@ -129,17 +129,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 	private void startFeedExecutor() {
 		if (fetcherStarted.getAndSet(true)) return;
 		LOG.info("Tor started, scheduling RSS feed fetcher");
-		Runnable fetcher = new Runnable() {
-			@Override
-			public void run() {
-				ioExecutor.execute(new Runnable() {
-					@Override
-					public void run() {
-						fetchFeeds();
-					}
-				});
-			}
-		};
+		Runnable fetcher = () -> ioExecutor.execute(this::fetchFeeds);
 		scheduler.scheduleWithFixedDelay(fetcher, FETCH_DELAY_INITIAL,
 				FETCH_INTERVAL, FETCH_UNIT);
 	}
@@ -502,23 +492,18 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 	}
 
 	private Comparator<SyndEntry> getEntryComparator() {
-		return new Comparator<SyndEntry>() {
-			@Override
-			public int compare(SyndEntry e1, SyndEntry e2) {
-				Date d1 =
-						e1.getPublishedDate() != null ? e1.getPublishedDate() :
-								e1.getUpdatedDate();
-				Date d2 =
-						e2.getPublishedDate() != null ? e2.getPublishedDate() :
-								e2.getUpdatedDate();
-				if (d1 == null && d2 == null) return 0;
-				if (d1 == null) return -1;
-				if (d2 == null) return 1;
-
-				if (d1.after(d2)) return 1;
-				if (d1.before(d2)) return -1;
-				return 0;
-			}
+		return (e1, e2) -> {
+			Date d1 = e1.getPublishedDate() != null ? e1.getPublishedDate() :
+							e1.getUpdatedDate();
+			Date d2 = e2.getPublishedDate() != null ? e2.getPublishedDate() :
+							e2.getUpdatedDate();
+			if (d1 == null && d2 == null) return 0;
+			if (d1 == null) return -1;
+			if (d2 == null) return 1;
+
+			if (d1.after(d2)) return 1;
+			if (d1.before(d2)) return -1;
+			return 0;
 		};
 	}
 
diff --git a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java
index 1745116768..7f7be6c971 100644
--- a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java
@@ -118,16 +118,12 @@ public class TestDataCreatorImpl implements TestDataCreator {
 	}
 
 	public void createTestData() {
-		ioExecutor.execute(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					createTestDataOnDbExecutor();
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING)) {
-						LOG.log(WARNING, "Creating test data failed", e);
-					}
-				}
+		ioExecutor.execute(() -> {
+			try {
+				createTestDataOnDbExecutor();
+			} catch (DbException e) {
+				if (LOG.isLoggable(WARNING))
+					LOG.log(WARNING, "Creating test data failed", e);
 			}
 		});
 	}
diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java
index 48b6b46bbb..c6bf6ebb16 100644
--- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java
+++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java
@@ -706,39 +706,29 @@ public class IntroductionIntegrationTest
 
 	@Test
 	public void testModifiedTransportProperties() throws Exception {
-		testModifiedResponse(new StateVisitor() {
-			@Override
-			public boolean visit(BdfDictionary response) {
-				BdfDictionary tp = response.getDictionary(TRANSPORT, null);
-				tp.put("fakeId",
-						BdfDictionary.of(new BdfEntry("fake", "fake")));
-				response.put(TRANSPORT, tp);
-				return false;
-			}
+		testModifiedResponse(response -> {
+			BdfDictionary tp = response.getDictionary(TRANSPORT, null);
+			tp.put("fakeId", BdfDictionary.of(new BdfEntry("fake", "fake")));
+			response.put(TRANSPORT, tp);
+			return false;
 		});
 	}
 
 	@Test
 	public void testModifiedTimestamp() throws Exception {
-		testModifiedResponse(new StateVisitor() {
-			@Override
-			public boolean visit(BdfDictionary response) {
-				long timestamp = response.getLong(TIME, 0L);
-				response.put(TIME, timestamp + 1);
-				return false;
-			}
+		testModifiedResponse(response -> {
+			long timestamp = response.getLong(TIME, 0L);
+			response.put(TIME, timestamp + 1);
+			return false;
 		});
 	}
 
 	@Test
 	public void testModifiedEphemeralPublicKey() throws Exception {
-		testModifiedResponse(new StateVisitor() {
-			@Override
-			public boolean visit(BdfDictionary response) {
-				KeyPair keyPair = crypto.generateSignatureKeyPair();
-				response.put(E_PUBLIC_KEY, keyPair.getPublic().getEncoded());
-				return true;
-			}
+		testModifiedResponse(response -> {
+			KeyPair keyPair = crypto.generateSignatureKeyPair();
+			response.put(E_PUBLIC_KEY, keyPair.getPublic().getEncoded());
+			return true;
 		});
 	}
 
-- 
GitLab