2017-12-15 8 views
1

私はkotlinを使ってアンドロイドに私のSharedPreferenceのヘルパークラスを作成したいと思います。 残念ながら私はContextが必要で、私はそれをパラメータとして毎回電話を設定したくないです。Android - SharedPreferences - コンテキスト

私は、コンテキストのためのコンパニオンオブジェクトを使用すると、アプリケーション起動時に設定した場合、私は次のエラーを取得する:Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)

私は好みを呼び出し、どのように毎回それを渡さずに、コンテキストを取得しますか?

var isWorking: Boolean 
    get() = getBoolean(IS_WORKING) 
    set(isWorking) = setPreference(IS_WORKING, isWorking) 

private fun setPreference(key: String, value: Boolean) { 
    val editor = settings.edit() 
    editor.putBoolean(key, value) 
    editor.commit() 
} 

private val settings: SharedPreferences by lazy { 
    context.getSharedPreferences("prefs", Context.MODE_PRIVATE) 
} 
+1

これはあなたの質問には答えませんが、毎回そのコンテキストを渡す必要があります。メッセージが示すように、アクティビティーが終了したときに操作がまだ実行中であれば、アクティビティーがリークする可能性があります。私の経験では、何らかの操作が行われたときにコンテキストを受け取るPreferenceHelperクラスを常に見ていました。 –

答えて

5

あなたは以下のようなextension functionを作成することができます。

object PreferenceHelper { 

    fun defaultPrefs(context: Context): SharedPreferences 
      = PreferenceManager.getDefaultSharedPreferences(context) 

    fun customPrefs(context: Context, name: String): SharedPreferences 
      = context.getSharedPreferences(name, Context.MODE_PRIVATE) 

    inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) { 
      val editor = this.edit() 
      operation(editor) 
      editor.apply() 
     } 
} 

編集: Hereこの回答のリファレンスです。あなたはをリファクタリングする方法を確認してKotlinトリックを使ってそれを使うことができます。

EDIT2:

あなたはクラスにあなたのヘルパーを変更してApplicationでこれを初期化することができます。それから、どこでも好きな場所で使うことができます。私はこれがあなたがやろうとしていることだと思います。やってみましょう。

class PreferenceHelper constructor(context: Context){ 

     fun defaultPrefs(): SharedPreferences 
       = PreferenceManager.getDefaultSharedPreferences(context) 

     fun customPrefs(name: String): SharedPreferences 
       = context.getSharedPreferences(name, Context.MODE_PRIVATE) 

     inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) { 
       val editor = this.edit() 
       operation(editor) 
       editor.apply() 
      } 
    } 

、アプリケーションのクラスで:

class YourApp : Application() { 

    override fun onCreate() { 
     super.onCreate() 
     YourApp.prefHelper = PreferenceHelper(this) 
    } 

    companion object { 
     lateinit var prefHelper: PreferenceHelper 
      private set 
    } 
} 

そして、あなたは以下のように好きな場所あなたが使用することができます。

YourApp.prefHelper.defaultPrefs().edit { 
    // Your shared pref operations. 
} 

私は最初のものがベストプラクティスにより近いと思いますが、もう一つは大丈夫です。あなたは必要なものを使うことができます。また、私が上で提供したリンクのコンテンツにはさらに優れた例があります。

+0

あなたの答えをありがとう。しかし、それは本当に私が望んでいたものではありません。コンストラクタを使ってヘルパークラスを呼び出すだけで、ここで違いはありません。 –

+1

私は自分の答えを編集し、あなたがしたいことを実装しようとしました。私は最初の1つを好むが、2番目のものもokeyだ – savepopulation

0

私の問題の解決策を見つけました。コンテキストの代わりにSharedPreferences変数を保持して解決しました。

object PreferenceDao { 
    private lateinit var settings: SharedPreferences 

    fun init(context: Context) { 
     settings = context.getSharedPreferences("prefs", Context.MODE_PRIVATE) 
    } 
} 

Applicationクラスでinit関数が呼び出されます。

+0

依存性注入フレームワークの使用を検討しましたか? – tynn

+0

何ですか?聞いたことがない。 –

関連する問題