Android - 如何在非Activity类中使用SharedPreferences?

49

如何在非Activity类中使用SharedPreferences?我尝试创建一个通用的Preferences实用程序类,并导入android.content.Context,但Eclipse仍然不允许我使用getSharedPreferences()

12个回答

52

SharedPreferences与上下文(Context)相关联,只能通过Context引用。

你可以将Context作为参数传递给你的类,例如在构造函数中。

在你的Activity中,可以这样做:

MyClass myClass = new MyClass(this);

13
啊哈!那正是我一直在寻找的东西。感谢你提供简单明了的答案。现在我可以使用 context.getSharedPreferences(); 来访问它了。 - Jake Wilson
错误是 MODE_PRIVATE 无法解析为变量。 - Prasad
1
我的活动不允许在我的其他类构造函数中使用“this”(具有“SharedPreferences”的类)。 - Azurespot
1
@Prasad 使用0。这是同样的事情。 - Edward
我们可以使用静态方法 http://www.freakyjolly.com/shared-preference-context-error-android/ - Code Spy

51

我找到的解决方法是:

1-在MainActivity类中创建一个静态变量来存储上下文(即在项目中获取任何上下文之前始终启动):

public static Context contextOfApplication;

2-在该类的一个重要方法中(例如onCreate、构造函数等),使用getApplicationContext方法初始化此变量:

public void onCreate() {
    contextOfApplication = getApplicationContext();
}

3-在同一个类中创建一个“getter”方法来获取这个变量(它也必须是静态的):

3-在同一类中创建一个"getter"方法以获取该变量(它也必须是静态的):

public static Context getContextOfApplication(){
    return contextOfApplication;
}

4-在非活动类中通过静态调用created方法来获取上下文:

Context applicationContext = MyActivityClass.getContextOfApplication();

使用PreferenceManager类获取SharedPreferences变量:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(applicationContext);

希望能对您有所帮助。


6
这是一个有用的变通方法,我建议将contextOfApplication作为私有字段使用。 - fredmaggiowski
你也可以使用applicationContext.getSharedPreferences(pref_name, MODE_PRIVATE); - B.shruti
3
这是一个很不规范的解决方案和反模式,在Activity中暴露一个公共的静态Context变量。但是,如果你决定这样做值得注意的是,由于成员变量 public static Context contextOfApplication; 是公共的和静态的,你不需要使用 getContextOfApplication() 方法来访问它。在第4步中,你只需要写成 MyActivityClass.contextOfApplication 就可以了。 - PrashanD

4
在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) }
    }
}

现在,您可以从应用程序的任何地方像这样获取一个值:
val heightInCentimeters: Int? = AppPreferences.heightInCentimeters
val heightOrDefault: Int = AppPreferences.heightInCentimeters ?: 170

为SharedPreferences设置一个值同样很容易:

AppPreferences.heightInCentimeters = 160 // sets a new value

2

使用静态方法在没有上下文对象的情况下使用 SharedPreference 的解释可以在这里找到:这里

OnCreate 之前在 MainActivity

public static SharedPreferences preferences;

OnCreate 方法中添加。
preferences = getSharedPreferences( getPackageName() + "_preferences", MODE_PRIVATE);

创建一个名为PreferenceHelper的类,其中包含静态方法Getters和Setters,用于处理与偏好设置相关的操作。保留html标签。
public class PreferenceHelper {

final public static String KEY_DEMO_NAME = "Demo Name";
public static void setName(String value) {
    MainActivity.preferences.edit().putString(KEY_DEMO_NAME, value ).commit();
}
public static String getName() {
    return MainActivity.preferences.getString(KEY_DEMO_NAME,"");
}

}


2
尝试在应用程序上下文中使用默认首选项。上下文类似于Linux或Windows上应用程序运行的环境(例如,PATH窗口样式或控制台大小等环境变量)。每个活动和服务也都有自己的上下文,例如屏幕方向、主题和标签等,但对于您的应用程序,您不希望使用活动的上下文,而是需要一些全局的东西来维护应用程序,这就是context.getApplicationContext()有用的地方。它在整个应用程序中都是相同的,并且始终会给您提供相同的默认首选项。

你能详细说明一下吗?我尝试了 SharedPreferences prefs = getDefaultSharedPreferences(this); 但它不起作用。 - Jake Wilson
无论您在代码中的哪个位置,都需要上下文才能使用首选项。请使用PreferenceManager.getDefaultSharedPreferences(applicationContext); - Dan S
1
@DanS - 当他在获取上下文方面遇到问题时,您希望他从哪里获取applicationContext呢? - Bamerza
@Bamerza 正如我所说,需要一个“Context”,其他答案展示了如何以静态方式存储一个“Context”。 - Dan S

2
在主活动中添加:您将获得全局静态共享首选项对象。
 companion object {    
    lateinit var sharedPreferences: SharedPreferences
}

override fun onCreate(savedInstanceState: Bundle?) {
 sharedPreferences = applicationContext.getSharedPreferences(
        SHARED_PREFERENCE_NAME,
        Context.MODE_PRIVATE
    )

1
在Kotlin中,你可以这样做:
val myClass = MyClass(this)

现在,这是你可以在类中获取上下文的方法。
class MyClass(context: Context) {

    val context: Context = context

}

现在,要使用上下文获取共享首选项,您可以执行以下操作:
context.getSharedPreferences(...)

1
使用此代码创建一个新的类。
import android.content.Context;
import android.content.SharedPreferences;

/**
   * Created by Atiar Talukdar on 6/5/2017.
*/

public class TemporaryStorageSharedPreference {
protected final static int DEFAULT = 0;
int temp = 0;

public int readSharedPreference(Context context, String spName,String key){
    SharedPreferences sharedPreferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
    return temp = sharedPreferences.getInt(key,DEFAULT);
}

public void writeSharedPreference(Context context,String ammount,String spName,String key ){

    SharedPreferences sharedPreferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putInt(key, DEFAULT);
    editor.commit();
}
}

0

创建SharedPreferences类

 /**
     * @param mContext
     * @param key
     * @param value
     */
    public static void savePreferences(Context mContext, String key, String value) {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, value).apply();
    }

    /**
     * @param context
     * @param keyValue
     * @return
     */
    public static String getPreferences(Context context, String keyValue) {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        return sharedPreferences.getString(keyValue, "");
    }

    /**
     * @param mContext
     */
    public static void removeAllSharedPreferences(Context mContext) {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.clear().apply();
    }

0
使用此代码从活动中获取context
if (context != null) {
    SharedPreferences sharedPrefs = context.getSharedPreferences("YOUR.PACKAGE.NAME", MODE_PRIVATE);
}

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