Fork me on GitHub

Friday, March 1, 2013

Dynamically accessing SharedPreferences

Scala 2.10 ships with a new feature called Type Dynamic, which is borrowed from typeless script language (e.g. Groovy). With this feature, the name of methods and properties can be handled in runtime. One of the practical use case of it is accessing SharedPreference object more concisely. An ordinary way of accessing a SharedPreference property looks like this:

val ec = pref.getInt("executionCount", 0)
val editor = pref.edit()
editor.putInt("executionCount", ec + 1)
editor.commit()

Doing some work on the backstage with Type Dynamic, the code can be improved as follows:
val ec = pref.executionCount(0)
pref.executionCount = ec + 1

Accessing properties becomes more natural. To do this, I wrote some helper classes using Type Dynamic as shown below:
class Preferences(val preferences: SharedPreferences) extends Dynamic {
  def updateDynamic(name: String)(value: Any) {
    value match {
      case v: String => preferences.edit().putString(name, v).commit()
      case v: Int => preferences.edit().putInt(name, v).commit()
      case v: Long => preferences.edit().putLong(name, v).commit()
      case v: Boolean => preferences.edit().putBoolean(name, v).commit()
      case v: Float => preferences.edit().putFloat(name, v).commit()
    }
  }

  def applyDynamic[T](name: String)(defaultVal: T): T = defaultVal match {
    case v: String => preferences.getString(name, v).asInstanceOf[T]
    case v: Int => preferences.getInt(name, v).asInstanceOf[T]
    case v: Long => preferences.getLong(name, v).asInstanceOf[T]
    case v: Boolean => preferences.getBoolean(name, v).asInstanceOf[T]
    case v: Float => preferences.getFloat(name, v).asInstanceOf[T]
  }
}
When you access pref.executionCount(0), Scala compiler expands it to pref.applyDynamic("executionCount")(0), and pref.executionCount = ec become pref.updateDynamic("executionCount")(ec).

The full source code can be found here. You can simply download and enjoy it.

Prompt user to rate your Android app

Now, you can easily access persistent properties. One of the most popular example is prompting engaged user to rate your Android app. I posted about it here.

3 comments:

  1. Thanks to this post, I've learnt about Dynamic classes. Thanks.

    ReplyDelete
  2. It would be nice if it could support enumerations as well.

    ReplyDelete
    Replies
    1. android.content.SharedPreferences does not explicitly support enumerations.

      How would it be designed? Any ideas please?

      Delete