Scaloid provides
a concise way to access SharedPreference using type dynamic of Scala language. A sample code that demonstrate it looks like this:
val pref = Preferences()
val ec = pref.executionCount(0) // read with default value 0
pref.executionCount = ec + 1 // write
pref.remove("executionCount") // remove
It is clearly better than old-Android-API, but it still has some limitations:
- No compile-time name checks
If there are a typo on the key name of the preferences, compiler does not warn you. It will be a nightmare if some preference name is used in multiple places and only one has a typo.
- Key names should be a Scala symbol name
For example, a key.name@with:special#chars
cannot be accessed with Scala type dynamic
- Inconsistencies with method and preference access
In the above example, pref.remove(...)
is a pre-defined method call, while pref.executionCount(...)
is a preference access.
Scaloid 4.0-RC2 contains a new way to access Preferences. Let's look into it:
val executionCount = preferenceVar(0) // default value 0
val ec = executionCount() // read
executionCount() = ec + 1 // write
executionCount.remove() // remove
It is cleaner, performs compile-time validation, and better semantics. Scala macro accesses the value name to be assigned,
executionCount
in this example. If you want a keyname has special characters, we provide an alternative:
val executionCount = preferenceVar("execution.count", 0)
Preference values does not have a dependency on
android.context.Context
when it is created. A
Context
is only needed when it is actually being accessed (e.g. reading, writing, removing). So, it can be a property of plain object (static method in Java terms), and can be defined only once:
object Prefs { // It ensures compile-time name checking
val executionCount = preferenceVar(0)
val showTips = preferenceVar("show-tips", true)
}
class MyActivity extends SActivity {
// access it anywhere having implicit Context
if(Prefs.showTips()) displayTips()
}
Let's compare it with the same code written in plain-old Android API:
object Prefs { // No idea about types, awful naming convention
val EXECUTION_COUNT = "executionCount"
val SHOW_TIPS = "show-tips"
}
class MyActivity extends SActivity {
// Wordy and not type-safe
if(defaultSharedPreference.getBoolean(Prefs.SHOW_TIPS, true)) displayTips()
}
The full source code is listed in
the Scaloid github repository. This is tested on
a millionth-downloaded production app, Soundcorset.