diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralFragment.kt
index df2a12538..120938bff 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralFragment.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralFragment.kt
@@ -18,7 +18,6 @@ import net.xpece.android.support.preference.MultiSelectListPreference
 import rx.Observable
 import rx.android.schedulers.AndroidSchedulers
 import uy.kohesive.injekt.injectLazy
-import java.util.*
 
 class SettingsGeneralFragment : SettingsFragment(),
         PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {
@@ -108,7 +107,7 @@ class SettingsGeneralFragment : SettingsFragment(),
 
         langPreference.setOnPreferenceChangeListener { preference, newValue ->
             (activity as SettingsActivity).parentFlags = SettingsActivity.FLAG_LANG_CHANGED
-            LocaleHelper.setLocale(Locale(LocaleHelper.intToLangCode(newValue.toString().toInt())))
+            LocaleHelper.changeLocale(newValue.toString().toInt())
             LocaleHelper.updateCfg(activity.application, activity.baseContext.resources.configuration)
             activity.recreate()
             true
diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt
index 5177137ff..763de98a2 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/util/LocaleHelper.kt
@@ -6,42 +6,81 @@ import android.os.Build
 import android.view.ContextThemeWrapper
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import uy.kohesive.injekt.injectLazy
-import java.util.Locale
+import java.util.*
 
+/**
+ * Utility class to change the application's language in runtime.
+ */
+@Suppress("DEPRECATION")
 object LocaleHelper {
 
+    /**
+     * Preferences helper.
+     */
     private val preferences: PreferencesHelper by injectLazy()
 
-    private var pLocale = Locale(intToLangCode(preferences.lang()))
+    /**
+     * In API 16 and below the application's configuration has to be changed, so we need a copy of
+     * the initial locale. The only problem is that if the system locale changes while the app is
+     * running, it won't change until an application restart.
+     */
+    private var v16SystemLocale = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
+        preferences.context.resources.configuration.locale else null
 
-    fun setLocale(locale: Locale) {
-        pLocale = locale
-        Locale.setDefault(pLocale)
-    }
+    /**
+     * The application's locale. When it's null, the system locale is used.
+     */
+    private var appLocale = getLocaleFromCode(preferences.lang())
 
-    fun updateCfg(wrapper: ContextThemeWrapper) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            val config = Configuration(preferences.context.resources.configuration)
-            config.setLocale(pLocale)
-            wrapper.applyOverrideConfiguration(config)
-        }
-    }
-
-    fun updateCfg(app: Application, config: Configuration) {
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            config.locale = pLocale
-            app.baseContext.resources.updateConfiguration(config, app.baseContext.resources.displayMetrics)
-        }
-    }
-
-    fun intToLangCode(i: Int): String {
-        return when(i) {
+    /**
+     * Returns the locale for the value stored in preferences, or null if system language or unknown
+     * value is selected.
+     *
+     * @param pref the int value stored in preferences.
+     */
+    private fun getLocaleFromCode(pref: Int): Locale? {
+        val code = when(pref) {
             1 -> "en"
             2 -> "es"
             3 -> "it"
             4 -> "pt"
-            else -> "" // System Language
+            else -> return null
+        }
+
+        return Locale(code)
+    }
+
+    /**
+     * Changes the application's locale with a new preference.
+     *
+     * @param pref the new value stored in preferences.
+     */
+    fun changeLocale(pref: Int) {
+        appLocale = getLocaleFromCode(pref)
+    }
+
+    /**
+     * Updates the app's language from API 17.
+     */
+    fun updateCfg(wrapper: ContextThemeWrapper) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && appLocale != null) {
+            val config = Configuration(preferences.context.resources.configuration)
+            config.setLocale(appLocale)
+            wrapper.applyOverrideConfiguration(config)
         }
     }
 
+    /**
+     * Updates the app's language for API 16 and lower.
+     */
+    fun updateCfg(app: Application, config: Configuration) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            val configCopy = Configuration(config)
+            val displayMetrics = app.baseContext.resources.displayMetrics
+            configCopy.locale = appLocale ?: v16SystemLocale
+            app.baseContext.resources.updateConfiguration(configCopy, displayMetrics)
+        }
+    }
+
+
 }