استخدام قيم الإعدادات المفضّلة المحفوظة جزء من Android Jetpack.

يوضّح هذا المستند طريقة تخزين واستخدام قيم Preference التي يتم حفظها من خلال "مكتبة الإعدادات المفضّلة".

تخزين البيانات المفضّلة

يوضِّح هذا القسم طريقة الاحتفاظ بالبيانات في Preference.

الإعدادات المفضّلة المشتركة

بشكل تلقائي، يستخدم Preference السمة SharedPreferences لحفظ القيم. تتيح واجهة برمجة التطبيقات SharedPreferences قراءة وكتابة أزواج المفتاح/القيمة البسيطة من ملف يتم حفظه في جلسات التطبيق. تستخدم مكتبة الإعدادات المفضّلة مثيل SharedPreferences خاصًا بحيث يمكن لتطبيقك فقط الوصول إليها.

على سبيل المثال، افترض ما يلي SwitchPreferenceCompat:

<SwitchPreferenceCompat
        app:key="notifications"
        app:title="Enable message notifications"/>

وعندما يفعِّل المستخدم هذا الخيار، يتم تعديل ملف SharedPreferences باستخدام زوج المفتاح/القيمة "notifications" : "true". المفتاح المستخدم هو نفسه مجموعة المفاتيح لـ Preference.

لمزيد من المعلومات حول واجهة برمجة التطبيقات SharedPreferences، يُرجى الاطّلاع على حفظ بيانات قيمة المفتاح.

للحصول على معلومات حول الطرق المختلفة لتخزين البيانات على Android، يُرجى الاطّلاع على نظرة عامة على تخزين البيانات والملفات.

PriorityDataStore

على الرغم من أنّ مكتبة الإعدادات المفضّلة تحتفظ بالبيانات باستخدام SharedPreferences تلقائيًا، لا يمكن استخدام SharedPreferences حلّاً مثاليًا دائمًا. على سبيل المثال، إذا كان تطبيقك يتطلب من المستخدم تسجيل الدخول، قد يكون من الأفضل الاحتفاظ بإعدادات التطبيق في السحابة الإلكترونية حتى تظهر الإعدادات على الأجهزة والأنظمة الأساسية الأخرى. وبالمثل، إذا كان تطبيقك يحتوي على خيارات ضبط خاصة بالجهاز، سيكون لكل مستخدم على الجهاز إعدادات منفصلة، ما يجعل SharedPreferences حلاً أقل من مثالية.

تتيح لك PreferenceDataStore استخدام خلفية مخصّصة لمساحة التخزين للاحتفاظ بقيم Preference. لمزيد من المعلومات، يُرجى الاطّلاع على استخدام مخزن بيانات مخصّص.

قراءة قيم الإعدادات المفضّلة

لاسترداد الكائن SharedPreferences الذي يتم استخدامه، استدعِ PreferenceManager.getDefaultSharedPreferences(). رغم أن هذه الطريقة تعمل من أي مكان في تطبيقك، إلا أننا ننصح بتقسيم التطبيق إلى طبقات. لمزيد من المعلومات، راجع طبقة البيانات.

على سبيل المثال، إذا كان EditTextPreference مع مفتاح "signature"، على النحو التالي:

<EditTextPreference
        app:key="signature"
        app:title="Your signature"/>

يمكنك استرداد القيمة المحفوظة لـ Preference هذا بشكل عام كما يلي:

Kotlin

val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */)
val name = sharedPreferences.getString("signature", "")

Java

SharedPreferences sharedPreferences =
        PreferenceManager.getDefaultSharedPreferences(this /* Activity context */);
String name = sharedPreferences.getString("signature", "");

التعرّف على التغييرات في قيم الإعدادات المفضّلة

للاستماع إلى التغييرات التي تطرأ على قيم Preference، يمكنك الاختيار بين واجهتَين:

يوضّح الجدول التالي مدى اختلاف الواجهتَين:

OnPreferenceChangeListener OnSharedPreferenceChangeListener
الضبط على Preference واحد ينطبق ذلك على جميع عناصر Preference.
يتم استدعاء هذا الإجراء عندما يكون Preference على وشك تغيير قيمته المحفوظة، حتى إذا كانت القيمة المعلَّقة هي نفسها القيمة المحفوظة. يتم استدعاؤه فقط عند حفظ القيمة لأحد قيم Preference.
يتم الاتصال فقط من خلال مكتبة Preference. ويمكن لجزء منفصل من التطبيق تغيير القيمة المحفوظة. يتم استدعاء هذا الإجراء عند تغيّر القيمة المحفوظة، حتى لو كانت من جزء منفصل من التطبيق.
تم استدعاؤه قبل حفظ القيمة المعلَّقة. يتم استدعاؤه بعد حفظ القيمة.
يتم استدعاء الإجراء عند استخدام SharedPreferences أو PreferenceDataStore. يتم الاتصال عند استخدام "SharedPreferences" فقط.

تنفيذ OnPreferredChangeListener

يتيح لك تنفيذ OnPreferenceChangeListener الاطّلاع على أي تغيير معلّق لقيمة Preference. بعد ذلك، يمكنك التحقق من حدوث تغيير. على سبيل المثال، يوضّح الرمز التالي كيفية رصد تغيير في قيمة EditTextPreference باستخدام مفتاح "name":

