Overview
SharedPreferences, as the most commonly used persistent storage solution in android development, is very suitable for local storage of attributes and configurations (in addition, local files and databases can also be used to achieve persistence). Although SharedPreferences is more convenient to use, it is really troublesome to maintain. It is easy to define redundant configurations, and a large number of configuration files may be generated. We even do not have enough confidence to determine whether the defined properties are defined repeatedly. (It will lead to cryptic bugs). Now based on Kotlin to encapsulate the object-oriented API (the technologies used are: class extension, dynamic proxy, annotation, etc.).
use
Configuration in gradle
implementation 'com.zhangzheng.easystore:library:1.1.0'
Application initialization
EasyStore.init(this)
The acquisition of SharedPreferences requires Context, because considering the ease of use and subsequent scalability, the method of passing Context when in use is not adopted.
Demo example
Define data structure interface
interface TestStorage :Storable{
var name:String
var count:Int
var isBool:Boolean
}
In the TestStorage configuration file, three attributes are configured. Only the interface needs to be defined here, and no specific implementation is required to describe the stored data structure
retrieve data
val loadFromLocal = TestStorage::class.load()
Get single data
val name = TestStorage::class.get { name }
Storing data
TestStorage::class.apply {
name = "2777777"
count = 100
isBool =false
}
TestStorage::class.commit {
name = "2777777"
count = 100
isBool =false
}
Apply is asynchronous. In this way, we can selectively store data. For example, if we only want to store name, we can use the following method:
TestStorage::class.commit {name = "2777777"}, other properties will not change.
Scalability
In actual development, we will not only store the configuration in SharedPreferences, but also database and files are one of our choices. In this case, we can expand it ourselves, as follows:
class TestStoreBuilder : IStoreBuilder {
override fun build(storable: KClass<out Storable>, context: Context): IStore {
return TestStore()
}
private class TestStore:IStore{
override fun commit(values: Map<String, Any?>): Boolean {
}
override fun apply(values: Map<String, Any?>) {
}
override fun getAll(): Map<String, Any> {
}
}
}
How to use
@Store(TestStoreBuilder::class)
interface TestStorage :Storable{
var name:String
var count:Int
var isBool:Boolean
}
Description
Specify the constructor by way of annotations, the reason for this method to design. On the one hand, considering the use of abstraction to shield the details, developers only need to define the configuration data structure without paying attention to the implementation, simplifying the difficulty of use; in addition, annotations cannot pass examples, so here we use the Builder without construction parameters to create a storage strategy.
At last
If this article is useful to you, I hope you can follow and like it! Here is the source code: https://github.com/long8313002/EasyStore