如何在不同活动之间最佳使用共享首选项

21

我在我的应用程序中有一个用户偏好设置,它被不同的活动使用。 我想知道在我的应用程序中利用这些首选项的最佳方法。

我有一个想法,从主活动创建一个共享首选项对象,然后从那里向不同的活动发送意图以执行操作。 那会起作用吗...?

还是只需从每个活动调用getsharedpreferences()..?

谢谢。

4个回答

26

将共享偏好通过意图发送似乎过于复杂。您可以使用以下类将共享偏好包装起来,然后直接从活动中调用方法:

public class Prefs {
    private static String MY_STRING_PREF = "mystringpref";
    private static String MY_INT_PREF = "myintpref";

    private static SharedPreferences getPrefs(Context context) {
        return context.getSharedPreferences("myprefs", 0);
    }

    public static String getMyStringPref(Context context) {
        return getPrefs(context).getString(MY_STRING_PREF, "default");
    }

    public static int getMyIntPref(Context context) {
        return getPrefs(context).getInt(MY_INT_PREF, 42);
    }

    public static void setMyStringPref(Context context, String value) {
        // perform validation etc..
        getPrefs(context).edit().putString(MY_STRING_PREF, value).commit();
    }

    public static void setMyIntPref(Context context, int value) {
        // perform validation etc..
        getPrefs(context).edit().putInt(MY_INT_PREF, value).commit();
    }
}

嗯...这里有太多选择了。但实际上,我的用户偏好包含复选框,在列表视图中执行操作。所以我可能会采用这里的建议。唯一的问题是它是从自定义游标适配器中填充的,所以我需要弄清楚在哪里调用它。 - irobotxx
1
是的,它有效,如果我走了意图路线,我真的会自毁前程! - irobotxx
你是否遇到了使用这种方法的性能问题?因为我正在使用相同的方法,但我有性能问题,不确定这种方法是否是问题的原因。 - AlAsiri
如果你有很多偏好设置,你会想要批处理它们。如果目标是Android 2.3或更新版本,则应该使用非阻塞的apply()方法而不是commit()方法 - http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#apply()。 - fornwall
为什么不将整个类声明为“静态”? - Fred

8
您可以使用这种方法,在所有需要使用的活动中声明相同名称的变量。
  public static final String PREFS_NAME = "MyPrefsFile";
  static SharedPreferences settings;
  SharedPreferences.Editor editor;
  int wordCount;

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    settings = getSharedPreferences(PREFS_NAME, 0);
    editor = settings.edit();

    wordCount = settings.getInt("wordCount", 4); 

  }

这里的wordCount最初是4; 当你编辑wordCount并想要重新存储时

  editor.putInt("wordCount", 6);
  editor.commit();

在想要使用共享偏好设置的活动中,您必须声明相同的变量。最好在每个活动中调用getSharedPreferences。

我认为将偏好设置传递给意图不起作用。


0

当然,您可以在应用程序中使用共享首选项。

如果您有更多的类型不仅仅是字符串或整数,您可以使用单例模式或扩展应用程序类,这将可被应用程序的所有活动访问。 => 这里没有磁盘访问。只需保留在内存中。


0

这里有一个漂亮且简单的解决方案,使用Kotlin编写 - 只需将代码复制并粘贴到新的AppPreferences.kt文件中,并按照代码中概述的4个TODO步骤进行操作:

import android.content.Context
import android.content.Context.MODE_PRIVATE
import android.content.SharedPreferences
import androidx.core.content.edit

object AppPreferences {
    private var sharedPreferences: SharedPreferences? = null

    // TODO step 1: call `AppPreferences.setup(applicationContext)` in your MainActivity's `onCreate` method
    fun setup(context: Context) {
        // TODO step 2: set your app name here
        sharedPreferences = context.getSharedPreferences("<YOUR_APP_NAME>.sharedprefs", MODE_PRIVATE)
    }

    // TODO step 4: replace these example attributes with your stored values
    var heightInCentimeters: Int?
        get() = Key.HEIGHT.getInt()
        set(value) = Key.HEIGHT.setInt(value)

    var birthdayInMilliseconds: Long?
        get() = Key.BIRTHDAY.getLong()
        set(value) = Key.BIRTHDAY.setLong(value)

    private enum class Key {
        HEIGHT, BIRTHDAY; // TODO step 3: replace these cases with your stored values keys

        fun getBoolean(): Boolean? = if (sharedPreferences!!.contains(name)) sharedPreferences!!.getBoolean(name, false) else null
        fun getFloat(): Float? = if (sharedPreferences!!.contains(name)) sharedPreferences!!.getFloat(name, 0f) else null
        fun getInt(): Int? = if (sharedPreferences!!.contains(name)) sharedPreferences!!.getInt(name, 0) else null
        fun getLong(): Long? = if (sharedPreferences!!.contains(name)) sharedPreferences!!.getLong(name, 0) else null
        fun getString(): String? = if (sharedPreferences!!.contains(name)) sharedPreferences!!.getString(name, "") else null

        fun setBoolean(value: Boolean?) = value?.let { sharedPreferences!!.edit { putBoolean(name, value) } } ?: remove()
        fun setFloat(value: Float?) = value?.let { sharedPreferences!!.edit { putFloat(name, value) } } ?: remove()
        fun setInt(value: Int?) = value?.let { sharedPreferences!!.edit { putInt(name, value) } } ?: remove()
        fun setLong(value: Long?) = value?.let { sharedPreferences!!.edit { putLong(name, value) } } ?: remove()
        fun setString(value: String?) = value?.let { sharedPreferences!!.edit { putString(name, value) } } ?: remove()

        fun remove() = sharedPreferences!!.edit { remove(name) }
    }
}

为什么你没有使用 commit() 或者 apply() - Kuvonchbek Yakubov
@KuvonchbekYakubov 很好的问题,我不记得了。它可能是这样工作的,但也许是错的?请随意报告或提供修复版本(例如通过GitHub Gists),我会更新我的答案! :) - Jeehut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接