Kotlin

override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
    Log.e("preference", "Pending Preference value is: $newValue")
    return true
}

Java

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    Log.e("preference", "Pending Preference value is: " + newValue);
    return true;
}

بعد ذلك، عليك ضبط أداة الاستماع هذه مباشرةً من خلال setOnPreferenceChangeListener()، كما يلي:

Kotlin

preference.onPreferenceChangeListener = ...

Java

preference.setOnPreferenceChangeListener(...);

تنفيذ OnSharedPreferencesChangeListener

عند الاحتفاظ بقيم Preference باستخدام SharedPreferences، يمكنك أيضًا استخدام SharedPreferences.OnSharedPreferenceChangeListener لرصد التغييرات. يتيح لك ذلك معرفة ما إذا تم تغيير القيم التي حفظتها في Preference، مثلاً عند مزامنة الإعدادات مع خادم. يوضّح المثال التالي كيفية الاستماع إلى تغيير في قيمة EditTextPreference باستخدام مفتاح "name":

Kotlin

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
    if (key == "signature") {
        Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, ""))
    }
}

Java

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    if (key.equals("signature")) {
        Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, ""));
    }
}

سجِّل المستمع باستخدام registerOnSharedPreferenceChangedListener()، على النحو التالي:

Kotlin

preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)

Java

getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(...);

Kotlin

    val listener: SharedPreferences.OnSharedPreferenceChangeListener =
            SharedPreferences.OnSharedPreferenceChangeListener {...}
    

Java

    SharedPreferences.OnSharedPreferenceChangeListener listener =
            new SharedPreferences.OnSharedPreferenceChangeListener() {...}
    

لإدارة مراحل النشاط بشكل صحيح في Activity أو Fragment، يمكنك تسجيل جهاز المستمع هذا وإلغاء تسجيله في طلبَي الاتصال onResume() وonPause()، كما هو موضّح في المثال التالي:

Kotlin

override fun onResume() {
    super.onResume()
    preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
}

override fun onPause() {
    super.onPause()
    preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
}

Java

@Override
public void onResume() {
    super.onResume();
    getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

@Override
public void onPause() {
    super.onPause();
    getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}

استخدام مخزن بيانات مخصّص

على الرغم من أنّنا ننصح بالاحتفاظ بكائنات Preference باستخدام SharedPreferences، يمكنك أيضًا استخدام مخزن بيانات مخصّص. يمكن أن يكون مخزن البيانات المخصص مفيدًا إذا احتفظ تطبيقك بقيم في قاعدة بيانات أو إذا كانت القيم خاصة بالجهاز، كما هو موضح في الأمثلة التالية.

تنفيذ مخزن البيانات

لتنفيذ مخزن بيانات مخصّص، أنشئ فئة تمتد إلى PreferenceDataStore. ينشئ المثال التالي مخزن بيانات يعالج قيم String:

Kotlin

class DataStore : PreferenceDataStore() {
    override fun putString(key: String, value: String?) {
        // Save the value somewhere.
    }

    override fun getString(key: String, defValue: String?): String? {
        // Retrieve the value.
    }
}

Java

public class DataStore extends PreferenceDataStore {
    @Override
    public void putString(String key, @Nullable String value) {
        // Save the value somewhere.
    }
    @Override
    @Nullable
    public String getString(String key, @Nullable String defValue) {
        // Retrieve the value.
    }
}

تشغيل أي عمليات تستغرق وقتًا طويلاً خارج سلسلة التعليمات الرئيسية لتجنب حظر واجهة المستخدم. بما أنّه من الممكن إتلاف Fragment أو Activity التي تتضمّن مخزن البيانات أثناء الاحتفاظ بالقيمة، يمكنك إنشاء تسلسل للبيانات كي لا تفقد أي قيم غيّرها المستخدم.

تمكين مخزن البيانات

بعد تنفيذ ملف تخزين البيانات، اضبط مخزن البيانات الجديد في onCreatePreferences() بحيث تحتفظ عناصر Preference بقيم مع مخزن البيانات بدلاً من استخدام SharedPreferences التلقائي. يمكنك تفعيل مخزن بيانات لكل Preference أو للتسلسل الهرمي بالكامل.

لتفعيل مخزن بيانات مخصّص لنطاق Preference محدّد، اتصل بـ setPreferenceDataStore() على Preference كما هو موضح في المثال التالي:

Kotlin

val preference: Preference? = findPreference("key")
preference?.preferenceDataStore = dataStore

Java

Preference preference = findPreference("key");
if (preference != null) {
    preference.setPreferenceDataStore(dataStore);
}

لتفعيل مخزن بيانات مخصّص لعرض هرمي كامل، استدعِ setPreferenceDataStore() في PreferenceManager:

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setPreferenceDataStore(dataStore);

يؤدي مخزن البيانات الذي تم إعداده لنطاق Preference محدّد إلى إلغاء أي مخزن بيانات تم إعداده للتدرّج الهرمي المقابل. في معظم الحالات، تقوم بتعيين مخزن بيانات للتسلسل الهرمي بأكمله.