Fix prefs object created every time maybe called app OOM problem in YukiHookModulePrefs

This commit is contained in:
2023-04-17 00:17:55 +08:00
parent b61bd33a67
commit e298f19e33

View File

@@ -36,6 +36,7 @@ import com.highcapable.yukihookapi.YukiHookAPI
import com.highcapable.yukihookapi.hook.log.yLoggerE import com.highcapable.yukihookapi.hook.log.yLoggerE
import com.highcapable.yukihookapi.hook.log.yLoggerW import com.highcapable.yukihookapi.hook.log.yLoggerW
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule
import com.highcapable.yukihookapi.hook.xposed.bridge.delegate.XSharedPreferencesDelegate
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
import com.highcapable.yukihookapi.hook.xposed.prefs.ui.ModulePreferenceFragment import com.highcapable.yukihookapi.hook.xposed.prefs.ui.ModulePreferenceFragment
import de.robv.android.xposed.XSharedPreferences import de.robv.android.xposed.XSharedPreferences
@@ -73,6 +74,12 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
/** 当前 [YukiHookModulePrefs] 单例 */ /** 当前 [YukiHookModulePrefs] 单例 */
private var instance: YukiHookModulePrefs? = null private var instance: YukiHookModulePrefs? = null
/** 当前缓存的 [XSharedPreferencesDelegate] 实例数组 */
private val xPrefs = HashMap<String, XSharedPreferencesDelegate>()
/** 当前缓存的 [SharedPreferences] 实例数组 */
private val sPrefs = HashMap<String, SharedPreferences>()
/** /**
* 获取 [YukiHookModulePrefs] 单例 * 获取 [YukiHookModulePrefs] 单例
* @param context 实例 - (Xposed) 宿主环境为空 * @param context 实例 - (Xposed) 宿主环境为空
@@ -149,14 +156,15 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
} }
/** /**
* 获 [XSharedPreferences] 对象 * 获取当前 [XSharedPreferences] 对象
* @return [XSharedPreferences] * @return [XSharedPreferences]
*/ */
private val xPrefs private val currentXsp
get() = checkApi().let { get() = checkApi().let {
runCatching { runCatching {
XSharedPreferences(YukiXposedModule.modulePackageName, prefsName).apply { (xPrefs[prefsName]?.instance ?: XSharedPreferencesDelegate.from(YukiXposedModule.modulePackageName, prefsName).also {
checkApi() xPrefs[prefsName] = it
}.instance).apply {
makeWorldReadable() makeWorldReadable()
reload() reload()
} }
@@ -165,18 +173,22 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
} }
/** /**
* 获 [SharedPreferences] 对象 * 获取当前 [SharedPreferences] 对象
* @return [SharedPreferences] * @return [SharedPreferences]
*/ */
private val sPrefs private val currentSp
get() = checkApi().let { get() = checkApi().let {
runCatching { runCatching {
@Suppress("DEPRECATION", "WorldReadableFiles") @Suppress("DEPRECATION", "WorldReadableFiles")
context?.getSharedPreferences(prefsName, Context.MODE_WORLD_READABLE).also { isUsingNewXSharedPreferences = true } sPrefs[context.toString() + prefsName] ?: context?.getSharedPreferences(prefsName, Context.MODE_WORLD_READABLE)?.also {
?: error("YukiHookModulePrefs missing Context instance") isUsingNewXSharedPreferences = true
sPrefs[context.toString() + prefsName] = it
} ?: error("YukiHookModulePrefs missing Context instance")
}.getOrElse { }.getOrElse {
context?.getSharedPreferences(prefsName, Context.MODE_PRIVATE).also { isUsingNewXSharedPreferences = false } sPrefs[context.toString() + prefsName] ?: context?.getSharedPreferences(prefsName, Context.MODE_PRIVATE)?.also {
?: error("YukiHookModulePrefs missing Context instance") isUsingNewXSharedPreferences = false
sPrefs[context.toString() + prefsName] = it
} ?: error("YukiHookModulePrefs missing Context instance")
} }
} }
@@ -217,10 +229,10 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
*/ */
val isPreferencesAvailable val isPreferencesAvailable
get() = if (isXposedEnvironment) get() = if (isXposedEnvironment)
(runCatching { xPrefs.let { it.file.exists() && it.file.canRead() } }.getOrNull() ?: false) (runCatching { currentXsp.let { it.file.exists() && it.file.canRead() } }.getOrNull() ?: false)
else runCatching { else runCatching {
/** 执行一次装载 */ /** 执行一次装载 */
sPrefs.edit() currentSp.edit()
isUsingNewXSharedPreferences isUsingNewXSharedPreferences
}.getOrNull() ?: false }.getOrNull() ?: false
@@ -262,13 +274,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
(if (isXposedEnvironment) (if (isXposedEnvironment)
if (isUsingKeyValueCache) if (isUsingKeyValueCache)
XSharedPreferencesCaches.stringData[key].let { XSharedPreferencesCaches.stringData[key].let {
(it ?: xPrefs.getString(key, value) ?: value).let { value -> (it ?: currentXsp.getString(key, value) ?: value).let { value ->
XSharedPreferencesCaches.stringData[key] = value XSharedPreferencesCaches.stringData[key] = value
value value
} }
} }
else resetCacheSet { xPrefs.getString(key, value) ?: value } else resetCacheSet { currentXsp.getString(key, value) ?: value }
else sPrefs.getString(key, value) ?: value).let { else currentSp.getString(key, value) ?: value).let {
makeWorldReadable() makeWorldReadable()
it it
} }
@@ -287,13 +299,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
(if (isXposedEnvironment) (if (isXposedEnvironment)
if (isUsingKeyValueCache) if (isUsingKeyValueCache)
XSharedPreferencesCaches.stringSetData[key].let { XSharedPreferencesCaches.stringSetData[key].let {
(it ?: xPrefs.getStringSet(key, value) ?: value).let { value -> (it ?: currentXsp.getStringSet(key, value) ?: value).let { value ->
XSharedPreferencesCaches.stringSetData[key] = value XSharedPreferencesCaches.stringSetData[key] = value
value value
} }
} }
else resetCacheSet { xPrefs.getStringSet(key, value) ?: value } else resetCacheSet { currentXsp.getStringSet(key, value) ?: value }
else sPrefs.getStringSet(key, value) ?: value).let { else currentSp.getStringSet(key, value) ?: value).let {
makeWorldReadable() makeWorldReadable()
it it
} }
@@ -312,13 +324,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
(if (isXposedEnvironment) (if (isXposedEnvironment)
if (isUsingKeyValueCache) if (isUsingKeyValueCache)
XSharedPreferencesCaches.booleanData[key].let { XSharedPreferencesCaches.booleanData[key].let {
it ?: xPrefs.getBoolean(key, value).let { value -> it ?: currentXsp.getBoolean(key, value).let { value ->
XSharedPreferencesCaches.booleanData[key] = value XSharedPreferencesCaches.booleanData[key] = value
value value
} }
} }
else resetCacheSet { xPrefs.getBoolean(key, value) } else resetCacheSet { currentXsp.getBoolean(key, value) }
else sPrefs.getBoolean(key, value)).let { else currentSp.getBoolean(key, value)).let {
makeWorldReadable() makeWorldReadable()
it it
} }
@@ -337,13 +349,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
(if (isXposedEnvironment) (if (isXposedEnvironment)
if (isUsingKeyValueCache) if (isUsingKeyValueCache)
XSharedPreferencesCaches.intData[key].let { XSharedPreferencesCaches.intData[key].let {
it ?: xPrefs.getInt(key, value).let { value -> it ?: currentXsp.getInt(key, value).let { value ->
XSharedPreferencesCaches.intData[key] = value XSharedPreferencesCaches.intData[key] = value
value value
} }
} }
else resetCacheSet { xPrefs.getInt(key, value) } else resetCacheSet { currentXsp.getInt(key, value) }
else sPrefs.getInt(key, value)).let { else currentSp.getInt(key, value)).let {
makeWorldReadable() makeWorldReadable()
it it
} }
@@ -362,13 +374,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
(if (isXposedEnvironment) (if (isXposedEnvironment)
if (isUsingKeyValueCache) if (isUsingKeyValueCache)
XSharedPreferencesCaches.floatData[key].let { XSharedPreferencesCaches.floatData[key].let {
it ?: xPrefs.getFloat(key, value).let { value -> it ?: currentXsp.getFloat(key, value).let { value ->
XSharedPreferencesCaches.floatData[key] = value XSharedPreferencesCaches.floatData[key] = value
value value
} }
} }
else resetCacheSet { xPrefs.getFloat(key, value) } else resetCacheSet { currentXsp.getFloat(key, value) }
else sPrefs.getFloat(key, value)).let { else currentSp.getFloat(key, value)).let {
makeWorldReadable() makeWorldReadable()
it it
} }
@@ -387,13 +399,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
(if (isXposedEnvironment) (if (isXposedEnvironment)
if (isUsingKeyValueCache) if (isUsingKeyValueCache)
XSharedPreferencesCaches.longData[key].let { XSharedPreferencesCaches.longData[key].let {
it ?: xPrefs.getLong(key, value).let { value -> it ?: currentXsp.getLong(key, value).let { value ->
XSharedPreferencesCaches.longData[key] = value XSharedPreferencesCaches.longData[key] = value
value value
} }
} }
else resetCacheSet { xPrefs.getLong(key, value) } else resetCacheSet { currentXsp.getLong(key, value) }
else sPrefs.getLong(key, value)).let { else currentSp.getLong(key, value)).let {
makeWorldReadable() makeWorldReadable()
it it
} }
@@ -433,8 +445,8 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
*/ */
fun contains(key: String) = fun contains(key: String) =
if (isXposedEnvironment) if (isXposedEnvironment)
xPrefs.contains(key) currentXsp.contains(key)
else sPrefs.contains(key) else currentSp.contains(key)
/** /**
* 获取全部存储的键值数据 * 获取全部存储的键值数据
@@ -446,8 +458,8 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
*/ */
fun all() = hashMapOf<String, Any?>().apply { fun all() = hashMapOf<String, Any?>().apply {
if (isXposedEnvironment) if (isXposedEnvironment)
xPrefs.all.forEach { (k, v) -> this[k] = v } currentXsp.all.forEach { (k, v) -> this[k] = v }
else sPrefs.all.forEach { (k, v) -> this[k] = v } else currentSp.all.forEach { (k, v) -> this[k] = v }
} }
/** /**
@@ -621,7 +633,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
inner class Editor internal constructor() { inner class Editor internal constructor() {
/** 创建新的存储代理类 */ /** 创建新的存储代理类 */
private var editor = runCatching { sPrefs.edit() }.getOrNull() private var editor = runCatching { currentSp.edit() }.getOrNull()
/** /**
* 移除全部包含 [key] 的存储数据 * 移除全部包含 [key] 的存储数据