دروس التفضيل المشتركة مع مثال في Android Studio
تُستخدم التفضيلات المشتركة في Android لحفظ البيانات بناءً على زوج القيمة الرئيسية. إذا تعمقنا في فهم الكلمة: الوسائل المشتركة لتوزيع البيانات داخل والتفضيل يعني شيئًا مهمًا أو مفضلاً ، لذلك يتم مشاركة بيانات SharedPreferences والبيانات المفضلة.
يمكن استخدام التفضيل المشترك لحفظ نوع البيانات البدائي: سلسلة ، طويلة ، عدد صحيح ، عائم ومنطقي.
ما هو ملف التفضيل Preference ؟
قبل أن نبدأ في شرح التفضيلات المشتركة Shared Preference ، من المهم فهم ملف التفضيل.
ملف التفضيل Preference هو في الواقع ملف xml محفوظ في الذاكرة الداخلية للجهاز. يحتوي كل تطبيق على بعض البيانات المخزنة في الذاكرة في دليل بيانات / بيانات / اسم حزمة التطبيق ، على سبيل المثال data / data / com.abhiandroid.abhiapp ، لذلك كلما تم استدعاء وظيفة getSharedPreferences (اسم السلسلة ، الوضع int) ، تتحقق من صحة الملف إذا كان موجودًا أو لم يتم إنشاء ملف xml جديد باسم مر.
جدول المحتويات
- 1 طريقتان لحفظ البيانات من خلال التفضيل المشترك:
- الوضع الثاني ونوعه في التفضيل المشترك:
- 3 مهمة توصي بها Google اصطلاح التسمية لملف التفضيل:
- 4 إنشاء تفضيل مشترك:
- 5 حفظ البيانات في SharedPreferences:
- 6 اقرأ البيانات أو احصل عليها من SharedPreferences
- 7 إزالة البيانات أو مسح كافة البيانات
- 8 كود حفظ واسترجاع البيانات في التفضيل المشترك:
- 9 مثال التفضيل المشترك:
- 10 الأهمية:
هناك طريقتان مختلفتان لحفظ البيانات في Android من خلال التفضيلات المشتركة - أحدهما يستخدم التفضيلات القائمة على النشاط والآخر هو إنشاء تفضيلات مخصصة.
تفضيلات النشاط:
- بالنسبة لتفضيلات النشاط ، يتعين على المطور استدعاء وظيفة getPreferences (الوضع int) المتوفرة في فئة النشاط
- استخدمه فقط عند الحاجة إلى ملف تفضيل واحد في النشاط
- لا يتطلب اسمًا لأنه سيكون ملف التفضيل الوحيد لهذا النشاط
- لا يفضل المطور عادةً استخدام هذا حتى إذا كانوا بحاجة إلى ملف تفضيل واحد فقط في النشاط. يفضلون استخدام getSharedPreferences المخصص (اسم السلسلة ، الوضع int).
لاستخدام تفضيلات النشاط ، يجب على المطور استدعاء وظيفة getPreferences (الوضع int) المتوفرة في فئة النشاط. تستدعي وظيفة getPreferences (الوضع int) الوظيفة الأخرى المستخدمة لإنشاء تفضيلات مخصصة مثل getSharedPreferences (اسم السلسلة ، الوضع int). فقط لأن النشاط يحتوي على ملف تفضيلات واحد فقط ، لذا فإن وظيفة getPreferences (الوضع int) تقوم ببساطة بتمرير اسم فئة النشاط لإنشاء ملف تفضيل.
ملاحظة مهمة: تمت مناقشة الوضع في التفضيلات المخصصة.
التفضيلات المخصصة:
- يحتاج المطور إلى استخدام getSharedPreferences (اسم السلسلة ، الوضع int) للتفضيلات المخصصة
- يُستخدم في الحالات التي يكون فيها أكثر من ملف تفضيل واحد مطلوبًا في النشاط
- يتم تمرير اسم ملف التفضيل في المعلمة الأولى
يمكن إنشاء التفضيلات المخصصة عن طريق استدعاء وظيفة getSharedPreferences (اسم السلسلة ، الوضع int) ، ويمكن استدعاؤها من أي مكان في التطبيق مع الإشارة إلى السياق. هنا الاسم هو أي اسم مفضل على سبيل المثال: مستخدم ، كتاب وما إلى ذلك ، ويستخدم الوضع لضبط نوع الخصوصية للملف.
لإنشاء تفضيلات قائمة على النشاط أو تفضيلات مخصصة ، يتعين على المطور اجتياز الوضع للسماح للنظام بمعرفة خصوصية ملف التفضيل.
قبل أن نبدأ مناقشة موجزة عن السياق
السياق عبارة عن فئة مجردة تستخدم للحصول على معلومات عالمية في موارد تطبيقات Android مثل السلاسل والقيم والعناصر القابلة للرسم والأصول وما إلى ذلك. هنا يتم الإعلان عن الأوضاع والثابت النهائي الثابت في فئة السياق.
هناك ثلاثة أنواع من الوضع في التفضيلات المشتركة:
- Context.MODE_PRIVATE – default value (Not accessible outside of your application)
- Context.MODE_WORLD_READABLE – readable to other apps
- Context.MODE_WORLD_WRITEABLE – read/write to other apps
MODE_PRIVATE - إنه وضع افتراضي. MODE_PRIVATE يعني أنه عند إنشاء أي ملف تفضيل بالوضع الخاص ، فلن يكون الوصول إليه متاحًا خارج التطبيق الخاص بك. هذا هو الوضع الأكثر شيوعًا المستخدم.
MODE_WORLD_READABLE - إذا قام المطور بإنشاء ملف تفضيلات مشترك باستخدام الوضع العالمي للقراءة ، فيمكن قراءته من قبل أي شخص يعرف اسمه ، بحيث يمكن لأي تطبيق خارجي آخر قراءة بيانات تطبيقك بسهولة. نادرًا ما يتم استخدام هذا الوضع في التطبيق.
MODE_WORLD_WRITEABLE - إنه مشابه لوضع العالم المقروء ولكن مع كلا النوعين من الوصول ، أي القراءة والكتابة. لا يتم استخدام هذا الوضع مطلقًا في التطبيق بواسطة المطور.
مهمة توصي بها Google اصطلاح التسمية لملف التفضيل:
يرجى التأكد من اتباع توصيات Google مع إعطاء اسم الملف المفضل. توصي Google بإعطاء اسم كاسم حزمة التطبيق + الاسم المفضل.
على سبيل المثال: إذا كان اسم حزمة التطبيق الخاص بك هو اسم ملف com.abhiandroid.abhiapp
التفضيل ، فقد يكون التفضيل هو com.abhiandroid.abhiapp.User
المكان الذي com.abhiandroid.abhiapp.User
يوجد فيه اسم ملف التفضيل.
كما نوقش أعلاه ، لإنشاء تفضيلات مشتركة ، يحتاج المطور إلى استدعاء getPreferences (الوضع int) أو getSharedPreferences (String name، int mode) . تقوم كلتا الوظيفتين بإرجاع كائن SharedPreferences للتعامل مع الحفظ والحصول على القيم من ملف التفضيل.
SharedPreferences هي فئة فردية تعني أن هذه الفئة ستحتوي على كائن واحد فقط طوال دورة حياة التطبيق. ومع ذلك ، يمكن أن يكون هناك ملفات تفضيلات متعددة بحيث يمكن قراءة جميع ملفات التفضيلات وكتابتها باستخدام فئة SharedPreferences.
الخطوة 1:
لحفظ البيانات في SharedPreferences ، يحتاج المطور إلى استدعاء وظيفة التحرير () لفئة SharedPreferences التي تقوم بإرجاع كائن فئة المحرر .
الخطوة 2:
توفر فئة المحرر وظيفة مختلفة لحفظ بيانات الوقت الأولية. على سبيل المثال ، يحتوي المحرر على جميع وظائف البيانات الأولية بما في ذلك بيانات نوع السلسلة مثل putInt (String keyName ، قيمة int).
تنسيق الوظيفة الأولية الشائع هو: وضع + اسم النوع الأساسي (اسم مفتاح السلسلة ، قيمة النوع الأساسي)
الخطوه 3:
تأكد الآن من أن اسم المفتاح يجب أن يكون فريدًا لأي قيم تحفظها وإلا فسيتم تجاوزه. لحفظ القيم التي تضعها بالضبط في وظائف بدائية مختلفة ، يجب عليك استدعاء وظيفة الالتزام () للمحرر.
الخطوة 1: لقراءة البيانات أولاً ، يجب على المطور الحصول على مرجع لكائن SharedPreferences عن طريق استدعاء getPreferences (الوضع int) أو getSharedPreferences (String name، int mode) .
الخطوة 2: بعد ذلك ، يمكن للمطور الحصول على القيم باستخدام كائن SharedPreferences عن طريق استدعاء دالة نوع بدائي مختلفة تبدأ بـ get + Primitive Type name. هنا تحتوي كل وظيفة على معلمة إضافية لكل نوع أساسي كقيمة افتراضية في حالة عدم وجود قيمة مطابقة للمفتاح الذي تم تمريره.
على سبيل المثال ، للحصول على قيمة int المحفوظة ، فقط اتصل بوظيفة getInt ("GameScore" ، - 1) حيث تكون "GameScore" هي المفتاح و -1 هي القيمة الافتراضية في حالة عدم حفظ أي قيمة لـ GameScore.
إزالة البيانات أو مسح كافة البيانات
مماثلة لحفظ البيانات وجود وظيفة إزالة (مفتاح سلسلة) في SharedPreferences.Editor
لإزالة البيانات الرئيسية القائمة معينة من ملف تفضيل
لمسح جميع البيانات ، ما عليك سوى الاتصال بالوظيفة امسح () المتوفرة بتنسيق SharedPreferences.Editor
. تأكد من استدعاء طريقة الالتزام () لحفظ التغييرات. لذا فإن البيانات الواضحة لن تحذف ملف التفضيل أبدًا ولكنها تجعله فارغًا.
public static final String PREFS_GAME ="com.abhiandroid.abhiapp.GamePlay"; public static final String GAME_SCORE= "GameScore"; //======== Code to save data =================== SharedPreferences sp = getSharedPreferences(PREFS_GAME ,Context.MODE_PRIVATE); sp.edit().putInt(GAME_SCORE,100).commit(); //========= Code to get saved/ retrieve data ============== SharedPreferences sp = getSharedPreferences(PREFS_GAME ,Context.MODE_PRIVATE); int sc = sp.getInt(GAME_SCORE,0); Log.d("AbhiAndroid","achieved score is "+ sc);
لنستخدم التفضيل المشترك لغرض أساسي للغاية وهو حفظ تفاصيل تسجيل الدخول لشخص ما ، مثل البريد الإلكتروني وكلمة المرور على جهازه. لذلك لا يتعين عليه إعادة إدخال تفاصيل تسجيل الدخول الخاصة به في كل مرة يفتح فيها التطبيق.
فيما يلي الناتج النهائي الذي سننشئه ونستخدمه "التفضيلات المشتركة" لحفظ تفاصيل تسجيل الدخول:

