SharedPreferences使用起來有些局限渣淤,以及它調(diào)用比較復(fù)雜岖瑰,并且只支持基本數(shù)據(jù)類型和String的存儲(chǔ),不支持自定義對(duì)象存儲(chǔ)砂代。記得以前有次為了不使用SQLite整個(gè)項(xiàng)目又只為了存儲(chǔ)一個(gè)對(duì)象,我只得把對(duì)象轉(zhuǎn)成JsonString率挣,再把JsonString作為字符串存入SharedPreferences刻伊。
后來接觸到Reservoir后用它進(jìn)行本地存儲(chǔ)輕量級(jí)的數(shù)據(jù),一直使用至今椒功。Reservoir是使用DiskLruCache建立磁盤緩存進(jìn)行存儲(chǔ)捶箱,當(dāng)應(yīng)用卸載時(shí),緩存也會(huì)被系統(tǒng)清除动漾。DiskLruCache也是開發(fā)者常用的圖片緩存技術(shù)之一丁屎。
GitHub地址:
https://github.com/anupcowkur/Reservoir
gradle鏈接:
implementation 'com.anupcowkur:reservoir:3.1.0'
開始Reservoir食用
在項(xiàng)目的build.gradle中添加
buildscript {
...
repositories {
jcenter()
}
...
}
在app的build.gradle中添加依賴
dependencies {
...
// 本地存儲(chǔ)替代shareprefer
implementation 'com.anupcowkur:reservoir:3.1.0'
...
}
此時(shí)已經(jīng)完成Reservoir的所有導(dǎo)入步驟。
在項(xiàng)目中使用時(shí)需要先給Reservoir開辟內(nèi)存空間做初始化旱眯,單位:bytes晨川。
例子中我在Activity的onCreate()中進(jìn)行了初始化,當(dāng)然它也可以在Application中的onCreate()或是Fragment里初始化删豺,關(guān)鍵是要獲得到Context即可共虑。
class TestActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 初始化
Reservoir.init(this, 2048)
}
}
建立自己的Reservoir管理類,如下代碼演示了一個(gè)String呀页、自定義對(duì)象妈拌、以及List的存儲(chǔ)方式,其余類型就不一一舉例蓬蝶,畢竟存儲(chǔ)對(duì)象和List才是關(guān)鍵尘分。
object ReservoirHelper {
...
// 所在城市
fun setCity(city: String) {
Reservoir.put("city", city)
}
fun getCity(): String {
if (Reservoir.contains("city"))
return Reservoir.get("city", String::class.java)
else
return "北京市"
}
// 天氣數(shù)據(jù)
fun setWeatherFreeInfo(weatherFreeInfo: WeatherFreeInfo) {
Reservoir.put("weatherFreeInfo", weatherFreeInfo)
}
fun getWeatherFreeInfo(): WeatherFreeInfo {
if (Reservoir.contains("weatherFreeInfo"))
return Reservoir.get("weatherFreeInfo", WeatherFreeInfo::class.java)
else
return WeatherFreeInfo()
}
// 房間數(shù)據(jù)
fun setRoomList(roomList: List<Room>) {
Reservoir.put("roomList", roomList)
}
fun getRoomList(): List<Room> {
if (Reservoir.contains("roomList"))
return Reservoir.get("roomList", object : TypeToken<List<Room>>() {}.type)
else
return ArrayList()
}
...
}
接下來我們就可以調(diào)用管理類進(jìn)行數(shù)據(jù)存儲(chǔ)猜惋,此處只舉例了List的存取
val roomList = ArrayList<Room>()
val r1 = Room()
val r2 = Room()
val r3 = Room()
roomList.add(r1)
roomList.add(r2)
roomList.add(r3)
// 進(jìn)行存儲(chǔ)
ReservoirHelper.setRoomList(room)
// 進(jìn)行讀取
val roomList = ReservoirHelper.getRoomList()
Log.d(TAG, "-->> 第二個(gè)房間溫度是${roomList[1].temperature}℃")
只要封裝得當(dāng),即可在項(xiàng)目低耦合的引用到它培愁。它可以出現(xiàn)在任何地方著摔,任何地方,任何地方(重要的事情說三遍)竭钝,任何一個(gè)獨(dú)立的Java類都可以進(jìn)行存取操作梨撞。
Reservoir常用方法
UI線程存取方法:
// 存
Reservoir.put("myKey", myObject)
// 取
Reservoir.get("myKey", MyClass.class)
異步存取方法:
Reservoir.putAsync("myKey", myObject, object : ReservoirPutCallback {
override fun onSuccess() {
//success
}
override fun onFailure(e: Exception) {
//error
}
})
Reservoir.getAsync<MyClass>("myKey", MyClass::class.java, object : ReservoirGetCallback<MyClass> {
override fun onSuccess(myObject: MyClass) {
//success
}
override fun onFailure(e: Exception) {
//error
}
})
檢查是否存在:
val isExists = Reservoir.contains("myKey")
刪除:
// UI線程執(zhí)行刪除
Reservoir.delete("myKey")
// 異步刪除
Reservoir.deleteAsync("myKey", object : ReservoirDeleteCallback {
fun onSuccess(myObject: MyClass) {
//success
}
override fun onFailure(e: Exception) {
//error
}
})
清空Reservoir的緩存:
Reservoir.clear()
Reservoir.clearAsync(object : ReservoirClearCallback {
override fun onSuccess() {
try {
assertEquals(0, Reservoir.bytesUsed())
} catch (e: Exception) {
}
}
override fun onFailure(e: Exception) {
}
})
到此,Reservoir已經(jīng)食用差不多香罐,需要深度學(xué)習(xí)與RxJava交互卧波,可以參考開頭的GitHub原作者鏈接進(jìn)行學(xué)習(xí)。