背景
工作中经常会遇到 最近 等类似功能,这些功能都需要保存相应的对象信息,但是由于这些对象在每次重新启动后都会再次初始化加载到内存中,可以通过只保存对象的某种唯一标志简单快速实现 最近 等类似功能。
原理
- 当需要保存 最近 对应的对象信息时,只保存对象的 key 信息,将 key 集合信息通过
,
连接转换成一个字符串后,通过 SP 保存
- 当 App 初始化 最近 相关的对象时,将这些对象根据 key 保存在一个 Map 中
- 当需要加载 最近 信息时,根据 SP 中存储的 key 信息和上面 Map 中存储的对象信息可以得出想要的 最近 对应的对象信息
实现
基类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| open class XLItemStore(private val context: Context, private val storeKey: String) { private val executor = Executors.newSingleThreadExecutor(XLThreadFactory()) private val key2ObjectMap = mutableMapOf<String, StorableItem>()
fun addKeyToObject(item: StorableItem) { if (key2ObjectMap.containsKey(item.key)) { return } key2ObjectMap[item.key] = item }
fun clearKeyToObject() { key2ObjectMap.clear() }
protected fun saveItem(items: Collection<StorableItem>) { executor.submit { val itemKeys = StringBuilder("") items.forEach { if (itemKeys.isNotEmpty()) { itemKeys.append(",") } itemKeys.append(it.key) } saveBySp(itemKeys.toString()) } }
protected fun loadItems(container: MutableSet<StorableItem>) { val keyList = getKeysBySp().split(",") keyList.forEach { (key2ObjectMap[it])?.let { item -> container.add(item) } } }
private fun saveBySp(value: String) { val sp = context.getSharedPreferences("xl_item", Context.MODE_PRIVATE) sp.edit().putString(storeKey, value).apply() }
private fun getKeysBySp(): String { val sp = context.getSharedPreferences("xl_item", Context.MODE_PRIVATE) return sp.getString(storeKey, "") ?: "" } }
private class XLThreadFactory : ThreadFactory { private val namePrefix = "XL.Thread" private val group = Thread.currentThread().threadGroup!! private val threadNumber = AtomicInteger(1)
override fun newThread(r: Runnable?): Thread { val thread = Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0) if (thread.isDaemon) { thread.isDaemon = false } if (thread.priority != Thread.NORM_PRIORITY) { thread.priority = Thread.NORM_PRIORITY } return thread } }
interface StorableItem { val key: String }
|
最近
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class RecentItemStore(context: Context, storeKey: String) : XLItemStore(context, storeKey) { private val displayNum = -1 private val recentItems = LinkedHashSet<StorableItem>()
fun restore() { if (recentItems.isNotEmpty()) { recentItems.clear() } loadItems(recentItems) }
fun getRecentItems(): Set<StorableItem> { return recentItems }
fun saveRecentItem(item: StorableItem) { val oldItem = recentItems.firstOrNull { it.key == item.key } recentItems.remove(oldItem) recentItems.add(item)
if (recentItems.size > displayNum && displayNum > 0) { recentItems.remove(recentItems.iterator().next()) } saveItem(recentItems) }
fun removeRecentItems() { clearKeyToObject() recentItems.clear() } }
|
具体使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| val store = RecentItemStore(...)
store.addKeyToObject(...)
store.restore()
store.getRecentItems()
store.saveRecentItem(...)
|