An overview of the

SharedPreferences as the most common persistent storage solution in Android development, it is very suitable for the local storage of attributes and configurations (in addition, local files, database persistence can also be used). Although SharedPreferences are easy to use, it can be a hassle to maintain. It’s easy to define redundant configurations, it can generate a lot of configuration files, and we don’t even have enough confidence that the defined properties are being defined repeatedly (which can lead to hidden bugs). Kotlin is now used to encapsulate object-oriented apis (using techniques such as class extension, dynamic proxy, annotations, etc.).

use

Gradle configured in

Implementation 'com. Zhangzheng. Easystore: library: 1.1.0'Copy the code

Application initialization

 EasyStore.init(this)
Copy the code

SharedPreferences need to be obtained through the Context, because for ease of use and subsequent extensibility, there is no way to pass the Context at the time of use.

The Demo sample

Define the data structure interface

interface TestStorage :Storable{    var name:String    var count:Int    var isBool:Boolean}
Copy the code

In the TestStorage configuration file, three properties are configured. They are used to describe the data structure of the storage and only need to define interfaces

To get the data

 val loadFromLocal = TestStorage::class.load()
Copy the code

Get single data

val name = TestStorage::class.get { name }
Copy the code

Store the data

TestStorage::class.apply {            name = "2777777"            count = 100            isBool =false        }

  TestStorage::class.commit {            name = "2777777"            count = 100            isBool =false        }
Copy the code

Apply is asynchronous, so we can optionally store data. For example, if we only want to store name, we can use the following method:

TestStorage::class.com MIT {name = “2777777”}, other properties will not have a change.

scalability

In real development, we will not only store the configuration in SharedPreferences, database and files are also one of our options. For this case, we can extend 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> { } } }Copy the code

use

@Store(TestStoreBuilder::class)interface TestStorage :Storable{    var name:String    var count:Int    var isBool:Boolean}
Copy the code

instructions

Annotating the constructor is the reason for the design. On the one hand, it is considered that details can be shielded through abstraction. Developers only need to define configuration data structures and do not need to worry about implementation, simplifying the use of the data. Also, annotations can’t pass an instance, so the storage policy is created using a Builder with no construction parameters.

The last

If this article is useful to you, I hope you can pay attention to and like! Here is the source code: github.com/long8313002…