diff --git a/docs-source/src/en/api/public/com/highcapable/yukihookapi/YukiHookAPI.md b/docs-source/src/en/api/public/com/highcapable/yukihookapi/YukiHookAPI.md index 7eb57611..8ec63842 100644 --- a/docs-source/src/en/api/public/com/highcapable/yukihookapi/YukiHookAPI.md +++ b/docs-source/src/en/api/public/com/highcapable/yukihookapi/YukiHookAPI.md @@ -414,23 +414,15 @@ var isDebug: Boolean 请转移到 `isEnablePrefsBridgeCache` -### isEnablePrefsBridgeCache - field - -```kotlin:no-line-numbers -var isEnablePrefsBridgeCache: Boolean -``` +

isEnablePrefsBridgeCache - field

**Change Records** `v1.1.9` `added` -**Function Illustrate** +`v1.1.11` `deprecated` -> 是否启用 `YukiHookPrefsBridge` 的键值缓存功能。 - -为防止内存复用过高问题,此功能默认启用。 - -你可以手动在 `YukiHookPrefsBridge` 中自由开启和关闭缓存功能以及清除缓存。 +键值的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题 ### isEnableModuleAppResourcesCache - field @@ -582,7 +574,6 @@ object HookEntry : IYukiHookXposedInit { elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID) } isDebug = BuildConfig.DEBUG - isEnablePrefsBridgeCache = true isEnableModuleAppResourcesCache = true isEnableHookModuleStatus = true isEnableHookSharedPreferences = false @@ -612,7 +603,6 @@ object HookEntry : IYukiHookXposedInit { elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID) } isDebug = BuildConfig.DEBUG - isEnablePrefsBridgeCache = true isEnableModuleAppResourcesCache = true isEnableHookModuleStatus = true isEnableHookSharedPreferences = false @@ -644,7 +634,6 @@ object HookEntry : IYukiHookXposedInit { YukiHookLogger.Configs.USER_ID ) YukiHookAPI.Configs.isDebug = BuildConfig.DEBUG - YukiHookAPI.Configs.isEnablePrefsBridgeCache = true YukiHookAPI.Configs.isEnableModuleAppResourcesCache = true YukiHookAPI.Configs.isEnableHookModuleStatus = true YukiHookAPI.Configs.isEnableHookSharedPreferences = false diff --git a/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.md b/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.md index ab635f4c..5d1a2f93 100644 --- a/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.md +++ b/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.md @@ -132,23 +132,15 @@ prefs("custom_name").getString("custom_key") prefs("custom_name").getString("custom_key") ``` -## direct - method - -```kotlin:no-line-numbers -fun direct(): YukiHookPrefsBridge -``` +

direct - method

**Change Records** `v1.0.5` `added` -**Function Illustrate** +`v1.1.11` `deprecated` -> 忽略缓存直接读取键值。 - -无论是否开启 `YukiHookAPI.Configs.isEnablePrefsBridgeCache`。 - -仅在 `XSharedPreferences` 下生效。 +键值的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题 ## native - method @@ -436,23 +428,15 @@ fun edit(initiate: Editor.() -> Unit) ::: -## clearCache - method - -```kotlin:no-line-numbers -fun clearCache() -``` +

clearCache - method

**Change Records** `v1.0.5` `added` -**Function Illustrate** +`v1.1.11` `deprecated` -> 清除 `YukiHookPrefsBridge` 中缓存的键值数据。 - -无论是否开启 `YukiHookAPI.Configs.isEnablePrefsBridgeCache`。 - -调用此方法将清除当前存储的全部键值缓存。 +键值的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题 ## Editor - class diff --git a/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/YukiHookAPI.md b/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/YukiHookAPI.md index d9eadabc..820e596a 100644 --- a/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/YukiHookAPI.md +++ b/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/YukiHookAPI.md @@ -406,23 +406,15 @@ var isDebug: Boolean 请转移到 `isEnablePrefsBridgeCache` -### isEnablePrefsBridgeCache - field - -```kotlin:no-line-numbers -var isEnablePrefsBridgeCache: Boolean -``` +