يوجد أدناه رمز واجهة مستخدم تسجيل الدخول الكامل Activity_login.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.samplesharedpreferences.LoginActivity"> <!-- Login progress --> <ProgressBar android:id="@+id/login_progress" style="?android:attr/progressBarStyleLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:visibility="gone"/> <ScrollView android:id="@+id/login_form" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/email_login_form" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/email" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/prompt_email" android:inputType="textEmailAddress" android:maxLines="1" android:singleLine="true"/> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/prompt_password" android:imeActionId="@+id/login" android:imeActionLabel="@string/action_sign_in_short" android:imeOptions="actionUnspecified" android:inputType="textPassword" android:maxLines="1" android:singleLine="true"/> </android.support.design.widget.TextInputLayout> <CheckBox android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Remember Me" android:id="@+id/checkBoxRememberMe"/> <Button android:id="@+id/email_sign_in_button" style="?android:textAppearanceSmall" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="@string/action_sign_in" android:textStyle="bold"/> </LinearLayout> </ScrollView> </LinearLayout>
الخطوة 2: الآن دعنا نبرمج نشاط تسجيل الدخول. جافا حيث سننشئ نموذج تسجيل الدخول. يوجد أدناه الرمز الكامل لـ LoginActivity. جافا مع شرح مدرج في التعليق.
package com.samplesharedpreferences; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.support.annotation.NonNull; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.app.LoaderManager.LoaderCallbacks; import android.content.ContentResolver; import android.content.CursorLoader; import android.content.Loader; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.os.Build.VERSION; import android.os.Build; import android.os.Bundle; import android.provider.ContactsContract; import android.text.TextUtils; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.inputmethod.EditorInfo; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; import java.util.ArrayList; import java.util.List; import static android.Manifest.permission.READ_CONTACTS; /** * A login screen that offers login via email/password. */ public class LoginActivity extends AppCompatActivity { // UI references. private EditText mEmailView; private EditText mPasswordView; private CheckBox checkBoxRememberMe; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); // Set up the login form. mEmailView = (EditText) findViewById(R.id.email); mPasswordView = (EditText) findViewById(R.id.password); mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) { if (id == R.id.login || id == EditorInfo.IME_NULL) { attemptLogin(); return true; } return false; } }); Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button); mEmailSignInButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { attemptLogin(); } }); checkBoxRememberMe = (CheckBox) findViewById(R.id.checkBoxRememberMe); //Here we will validate saved preferences if (!new PrefManager(this).isUserLogedOut()) { //user's email and password both are saved in preferences startHomeActivity(); } } /** * Attempts to sign in or register the account specified by the login form. * If there are form errors (invalid email, missing fields, etc.), the * errors are presented and no actual login attempt is made. */ private void attemptLogin() { // Reset errors. mEmailView.setError(null); mPasswordView.setError(null); // Store values at the time of the login attempt. String email = mEmailView.getText().toString(); String password = mPasswordView.getText().toString(); boolean cancel = false; View focusView = null; // Check for a valid password, if the user entered one. if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) { mPasswordView.setError(getString(R.string.error_invalid_password)); focusView = mPasswordView; cancel = true; } // Check for a valid email address. if (TextUtils.isEmpty(email)) { mEmailView.setError(getString(R.string.error_field_required)); focusView = mEmailView; cancel = true; } else if (!isEmailValid(email)) { mEmailView.setError(getString(R.string.error_invalid_email)); focusView = mEmailView; cancel = true; } if (cancel) { // There was an error; don't attempt login and focus the first // form field with an error. focusView.requestFocus(); } else { // save data in local shared preferences if (checkBoxRememberMe.isChecked()) saveLoginDetails(email, password); startHomeActivity(); } } private void startHomeActivity() { Intent intent = new Intent(this, HomeActivity.class); startActivity(intent); finish(); } private void saveLoginDetails(String email, String password) { new PrefManager(this).saveLoginDetails(email, password); } private boolean isEmailValid(String email) { //TODO: Replace this with your own logic return email.contains("@"); } private boolean isPasswordValid(String password) { //TODO: Replace this with your own logic return password.length() > 4; } }
الخطوة 3: قم بإنشاءفئة java جديدةلـ Shared PrefManager. يوجد أدناه رمز PrefManager.java
package com.samplesharedpreferences; import android.content.Context; import android.content.SharedPreferences; /** * Class for Shared Preference */ public class PrefManager { Context context; PrefManager(Context context) { this.context = context; } public void saveLoginDetails(String email, String password) { SharedPreferences sharedPreferences = context.getSharedPreferences("LoginDetails", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("Email", email); editor.putString("Password", password); editor.commit(); } public String getEmail() { SharedPreferences sharedPreferences = context.getSharedPreferences("LoginDetails", Context.MODE_PRIVATE); return sharedPreferences.getString("Email", ""); } public boolean isUserLogedOut() { SharedPreferences sharedPreferences = context.getSharedPreferences("LoginDetails", Context.MODE_PRIVATE); boolean isEmailEmpty = sharedPreferences.getString("Email", "").isEmpty(); boolean isPasswordEmpty = sharedPreferences.getString("Password", "").isEmpty(); return isEmailEmpty || isPasswordEmpty; } }
الخطوة 4: صمم واجهة مستخدم الصفحة الرئيسية البسيطة حيث سنعرض رسالة ترحيب مع عنوان بريده الإلكتروني المحفوظ في التفضيل المشترك. يوجد أدناه رمز content_home.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.samplesharedpreferences.HomeActivity" tools:showIn="@layout/activity_home"> <TextView android:id="@+id/textViewUser" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center" android:text="Welcome"/> </RelativeLayout>
الخطوة 5: ملف البيان
تأكد من تعيين AndroidManifest.xml Intent Filter for Main و Launcher بداخل .LoginActivity لأنه عندئذٍ فقط سيتم فتح هذا النشاط أولاً.
<?xml version="1.0" encoding="utf-8"?> <manifest package="com.samplesharedpreferences" xmlns:android="http://schemas.android.com/apk/res/android"> <!-- To auto-complete the email text field in the login form with the user's emails --> <uses-permission android:name="android.permission.GET_ACCOUNTS"/> <uses-permission android:name="android.permission.READ_PROFILE"/> <uses-permission android:name="android.permission.READ_CONTACTS"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".LoginActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".HomeActivity" android:label="@string/title_activity_home" android:theme="@style/AppTheme.NoActionBar"> </activity> </application> </manifest>
انتاج:
الخطوة 1: الآن قم بتشغيل التطبيق في Emulator. سترى شاشة الإخراج أدناه



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