Skip to content

Commit e298f19

Browse files
committed
Fix prefs object created every time maybe called app OOM problem in YukiHookModulePrefs
1 parent b61bd33 commit e298f19

File tree

1 file changed

+47
-35
lines changed

1 file changed

+47
-35
lines changed

yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookModulePrefs.kt

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import com.highcapable.yukihookapi.YukiHookAPI
3636
import com.highcapable.yukihookapi.hook.log.yLoggerE
3737
import com.highcapable.yukihookapi.hook.log.yLoggerW
3838
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule
39+
import com.highcapable.yukihookapi.hook.xposed.bridge.delegate.XSharedPreferencesDelegate
3940
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
4041
import com.highcapable.yukihookapi.hook.xposed.prefs.ui.ModulePreferenceFragment
4142
import de.robv.android.xposed.XSharedPreferences
@@ -73,6 +74,12 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
7374
/** 当前 [YukiHookModulePrefs] 单例 */
7475
private var instance: YukiHookModulePrefs? = null
7576

77+
/** 当前缓存的 [XSharedPreferencesDelegate] 实例数组 */
78+
private val xPrefs = HashMap<String, XSharedPreferencesDelegate>()
79+
80+
/** 当前缓存的 [SharedPreferences] 实例数组 */
81+
private val sPrefs = HashMap<String, SharedPreferences>()
82+
7683
/**
7784
* 获取 [YukiHookModulePrefs] 单例
7885
* @param context 实例 - (Xposed) 宿主环境为空
@@ -149,14 +156,15 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
149156
}
150157

151158
/**
152-
* 获得 [XSharedPreferences] 对象
159+
* 获取当前 [XSharedPreferences] 对象
153160
* @return [XSharedPreferences]
154161
*/
155-
private val xPrefs
162+
private val currentXsp
156163
get() = checkApi().let {
157164
runCatching {
158-
XSharedPreferences(YukiXposedModule.modulePackageName, prefsName).apply {
159-
checkApi()
165+
(xPrefs[prefsName]?.instance ?: XSharedPreferencesDelegate.from(YukiXposedModule.modulePackageName, prefsName).also {
166+
xPrefs[prefsName] = it
167+
}.instance).apply {
160168
makeWorldReadable()
161169
reload()
162170
}
@@ -165,18 +173,22 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
165173
}
166174

167175
/**
168-
* 获得 [SharedPreferences] 对象
176+
* 获取当前 [SharedPreferences] 对象
169177
* @return [SharedPreferences]
170178
*/
171-
private val sPrefs
179+
private val currentSp
172180
get() = checkApi().let {
173181
runCatching {
174182
@Suppress("DEPRECATION", "WorldReadableFiles")
175-
context?.getSharedPreferences(prefsName, Context.MODE_WORLD_READABLE).also { isUsingNewXSharedPreferences = true }
176-
?: error("YukiHookModulePrefs missing Context instance")
183+
sPrefs[context.toString() + prefsName] ?: context?.getSharedPreferences(prefsName, Context.MODE_WORLD_READABLE)?.also {
184+
isUsingNewXSharedPreferences = true
185+
sPrefs[context.toString() + prefsName] = it
186+
} ?: error("YukiHookModulePrefs missing Context instance")
177187
}.getOrElse {
178-
context?.getSharedPreferences(prefsName, Context.MODE_PRIVATE).also { isUsingNewXSharedPreferences = false }
179-
?: error("YukiHookModulePrefs missing Context instance")
188+
sPrefs[context.toString() + prefsName] ?: context?.getSharedPreferences(prefsName, Context.MODE_PRIVATE)?.also {
189+
isUsingNewXSharedPreferences = false
190+
sPrefs[context.toString() + prefsName] = it
191+
} ?: error("YukiHookModulePrefs missing Context instance")
180192
}
181193
}
182194

@@ -217,10 +229,10 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
217229
*/
218230
val isPreferencesAvailable
219231
get() = if (isXposedEnvironment)
220-
(runCatching { xPrefs.let { it.file.exists() && it.file.canRead() } }.getOrNull() ?: false)
232+
(runCatching { currentXsp.let { it.file.exists() && it.file.canRead() } }.getOrNull() ?: false)
221233
else runCatching {
222234
/** 执行一次装载 */
223-
sPrefs.edit()
235+
currentSp.edit()
224236
isUsingNewXSharedPreferences
225237
}.getOrNull() ?: false
226238

@@ -262,13 +274,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
262274
(if (isXposedEnvironment)
263275
if (isUsingKeyValueCache)
264276
XSharedPreferencesCaches.stringData[key].let {
265-
(it ?: xPrefs.getString(key, value) ?: value).let { value ->
277+
(it ?: currentXsp.getString(key, value) ?: value).let { value ->
266278
XSharedPreferencesCaches.stringData[key] = value
267279
value
268280
}
269281
}
270-
else resetCacheSet { xPrefs.getString(key, value) ?: value }
271-
else sPrefs.getString(key, value) ?: value).let {
282+
else resetCacheSet { currentXsp.getString(key, value) ?: value }
283+
else currentSp.getString(key, value) ?: value).let {
272284
makeWorldReadable()
273285
it
274286
}
@@ -287,13 +299,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
287299
(if (isXposedEnvironment)
288300
if (isUsingKeyValueCache)
289301
XSharedPreferencesCaches.stringSetData[key].let {
290-
(it ?: xPrefs.getStringSet(key, value) ?: value).let { value ->
302+
(it ?: currentXsp.getStringSet(key, value) ?: value).let { value ->
291303
XSharedPreferencesCaches.stringSetData[key] = value
292304
value
293305
}
294306
}
295-
else resetCacheSet { xPrefs.getStringSet(key, value) ?: value }
296-
else sPrefs.getStringSet(key, value) ?: value).let {
307+
else resetCacheSet { currentXsp.getStringSet(key, value) ?: value }
308+
else currentSp.getStringSet(key, value) ?: value).let {
297309
makeWorldReadable()
298310
it
299311
}
@@ -312,13 +324,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
312324
(if (isXposedEnvironment)
313325
if (isUsingKeyValueCache)
314326
XSharedPreferencesCaches.booleanData[key].let {
315-
it ?: xPrefs.getBoolean(key, value).let { value ->
327+
it ?: currentXsp.getBoolean(key, value).let { value ->
316328
XSharedPreferencesCaches.booleanData[key] = value
317329
value
318330
}
319331
}
320-
else resetCacheSet { xPrefs.getBoolean(key, value) }
321-
else sPrefs.getBoolean(key, value)).let {
332+
else resetCacheSet { currentXsp.getBoolean(key, value) }
333+
else currentSp.getBoolean(key, value)).let {
322334
makeWorldReadable()
323335
it
324336
}
@@ -337,13 +349,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
337349
(if (isXposedEnvironment)
338350
if (isUsingKeyValueCache)
339351
XSharedPreferencesCaches.intData[key].let {
340-
it ?: xPrefs.getInt(key, value).let { value ->
352+
it ?: currentXsp.getInt(key, value).let { value ->
341353
XSharedPreferencesCaches.intData[key] = value
342354
value
343355
}
344356
}
345-
else resetCacheSet { xPrefs.getInt(key, value) }
346-
else sPrefs.getInt(key, value)).let {
357+
else resetCacheSet { currentXsp.getInt(key, value) }
358+
else currentSp.getInt(key, value)).let {
347359
makeWorldReadable()
348360
it
349361
}
@@ -362,13 +374,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
362374
(if (isXposedEnvironment)
363375
if (isUsingKeyValueCache)
364376
XSharedPreferencesCaches.floatData[key].let {
365-
it ?: xPrefs.getFloat(key, value).let { value ->
377+
it ?: currentXsp.getFloat(key, value).let { value ->
366378
XSharedPreferencesCaches.floatData[key] = value
367379
value
368380
}
369381
}
370-
else resetCacheSet { xPrefs.getFloat(key, value) }
371-
else sPrefs.getFloat(key, value)).let {
382+
else resetCacheSet { currentXsp.getFloat(key, value) }
383+
else currentSp.getFloat(key, value)).let {
372384
makeWorldReadable()
373385
it
374386
}
@@ -387,13 +399,13 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
387399
(if (isXposedEnvironment)
388400
if (isUsingKeyValueCache)
389401
XSharedPreferencesCaches.longData[key].let {
390-
it ?: xPrefs.getLong(key, value).let { value ->
402+
it ?: currentXsp.getLong(key, value).let { value ->
391403
XSharedPreferencesCaches.longData[key] = value
392404
value
393405
}
394406
}
395-
else resetCacheSet { xPrefs.getLong(key, value) }
396-
else sPrefs.getLong(key, value)).let {
407+
else resetCacheSet { currentXsp.getLong(key, value) }
408+
else currentSp.getLong(key, value)).let {
397409
makeWorldReadable()
398410
it
399411
}
@@ -433,8 +445,8 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
433445
*/
434446
fun contains(key: String) =
435447
if (isXposedEnvironment)
436-
xPrefs.contains(key)
437-
else sPrefs.contains(key)
448+
currentXsp.contains(key)
449+
else currentSp.contains(key)
438450

439451
/**
440452
* 获取全部存储的键值数据
@@ -446,8 +458,8 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
446458
*/
447459
fun all() = hashMapOf<String, Any?>().apply {
448460
if (isXposedEnvironment)
449-
xPrefs.all.forEach { (k, v) -> this[k] = v }
450-
else sPrefs.all.forEach { (k, v) -> this[k] = v }
461+
currentXsp.all.forEach { (k, v) -> this[k] = v }
462+
else currentSp.all.forEach { (k, v) -> this[k] = v }
451463
}
452464

453465
/**
@@ -621,7 +633,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
621633
inner class Editor internal constructor() {
622634

623635
/** 创建新的存储代理类 */
624-
private var editor = runCatching { sPrefs.edit() }.getOrNull()
636+
private var editor = runCatching { currentSp.edit() }.getOrNull()
625637

626638
/**
627639
* 移除全部包含 [key] 的存储数据

0 commit comments

Comments
 (0)