سؤال

لدي بعض المعلومات المخزنة كمشاركات. أحتاج إلى الوصول إلى هذه المعلومات من النشاط (من فئة نموذج المجال). لذلك قمت بإنشاء طريقة ثابتة في نشاط أستخدمه فقط للحصول على التفضيلات المشتركة.

هذا يعطيني بعض المشكلات ، لأنه على ما يبدو أنه من غير الممكن تسمية طريقة "getSharedPreferences" من طريقة ثابتة.

إليكم الرسالة التي تعطيني Eclipse:

Cannot make a static reference to the non-static method 
getSharedPreferences(String, int) from the type ContextWrapper

حاولت العمل حول هذا باستخدام مثيل نشاط ، مثل هذا:

public static SharedPreferences getSharedPreferences () {
  Activity act = new Activity();
  return act.getSharedPreferences("FILE", 0);
}

هذا الرمز يعطي استثناء نقطة فارغة.

ايوجد اي عمل في هذه المنطقه؟ هل سأذهب إلى طية الرمز الناتج عن الرمز من خلال محاولة القيام بذلك؟

شكرا لك مقدما.

هل كانت مفيدة؟

المحلول

هذا لأنه في هذه الحالة ، act هو كائن تقوم بإنشائه فقط. عليك أن تدع Android تفعل ذلك من أجلك ؛ getSharedPreferences() هي طريقة Context, (Activity, Service تمتد الفصول الأخرى من Context). لذلك ، عليك أن تختار:

  • إذا كانت الطريقة داخل نشاط أو نوع آخر من السياق:

    getApplicationContext().getSharedPreferences("foo", 0);
    
  • إذا كانت الطريقة خارج نشاط أو نوع آخر من السياق:

    // you have to pass the context to it. In your case:
    // this is inside a public class
    public static SharedPreferences getSharedPreferences (Context ctxt) {
       return ctxt.getSharedPreferences("FILE", 0);
    }
    
    // and, this is in your activity
    YourClass.this.getSharedPreferences(YourClass.this.getApplicationContext());
    

نصائح أخرى

إجابة كريستيان جيدة ، ولكن إذا كنت تريد أن تكون قادرًا على الوصول إلى تفضيلاتك المشتركة من كل مكان ، فستكون الطريقة الصحيحة:

  1. إنشاء فئة فرعية من Application, ، على سبيل المثال public class MyApp extends Application {...
  2. تعيين android:name سمة الخاص بك <application> علامة في AndroidManifest.xml للإشارة إلى فصلك الجديد ، على سبيل المثال android:name="MyApp" (لذلك يتم التعرف على الفصل بواسطة Android)
  3. في طريقة onCreate () لمثيل التطبيق الخاص بك ، احفظ سياقك (على سبيل المثال this) إلى حقل ثابت اسمه app وإنشاء طريقة ثابتة تُرجع هذا الحقل ، على سبيل المثال getApp(). يمكنك بعد ذلك استخدام هذه الطريقة لاحقًا للحصول على سياق لتطبيقك وبالتالي الحصول على تفضيلاتك المشتركة. :-)

لقد واجهت مشكلة مماثلة وحلتها ببساطة عن طريق تمرير السياق الحالي إلى الوظيفة الثابتة:

public static void LoadData(Context context)
{
    SharedPreferences SaveData = context.getSharedPreferences(FILENAME, MODE_PRIVATE);
    Variable = SaveData.getInt("Variable", 0);
    Variable1 = SaveData.getInt("Variable1", 0);
    Variable2 = SaveData.getInt("Variable2", 0);
}

نظرًا لأنك تتصل من خارج النشاط ، ستحتاج إلى حفظ السياق:

public static Context context;

وداخل oncreate:

context = this;

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

إليك بديل أفضل لتخزين تفضيلاتك المشتركة في الحقول الثابتة.

  1. على غرار ما تم اقتراحه هنا ، قم بإنشاء فصل يمتد التطبيق
  2. اجعل المُنشئ لفصلك ، يأخذ السياق كمعلمة.
  3. استخدم سياقك للحصول على تفضيلات مشتركة وتخزينها في متغيرات خاصة.
  4. إنشاء متغيرات عامة لإرجاع البيانات التي تم استردادها.

على سبيل المثال

public class UserInfo extends Application{
    private String SAVED_USERID;
    private String SAVED_USERNAME;

    public UserInfo(Context context) {
        SharedPreferences prefs = context.getSharedPreferences(FILE, MODE_PRIVATE);
        SAVED_USERNAME = prefs.getString("UserName", null);
        SAVED_USERID = prefs.getString("UserID", null);
    }

    public String getSavedUserName() {
        return SAVED_USERNAME;
    }

    public String getSavedUserID() {
         return SAVED_USERID;
    }
}

الاستخدام في نشاطك

   UserInfo user = new UserInfo(this.getApplicationContext());

   String SAVED_USERNAME = user.getSavedUserName();
   String SAVED_USERID = user.getSavedUserID();

كان لدي نفس الحاجة - يجب الوصول إلى بعض تفضيلاتي في كثير من الأحيان ، وكفاءة. أتخيل أيضًا أن قراءة وكتابة سلسلة من المشاركين أبطأ قليلاً من الحصول على متغير ثابت (ولكن من المحتمل أن يكون هناك درجة ضئيلة). كما أنني اعتدت على استخدام الحقول الثابتة ، واسترداد قيم التفضيل فقط عند بدء التشغيل ، وحفظها على قرب.

لم أكن أحب خياراتي للحفاظ على الإشارات الثابتة إلى المشاركين/السياقات مباشرة ، ولكن حتى الآن هذا الحل الكافي.

بلدي الحل:

  1. قم بإنشاء فئة إعدادات مع جميع المتغيرات الثابتة التي تحتاجها.

  2. عندما يتم تهيئة التطبيق ، استرجاع حقول المشتركين وضبط جميع حقول الإعدادات على الفور (أسميها طريقة "loadsharedprefs ()" في نهاية طريقة OnCreate الخاصة بـ MainActivity).

  3. في تفضيلات Settivivity's PreferenceChangelistener ، قم بتعيين الحقل الثابت المناسب في فئة الإعدادات. (أسمي طريقة "setAppRiatesting (المفتاح ، القيمة)" في بداية الإعدادات OnPreferenCechange ()).

استخدم تفضيلاتك الثابتة أينما ، كلما!

public static String getPreferenceValue(Context context) {
    SharedPreferences sharedPreferences = 
        PreferenceManager.getDefaultSharedPreferences(context);
    String key = context.getString(R.string.pref_key);
    String defaultVal = context.getString(R.string.pref_default);
    return sharedPreferences.getString(key,defaulVal);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top