isEnablePrefsBridgeCache - field

**变更记录** `v1.1.9` `新增` -**功能描述** +`v1.1.11` `作废` -> 是否启用 `YukiHookPrefsBridge` 的键值缓存功能。 - -为防止内存复用过高问题,此功能默认启用。 - -你可以手动在 `YukiHookPrefsBridge` 中自由开启和关闭缓存功能以及清除缓存。 +键值的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题 ### isEnableModuleAppResourcesCache - field @@ -574,7 +566,6 @@ object HookEntry : IYukiHookXposedInit { elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID) } isDebug = BuildConfig.DEBUG - isEnablePrefsBridgeCache = true isEnableModuleAppResourcesCache = true isEnableHookModuleStatus = true isEnableHookSharedPreferences = false @@ -604,7 +595,6 @@ object HookEntry : IYukiHookXposedInit { elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID) } isDebug = BuildConfig.DEBUG - isEnablePrefsBridgeCache = true isEnableModuleAppResourcesCache = true isEnableHookModuleStatus = true isEnableHookSharedPreferences = false @@ -636,7 +626,6 @@ object HookEntry : IYukiHookXposedInit { YukiHookLogger.Configs.USER_ID ) YukiHookAPI.Configs.isDebug = BuildConfig.DEBUG - YukiHookAPI.Configs.isEnablePrefsBridgeCache = true YukiHookAPI.Configs.isEnableModuleAppResourcesCache = true YukiHookAPI.Configs.isEnableHookModuleStatus = true YukiHookAPI.Configs.isEnableHookSharedPreferences = false diff --git a/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.md b/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.md index 4a5c204d..276885a2 100644 --- a/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.md +++ b/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.md @@ -124,23 +124,15 @@ prefs("custom_name").getString("custom_key") prefs("custom_name").getString("custom_key") ``` -## direct - method - -```kotlin:no-line-numbers -fun direct(): YukiHookPrefsBridge -``` +

direct - method

**变更记录** `v1.0.5` `新增` -**功能描述** +`v1.1.11` `作废` -> 忽略缓存直接读取键值。 - -无论是否开启 `YukiHookAPI.Configs.isEnablePrefsBridgeCache`。 - -仅在 `XSharedPreferences` 下生效。 +键值的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题 ## native - method @@ -428,23 +420,15 @@ fun edit(initiate: Editor.() -> Unit) ::: -## clearCache - method - -```kotlin:no-line-numbers -fun clearCache() -``` +

clearCache - method

