静的メソッドによる SharedPreferences へのアクセス
-
25-09-2019 - |
質問
いくつかの情報が SharedPreferences として保存されています。アクティビティの外部から (ドメイン モデル クラスから) その情報にアクセスする必要があります。そこで、共有設定を取得するためだけに使用する静的メソッドをアクティビティ内に作成しました。
どうやら静的メソッドから「getSharedPreferences」メソッドを呼び出すことができないため、これによりいくつかの問題が発生します。
日食が私に与えているメッセージは次のとおりです。
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);
}
このコードは NULL ポイント例外を発生させます。
回避策はありますか?これをやろうとすると Android コードの匂いがするのでしょうか?
前もって感謝します。
解決
なぜなら、この場合、 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());
他のヒント
Cristian の答えは良いですが、どこからでも共有設定にアクセスできるようにしたい場合は、正しい方法は次のとおりです。
- のサブクラスを作成します
Application
, 、例えばpublic class MyApp extends Application {
... - をセットする
android:name
あなたの属性<application>
AndroidManifest.xml 内のタグを使用して、新しいクラスをポイントします。android:name="MyApp"
(クラスが Android に認識されるように) - アプリ インスタンスの 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;
クラスがそのように破壊された場合、静的変数があるため、静的変数として、コンテキストの保存、問題を引き起こす可能性があります。これは、時々、アプリが中断されたときに発生し、メモリ上に低くなります。ちょうどあなたがコンテキストを設定するクラスがランダムに破壊された場合でも、それを使用しようとする前に、コンテキストが常に設定されていることを確認します。
これは、共有設定を静的フィールドに保存するより良い代替手段です。
- ここで提案されているのと同様に、Application を拡張するクラスを作成します。
- クラスのコンストラクターがパラメータとして Context を受け取るようにします。
- コンテキストを使用して共有設定を取得し、プライベート変数に保存します。
- 取得したデータを返すパブリック変数を作成します。
例えば
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();
私も同じニーズを持っていました。私の設定の一部には、頻繁かつ効率的にアクセスする必要がありました。また、SharedPreferences からの文字列の読み取りと書き込みは、静的変数の取得と設定よりもわずかに遅いと思います (ただし、程度は重要ではない可能性があります)。また、静的フィールドの使用、起動時にのみ設定値を取得し、閉じるときにそれらの値を保存することにも、少し慣れてきました。
私は SharedPreferences/contexts への静的参照を直接保持するオプションが気に入らなかったのですが、今のところこの回避策で十分です。
私の解決策:
必要なすべての静的変数を含む設定クラスを作成します。
アプリケーションが初期化されると、SharedPreferences フィールドが取得され、すぐにすべての設定フィールドが設定されます (MainActivity の onCreate メソッドの最後で「loadSharedPrefs()」メソッドを呼び出します)。
SettingsActivity のpreferenceChangeListener の初期化で、Settings クラスに適切な静的フィールドを設定します。(SettingsActivity の onPreferenceChange() の先頭で「setAppropriateSetting(key, value)」メソッドを呼び出します)。
いつでもどこでも静的な設定を使用できます。
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);
}