web-dev-qa-db-ja.com

静的メソッドを介してSharedPreferencesにアクセスする

SharedPreferencesとして保存されている情報があります。その情報にアクセスするには、外部のアクティビティ(ドメインモデルクラスから)にアクセスする必要があります。そこで、共有設定を取得するためだけに使用するアクティビティに静的メソッドを作成しました。

静的メソッドから「getSharedPreferences」メソッドを呼び出すことは明らかに不可能なので、これはいくつかの問題を引き起こしています。

Eclipseからのメッセージは次のとおりです。

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

次のようにActivityインスタンスを使用して、これを回避しようとしました。

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

このコードは、ヌルポイント例外を提供します。

回避策はありますか?これを試みることでAndroidコードの匂いになりますか?

前もって感謝します。

31
MyNameIsZero

これは、この場合、actが作成したばかりのオブジェクトだからです。 Androidはあなたのためにそれをさせます; getSharedPreferences()Contextのメソッドです(ActivityServiceおよびその他のクラスは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());
    
36
Cristian

Cristianの答えは良いですが、どこからでも共有設定にアクセスできるようにしたい場合、正しい方法は次のとおりです。

  1. Application のサブクラスを作成します。 _public class MyApp extends Application {_...
  2. AndroidManifest.xmlで_Android:name_タグの_<application>_属性を設定して、新しいクラスを指すようにします。 _Android:name="MyApp"_(したがって、クラスはAndroidによって認識されます)
  3. アプリインスタンスのonCreate()メソッドで、コンテキスト(たとえばthis)をappという名前の静的フィールドに保存し、このフィールドを返す静的メソッドを作成します。 getApp()。その後、このメソッドを使用してアプリケーションのコンテキストを取得し、共有設定を取得できます。 :-)
65
mreichelt

同様の問題がありましたが、現在のコンテキストを静的関数に渡すだけで解決しました。

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;

コンテキストを静的変数として保存すると、クラスが破壊されるときに静的変数も破壊されるため、問題が発生する可能性があります。これは、アプリが中断され、メモリが少なくなると発生することがあります。コンテキストを設定するクラスがランダムに破棄される場合でも、使用する前に常にコンテキストが設定されていることを確認してください。

8
Dan Bray

共有設定を静的フィールドに保存するより良い代替方法を次に示します。

  1. ここで提案されているものと同様に、Applicationを拡張するクラスを作成します
  2. クラスのコンストラクターにContextをパラメーターとして設定させます。
  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();
4
kerux2222

同じニーズがありました-私の好みのいくつかは頻繁に、そして効率的にアクセスされる必要があります。また、SharedPreferencesからの文字列の読み取りと書き込みは、静的変数の取得と設定よりもわずかに遅いことを想像します(ただし、ほとんど意味がない程度です)。また、静的フィールドを使用して、起動時にのみ設定値を取得し、終了時に保存することにも慣れました。

SharedPreferences/contextへの静的な参照を直接保持するオプションは好きではありませんでしたが、これまでのところこの回避策で十分です。

私の解決策:

  1. 必要なすべての静的変数を使用してSettingsクラスを作成します。

  2. アプリケーションが初期化されると、SharedPreferencesフィールドを取得し、すぐにすべてのSettingsフィールドを設定します(MainActivityのonCreateメソッドの最後で "loadSharedPrefs()"メソッドを呼び出します)。

  3. SettingsActivityのpreferenceChangeListenerの初期化で、Settingsクラスの適切な静的フィールドを設定します。 (SettingsActivityのonPreferenceChange()の最初に「setAppropriateSetting(key、value)」メソッドを呼び出します)。

いつでもどこでも静的設定を使用してください!

2
Ed Cooper
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);
}
0
Eric Smith