**变更记录** `v1.0.5` `新增` -**功能描述** +`v1.1.11` `作废` -> 清除 `YukiHookPrefsBridge` 中缓存的键值数据。 - -无论是否开启 `YukiHookAPI.Configs.isEnablePrefsBridgeCache`。 - -调用此方法将清除当前存储的全部键值缓存。 +键值的直接缓存功能已被移除,因为其存在内存溢出 (OOM) 问题 ## Editor - class diff --git a/yukihookapi/src/main/java/com/highcapable/yukihookapi/YukiHookAPI.kt b/yukihookapi/src/main/java/com/highcapable/yukihookapi/YukiHookAPI.kt index f8178304..c33d7f12 100644 --- a/yukihookapi/src/main/java/com/highcapable/yukihookapi/YukiHookAPI.kt +++ b/yukihookapi/src/main/java/com/highcapable/yukihookapi/YukiHookAPI.kt @@ -288,20 +288,17 @@ object YukiHookAPI { * - ❗请现在转移到 [isEnablePrefsBridgeCache] */ @Deprecated(message = "请使用新的命名方法来实现此功能", ReplaceWith("isEnablePrefsBridgeCache")) - var isEnableModulePrefsCache - get() = isEnablePrefsBridgeCache - set(value) { - isEnablePrefsBridgeCache = value - } + var isEnableModulePrefsCache = false /** * 是否启用 [YukiHookPrefsBridge] 的键值缓存功能 * - * - 为防止内存复用过高问题 - 此功能默认启用 + * - ❗此方法及功能已被移除 - 在之后的版本中将直接被删除 * - * 你可以手动在 [YukiHookPrefsBridge] 中自由开启和关闭缓存功能以及清除缓存 + * - ❗键值的直接缓存功能已被移除 - 因为其存在内存溢出 (OOM) 问题 */ - var isEnablePrefsBridgeCache = true + @Deprecated(message = "此方法及功能已被移除,请删除此方法") + var isEnablePrefsBridgeCache = false /** * 是否启用当前 Xposed 模块自身 [Resources] 缓存功能 diff --git a/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.kt b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.kt index d9c35785..5e8eb4c2 100644 --- a/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.kt +++ b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge.kt @@ -39,7 +39,6 @@ import com.highcapable.yukihookapi.hook.log.yLoggerW import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule import com.highcapable.yukihookapi.hook.xposed.bridge.delegate.XSharedPreferencesDelegate import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics -import com.highcapable.yukihookapi.hook.xposed.prefs.cache.PreferencesCacheManager import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData import com.highcapable.yukihookapi.hook.xposed.prefs.ui.ModulePreferenceFragment import de.robv.android.xposed.XSharedPreferences @@ -99,6 +98,12 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu /** 存储名称 */ private var prefsName = "" + /** 是否使用新版存储方式 EdXposed、LSPosed */ + private var isUsingNewXSharedPreferences = false + + /** 是否启用原生存储方式 */ + private var isUsingNativeStorage = false + /** * 获取当前存储名称 - 默认包名 + _preferences * @return [String] @@ -109,12 +114,6 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu else "${YukiXposedModule.modulePackageName.ifBlank { context?.packageName ?: "unknown" }}_preferences" } - /** 是否使用新版存储方式 EdXposed、LSPosed */ - private var isUsingNewXSharedPreferences = false - - /** 是否启用原生存储方式 */ - private var isUsingNativeStorage = false - /** 检查 API 装载状态 */ private fun checkApi() { if (YukiHookAPI.isLoadedFromBaseContext) error("YukiHookPrefsBridge not allowed in Custom Hook API") @@ -122,6 +121,18 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu error("Xposed modulePackageName load failed, please reset and rebuild it") } + /** + * 设置全局可读可写 + * @param callback 回调方法体 + * @return [T] + */ + private fun makeWorldReadable(callback: () -> T): T { + val result = callback() + if (isXposedEnvironment.not() && isUsingNewXSharedPreferences.not()) + runCatching { makeWorldReadable(context, prefsFileName = "${currentPrefsName}.xml") } + return result + } + /** * 获取当前 [XSharedPreferences] 对象 * @return [XSharedPreferences] @@ -161,17 +172,6 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu } } - /** 设置全局可读可写 */ - private fun makeWorldReadable() = runCatching { - if (isUsingNewXSharedPreferences.not()) makeWorldReadable(context, prefsFileName = "${currentPrefsName}.xml") - } - - /** - * 获取当前 [PreferencesCacheManager] 对象 - * @return [PreferencesCacheManager] - */ - private val cacheManager get() = PreferencesCacheManager.instance() - /** * 获取 [XSharedPreferences] 是否可读 * @@ -217,7 +217,6 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @return [YukiHookPrefsBridge] */ fun name(name: String): YukiHookPrefsBridge { - cacheManager.enableByConfig() prefsName = name return this } @@ -225,15 +224,13 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu /** * 忽略缓存直接读取键值 * - * 无论是否开启 [YukiHookAPI.Configs.isEnableModulePrefsCache] + * - ❗此方法及功能已被移除 - 在之后的版本中将直接被删除 * - * - 仅在 [XSharedPreferences] 下生效 + * - ❗键值的直接缓存功能已被移除 - 因为其存在内存溢出 (OOM) 问题 * @return [YukiHookPrefsBridge] */ - fun direct(): YukiHookPrefsBridge { - cacheManager.disable() - return this - } + @Deprecated(message = "此方法及功能已被移除,请删除此方法", ReplaceWith("this")) + fun direct() = this /** * 忽略当前环境直接使用 [Context.getSharedPreferences] 存取数据 @@ -257,12 +254,11 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 默认数据 - "" * @return [String] */ - fun getString(key: String, value: String = "") = - cacheManager.getString(key) { - if (isXposedEnvironment && isUsingNativeStorage.not()) - currentXsp.getString(key, value) ?: value - else currentSp.getString(key, value) ?: value - }.also { makeWorldReadable() } + fun getString(key: String, value: String = "") = makeWorldReadable { + if (isXposedEnvironment && isUsingNativeStorage.not()) + currentXsp.getString(key, value) ?: value + else currentSp.getString(key, value) ?: value + } /** * 获取 [Set]<[String]> 键值 @@ -274,12 +270,11 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 默认数据 - [HashSet]<[String]> * @return [Set]<[String]> */ - fun getStringSet(key: String, value: Set = hashSetOf()) = - cacheManager.getStringSet(key) { - if (isXposedEnvironment && isUsingNativeStorage.not()) - currentXsp.getStringSet(key, value) ?: value - else currentSp.getStringSet(key, value) ?: value - }.also { makeWorldReadable() } + fun getStringSet(key: String, value: Set = hashSetOf()) = makeWorldReadable { + if (isXposedEnvironment && isUsingNativeStorage.not()) + currentXsp.getStringSet(key, value) ?: value + else currentSp.getStringSet(key, value) ?: value + } /** * 获取 [Boolean] 键值 @@ -291,12 +286,11 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 默认数据 - false * @return [Boolean] */ - fun getBoolean(key: String, value: Boolean = false) = - cacheManager.getBoolean(key) { - if (isXposedEnvironment && isUsingNativeStorage.not()) - currentXsp.getBoolean(key, value) - else currentSp.getBoolean(key, value) - }.also { makeWorldReadable() } + fun getBoolean(key: String, value: Boolean = false) = makeWorldReadable { + if (isXposedEnvironment && isUsingNativeStorage.not()) + currentXsp.getBoolean(key, value) + else currentSp.getBoolean(key, value) + } /** * 获取 [Int] 键值 @@ -308,12 +302,11 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 默认数据 - 0 * @return [Int] */ - fun getInt(key: String, value: Int = 0) = - cacheManager.getInt(key) { - if (isXposedEnvironment && isUsingNativeStorage.not()) - currentXsp.getInt(key, value) - else currentSp.getInt(key, value) - }.also { makeWorldReadable() } + fun getInt(key: String, value: Int = 0) = makeWorldReadable { + if (isXposedEnvironment && isUsingNativeStorage.not()) + currentXsp.getInt(key, value) + else currentSp.getInt(key, value) + } /** * 获取 [Float] 键值 @@ -325,12 +318,11 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 默认数据 - 0f * @return [Float] */ - fun getFloat(key: String, value: Float = 0f) = - cacheManager.getFloat(key) { - if (isXposedEnvironment && isUsingNativeStorage.not()) - currentXsp.getFloat(key, value) - else currentSp.getFloat(key, value) - }.also { makeWorldReadable() } + fun getFloat(key: String, value: Float = 0f) = makeWorldReadable { + if (isXposedEnvironment && isUsingNativeStorage.not()) + currentXsp.getFloat(key, value) + else currentSp.getFloat(key, value) + } /** * 获取 [Long] 键值 @@ -342,12 +334,11 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 默认数据 - 0L * @return [Long] */ - fun getLong(key: String, value: Long = 0L) = - cacheManager.getLong(key) { - if (isXposedEnvironment && isUsingNativeStorage.not()) - currentXsp.getLong(key, value) - else currentSp.getLong(key, value) - }.also { makeWorldReadable() } + fun getLong(key: String, value: Long = 0L) = makeWorldReadable { + if (isXposedEnvironment && isUsingNativeStorage.not()) + currentXsp.getLong(key, value) + else currentSp.getLong(key, value) + } /** * 智能获取指定类型的键值 @@ -540,11 +531,14 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu /** * 清除 [YukiHookPrefsBridge] 中缓存的键值数据 * - * 无论是否开启 [YukiHookAPI.Configs.isEnableModulePrefsCache] + * - ❗此方法及功能已被移除 - 在之后的版本中将直接被删除 * - * 调用此方法将清除当前存储的全部键值缓存 + * - ❗键值的直接缓存功能已被移除 - 因为其存在内存溢出 (OOM) 问题 + * @return [YukiHookPrefsBridge] */ - fun clearCache() = cacheManager.edit().clear().apply() + @Deprecated(message = "此方法及功能已被移除,请删除此方法") + fun clearCache() { + } /** * [YukiHookPrefsBridge] 的存储代理类 @@ -560,19 +554,12 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu /** 创建新的存储代理类 */ private var editor = runCatching { currentSp.edit() }.getOrNull() - /** 创建 [PreferencesCacheManager] 存储代理类 */ - private var cacheEditor = cacheManager.edit() - /** * 移除全部包含 [key] 的存储数据 * @param key 键值名称 * @return [Editor] */ - fun remove(key: String) = specifiedScope { - editor?.remove(key) - cacheEditor.remove(key) - makeWorldReadable() - } + fun remove(key: String) = specifiedScope { editor?.remove(key) } /** * 移除 [PrefsData.key] 的存储数据 @@ -585,11 +572,7 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * 移除全部存储数据 * @return [Editor] */ - fun clear() = specifiedScope { - editor?.clear() - cacheEditor.clear() - makeWorldReadable() - } + fun clear() = specifiedScope { editor?.clear() } /** * 存储 [String] 键值 @@ -599,11 +582,7 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 键值数据 * @return [Editor] */ - fun putString(key: String, value: String) = specifiedScope { - editor?.putString(key, value) - cacheEditor.updateString(key, value) - makeWorldReadable() - } + fun putString(key: String, value: String) = specifiedScope { editor?.putString(key, value) } /** * 存储 [Set]<[String]> 键值 @@ -613,11 +592,7 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 键值数据 * @return [Editor] */ - fun putStringSet(key: String, value: Set) = specifiedScope { - editor?.putStringSet(key, value) - cacheEditor.updateStringSet(key, value) - makeWorldReadable() - } + fun putStringSet(key: String, value: Set) = specifiedScope { editor?.putStringSet(key, value) } /** * 存储 [Boolean] 键值 @@ -627,11 +602,7 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 键值数据 * @return [Editor] */ - fun putBoolean(key: String, value: Boolean) = specifiedScope { - editor?.putBoolean(key, value) - cacheEditor.updateBoolean(key, value) - makeWorldReadable() - } + fun putBoolean(key: String, value: Boolean) = specifiedScope { editor?.putBoolean(key, value) } /** * 存储 [Int] 键值 @@ -641,11 +612,7 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 键值数据 * @return [Editor] */ - fun putInt(key: String, value: Int) = specifiedScope { - editor?.putInt(key, value) - cacheEditor.updateInt(key, value) - makeWorldReadable() - } + fun putInt(key: String, value: Int) = specifiedScope { editor?.putInt(key, value) } /** * 存储 [Float] 键值 @@ -655,11 +622,7 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 键值数据 * @return [Editor] */ - fun putFloat(key: String, value: Float) = specifiedScope { - editor?.putFloat(key, value) - cacheEditor.updateFloat(key, value) - makeWorldReadable() - } + fun putFloat(key: String, value: Float) = specifiedScope { editor?.putFloat(key, value) } /** * 存储 [Long] 键值 @@ -669,11 +632,7 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * @param value 键值数据 * @return [Editor] */ - fun putLong(key: String, value: Long) = specifiedScope { - editor?.putLong(key, value) - cacheEditor.updateLong(key, value) - makeWorldReadable() - } + fun putLong(key: String, value: Long) = specifiedScope { editor?.putLong(key, value) } /** * 智能存储指定类型的键值 @@ -706,10 +665,10 @@ class YukiHookPrefsBridge private constructor(private var context: Context? = nu * 提交更改 (同步) * @return [Boolean] 是否成功 */ - fun commit() = editor?.commit()?.also { cacheEditor.apply(); makeWorldReadable() } ?: false + fun commit() = makeWorldReadable { editor?.commit() ?: false } /** 提交更改 (异步) */ - fun apply() = editor?.apply().also { cacheEditor.apply(); makeWorldReadable() } ?: Unit + fun apply() = makeWorldReadable { editor?.apply() ?: Unit } /** * 仅在模块环境或 [isUsingNativeStorage] 执行 diff --git a/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/cache/PreferencesCacheManager.kt b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/cache/PreferencesCacheManager.kt deleted file mode 100644 index 902089ed..00000000 --- a/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/cache/PreferencesCacheManager.kt +++ /dev/null @@ -1,247 +0,0 @@ -/* - * YukiHookAPI - An efficient Hook API and Xposed Module solution built in Kotlin. - * Copyright (C) 2019-2023 HighCapable - * https://github.com/fankes/YukiHookAPI - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * This file is Created by fankes on 2023/4/20. - */ -package com.highcapable.yukihookapi.hook.xposed.prefs.cache - -import com.highcapable.yukihookapi.YukiHookAPI -import com.highcapable.yukihookapi.hook.utils.memory.factory.createLruCache -import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookPrefsBridge - -/** - * [YukiHookPrefsBridge] 缓存管理类 - */ -internal class PreferencesCacheManager private constructor() { - - internal companion object { - - /** 当前 [PreferencesCacheManager] 单例 */ - private var instance: PreferencesCacheManager? = null - - /** - * 获取 [PreferencesCacheManager] 单例 - * @return [PreferencesCacheManager] - */ - internal fun instance() = instance ?: PreferencesCacheManager().apply { instance = this } - } - - /** 是否使用键值缓存功能 */ - private var isUsingKeyValueCache = YukiHookAPI.Configs.isEnablePrefsBridgeCache - - private val stringData = createLruCache() - private val stringSetData = createLruCache>() - private val booleanData = createLruCache() - private val intData = createLruCache() - private val longData = createLruCache() - private val floatData = createLruCache() - - /** - * 获取缓存的 [String] 键值 - * @param key 键值名称 - * @param value 无缓存获取回调 - */ - internal fun getString(key: String, value: () -> String) = - if (isUsingKeyValueCache) stringData.get(key) ?: resetCacheSet { value().also { stringData.put(key, it) } } else value() - - /** - * 获取缓存的 [Set]<[String]> 键值 - * @param key 键值名称 - * @param value 无缓存获取回调 - */ - internal fun getStringSet(key: String, value: () -> Set) = - if (isUsingKeyValueCache) stringSetData.get(key) ?: resetCacheSet { value().also { stringSetData.put(key, it) } } else value() - - /** - * 获取缓存的 [Boolean] 键值 - * @param key 键值名称 - * @param value 无缓存获取回调 - */ - internal fun getBoolean(key: String, value: () -> Boolean) = - if (isUsingKeyValueCache) booleanData.get(key) ?: resetCacheSet { value().also { booleanData.put(key, it) } } else value() - - /** - * 获取缓存的 [Int] 键值 - * @param key 键值名称 - * @param value 无缓存获取回调 - */ - internal fun getInt(key: String, value: () -> Int) = - if (isUsingKeyValueCache) intData.get(key) ?: resetCacheSet { value().also { intData.put(key, it) } } else value() - - /** - * 获取缓存的 [Long] 键值 - * @param key 键值名称 - * @param value 无缓存获取回调 - */ - internal fun getLong(key: String, value: () -> Long) = - if (isUsingKeyValueCache) longData.get(key) ?: resetCacheSet { value().also { longData.put(key, it) } } else value() - - /** - * 获取缓存的 [Float] 键值 - * @param key 键值名称 - * @param value 无缓存获取回调 - */ - internal fun getFloat(key: String, value: () -> Float) = - if (isUsingKeyValueCache) floatData.get(key) ?: resetCacheSet { value().also { floatData.put(key, it) } } else value() - - /** - * 创建新的 [Editor] - * @return [Editor] - */ - internal fun edit() = Editor() - - /** 启用缓存功能 - 跟随 [YukiHookAPI.Configs.isEnablePrefsBridgeCache] 控制 */ - internal fun enableByConfig() { - isUsingKeyValueCache = YukiHookAPI.Configs.isEnablePrefsBridgeCache - } - - /** 禁用缓存功能 */ - internal fun disable() { - isUsingKeyValueCache = false - } - - /** - * [PreferencesCacheManager] 的存储代理类 - * - * - ❗请使用 [edit] 方法来获取 [Editor] - */ - internal inner class Editor internal constructor() { - - /** 预提交任务数组 */ - private val preSubmitTasks = HashSet<() -> Unit>() - - /** - * 更新缓存的 [String] 键值 - * @param key 键值名称 - * @param value 键值内容 - * @return [Editor] - */ - internal fun updateString(key: String, value: String): Editor { - if (isUsingKeyValueCache) preSubmitTasks.add { stringData.put(key, value) } - return this - } - - /** - * 更新缓存的 [Set]<[String]> 键值 - * @param key 键值名称 - * @param value 键值内容 - * @return [Editor] - */ - internal fun updateStringSet(key: String, value: Set): Editor { - if (isUsingKeyValueCache) preSubmitTasks.add { stringSetData.put(key, value) } - return this - } - - /** - * 更新缓存的 [Boolean] 键值 - * @param key 键值名称 - * @param value 键值内容 - * @return [Editor] - */ - internal fun updateBoolean(key: String, value: Boolean): Editor { - if (isUsingKeyValueCache) preSubmitTasks.add { booleanData.put(key, value) } - return this - } - - /** - * 更新缓存的 [Int] 键值 - * @param key 键值名称 - * @param value 键值内容 - * @return [Editor] - */ - internal fun updateInt(key: String, value: Int): Editor { - if (isUsingKeyValueCache) preSubmitTasks.add { intData.put(key, value) } - return this - } - - /** - * 更新缓存的 [Long] 键值 - * @param key 键值名称 - * @param value 键值内容 - * @return [Editor] - */ - internal fun updateLong(key: String, value: Long): Editor { - if (isUsingKeyValueCache) preSubmitTasks.add { longData.put(key, value) } - return this - } - - /** - * 更新缓存的 [Float] 键值 - * @param key 键值名称 - * @param value 键值内容 - * @return [Editor] - */ - internal fun updateFloat(key: String, value: Float): Editor { - if (isUsingKeyValueCache) preSubmitTasks.add { floatData.put(key, value) } - return this - } - - /** - * 移除缓存的键值 - * @param key 键值名称 - * @return [Editor] - */ - internal fun remove(key: String): Editor { - if (isUsingKeyValueCache) runCatching { - if (stringSetData.get(key) != null) preSubmitTasks.add { stringData.remove(key) } - if (stringSetData.get(key) != null) preSubmitTasks.add { stringSetData.remove(key) } - if (booleanData.get(key) != null) preSubmitTasks.add { booleanData.remove(key) } - if (intData.get(key) != null) preSubmitTasks.add { intData.remove(key) } - if (longData.get(key) != null) preSubmitTasks.add { longData.remove(key) } - if (floatData.get(key) != null) preSubmitTasks.add { floatData.remove(key) } - }; return this - } - - /** - * 清除所有缓存的键值数据 - * @return [Editor] - */ - internal fun clear(): Editor { - preSubmitTasks.add { - stringData.evictAll() - stringSetData.evictAll() - booleanData.evictAll() - intData.evictAll() - longData.evictAll() - floatData.evictAll() - }; return this - } - - /** 提交更改 */ - internal fun apply() { - preSubmitTasks.takeIf { it.isNotEmpty() }?.onEach { it() }?.clear() - } - } - - /** - * 恢复 [isUsingKeyValueCache] 为默认状态 - * @param result 回调方法体的结果 - * @return [T] - */ - private inline fun resetCacheSet(result: () -> T): T { - enableByConfig() - return result() - } -} \ No newline at end of file