mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 09:45:19 +08:00
Modify change YukiHookModulePrefs name to YukiHookPrefsBridge and make it support native storage usage in YukiHookPrefsBridge
This commit is contained in:
@@ -29,7 +29,7 @@ const navigationLinks = {
|
|||||||
baseApiPath + 'hook/param/HookParam',
|
baseApiPath + 'hook/param/HookParam',
|
||||||
baseApiPath + 'annotation/xposed/InjectYukiHookWithXposed',
|
baseApiPath + 'annotation/xposed/InjectYukiHookWithXposed',
|
||||||
baseApiPath + 'hook/xposed/proxy/IYukiHookXposedInit',
|
baseApiPath + 'hook/xposed/proxy/IYukiHookXposedInit',
|
||||||
baseApiPath + 'hook/xposed/prefs/YukiHookModulePrefs',
|
baseApiPath + 'hook/xposed/prefs/YukiHookPrefsBridge',
|
||||||
baseApiPath + 'hook/xposed/prefs/ui/ModulePreferenceFragment',
|
baseApiPath + 'hook/xposed/prefs/ui/ModulePreferenceFragment',
|
||||||
baseApiPath + 'hook/xposed/prefs/data/PrefsData',
|
baseApiPath + 'hook/xposed/prefs/data/PrefsData',
|
||||||
baseApiPath + 'hook/xposed/channel/YukiHookDataChannel',
|
baseApiPath + 'hook/xposed/channel/YukiHookDataChannel',
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
> Here are the unresolved issues with `YukiHookAPI`.
|
> Here are the unresolved issues with `YukiHookAPI`.
|
||||||
|
|
||||||
### YukiHookModulePrefs
|
### YukiHookPrefsBridge
|
||||||
|
|
||||||
Currently only supports LSPosed perfectly, other Xposed Framework need to downgrade the module target api.
|
Currently only supports LSPosed perfectly, other Xposed Framework need to downgrade the module target api.
|
||||||
|
|
||||||
|
@@ -404,23 +404,33 @@ var isDebug: Boolean
|
|||||||
|
|
||||||
请转移到 `YukiHookLogger.Configs.isEnable`
|
请转移到 `YukiHookLogger.Configs.isEnable`
|
||||||
|
|
||||||
### isEnableModulePrefsCache <span class="symbol">- field</span>
|
<h3 class="deprecated">isEnableModulePrefsCache - field</h3>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
|
||||||
var isEnableModulePrefsCache: Boolean
|
|
||||||
```
|
|
||||||
|
|
||||||
**Change Records**
|
**Change Records**
|
||||||
|
|
||||||
`v1.0.5` `added`
|
`v1.0.5` `added`
|
||||||
|
|
||||||
|
`v1.1.9` `deprecated`
|
||||||
|
|
||||||
|
请转移到 `isEnablePrefsBridgeCache`
|
||||||
|
|
||||||
|
### isEnablePrefsBridgeCache <span class="symbol">- field</span>
|
||||||
|
|
||||||
|
```kotlin:no-line-numbers
|
||||||
|
var isEnablePrefsBridgeCache: Boolean
|
||||||
|
```
|
||||||
|
|
||||||
|
**Change Records**
|
||||||
|
|
||||||
|
`v1.1.9` `added`
|
||||||
|
|
||||||
**Function Illustrate**
|
**Function Illustrate**
|
||||||
|
|
||||||
> 是否启用 `YukiHookModulePrefs` 的键值缓存功能。
|
> 是否启用 `YukiHookPrefsBridge` 的键值缓存功能。
|
||||||
|
|
||||||
为防止内存复用过高问题,此功能默认启用。
|
为防止内存复用过高问题,此功能默认启用。
|
||||||
|
|
||||||
你可以手动在 `YukiHookModulePrefs` 中自由开启和关闭缓存功能以及清除缓存。
|
你可以手动在 `YukiHookPrefsBridge` 中自由开启和关闭缓存功能以及清除缓存。
|
||||||
|
|
||||||
### isEnableModuleAppResourcesCache <span class="symbol">- field</span>
|
### isEnableModuleAppResourcesCache <span class="symbol">- field</span>
|
||||||
|
|
||||||
@@ -488,7 +498,7 @@ var isEnableHookSharedPreferences: Boolean
|
|||||||
|
|
||||||
这是一个可选的实验性功能,此功能默认不启用。
|
这是一个可选的实验性功能,此功能默认不启用。
|
||||||
|
|
||||||
仅用于修复某些系统可能会出现在启用了 **New XSharedPreferences** 后依然出现文件权限错误问题,若你能正常使用 **YukiHookModulePrefs** 就不建议启用此功能。
|
仅用于修复某些系统可能会出现在启用了 **New XSharedPreferences** 后依然出现文件权限错误问题,若你能正常使用 **YukiHookPrefsBridge** 就不建议启用此功能。
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -572,7 +582,7 @@ object HookEntry : IYukiHookXposedInit {
|
|||||||
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
|
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
|
||||||
}
|
}
|
||||||
isDebug = BuildConfig.DEBUG
|
isDebug = BuildConfig.DEBUG
|
||||||
isEnableModulePrefsCache = true
|
isEnablePrefsBridgeCache = true
|
||||||
isEnableModuleAppResourcesCache = true
|
isEnableModuleAppResourcesCache = true
|
||||||
isEnableHookModuleStatus = true
|
isEnableHookModuleStatus = true
|
||||||
isEnableHookSharedPreferences = false
|
isEnableHookSharedPreferences = false
|
||||||
@@ -602,7 +612,7 @@ object HookEntry : IYukiHookXposedInit {
|
|||||||
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
|
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
|
||||||
}
|
}
|
||||||
isDebug = BuildConfig.DEBUG
|
isDebug = BuildConfig.DEBUG
|
||||||
isEnableModulePrefsCache = true
|
isEnablePrefsBridgeCache = true
|
||||||
isEnableModuleAppResourcesCache = true
|
isEnableModuleAppResourcesCache = true
|
||||||
isEnableHookModuleStatus = true
|
isEnableHookModuleStatus = true
|
||||||
isEnableHookSharedPreferences = false
|
isEnableHookSharedPreferences = false
|
||||||
@@ -634,7 +644,7 @@ object HookEntry : IYukiHookXposedInit {
|
|||||||
YukiHookLogger.Configs.USER_ID
|
YukiHookLogger.Configs.USER_ID
|
||||||
)
|
)
|
||||||
YukiHookAPI.Configs.isDebug = BuildConfig.DEBUG
|
YukiHookAPI.Configs.isDebug = BuildConfig.DEBUG
|
||||||
YukiHookAPI.Configs.isEnableModulePrefsCache = true
|
YukiHookAPI.Configs.isEnablePrefsBridgeCache = true
|
||||||
YukiHookAPI.Configs.isEnableModuleAppResourcesCache = true
|
YukiHookAPI.Configs.isEnableModuleAppResourcesCache = true
|
||||||
YukiHookAPI.Configs.isEnableHookModuleStatus = true
|
YukiHookAPI.Configs.isEnableHookModuleStatus = true
|
||||||
YukiHookAPI.Configs.isEnableHookSharedPreferences = false
|
YukiHookAPI.Configs.isEnableHookSharedPreferences = false
|
||||||
|
@@ -64,33 +64,45 @@ fun IYukiHookXposedInit.encase(vararg hooker: YukiBaseHooker)
|
|||||||
|
|
||||||
> 在 `IYukiHookXposedInit` 中调用 `YukiHookAPI`。
|
> 在 `IYukiHookXposedInit` 中调用 `YukiHookAPI`。
|
||||||
|
|
||||||
## Context.modulePrefs <span class="symbol">- ext-field</span>
|
<h2 class="deprecated">Context.modulePrefs - ext-field</h2>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
|
||||||
val Context.modulePrefs: YukiHookModulePrefs
|
|
||||||
```
|
|
||||||
|
|
||||||
**Change Records**
|
**Change Records**
|
||||||
|
|
||||||
`v1.0` `first`
|
`v1.0` `first`
|
||||||
|
|
||||||
**Function Illustrate**
|
`v1.1.9` `deprecated`
|
||||||
|
|
||||||
> 获取模块的存取对象。
|
请转移到 `prefs` 方法
|
||||||
|
|
||||||
## Context.modulePrefs <span class="symbol">- ext-method</span>
|
<h2 class="deprecated">Context.modulePrefs - ext-method</h2>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
|
||||||
fun Context.modulePrefs(name: String): YukiHookModulePrefs
|
|
||||||
```
|
|
||||||
|
|
||||||
**Change Records**
|
**Change Records**
|
||||||
|
|
||||||
`v1.0` `first`
|
`v1.0` `first`
|
||||||
|
|
||||||
|
`v1.1.9` `deprecated`
|
||||||
|
|
||||||
|
请转移到 `prefs` 方法
|
||||||
|
|
||||||
|
## Context.prefs <span class="symbol">- ext-method</span>
|
||||||
|
|
||||||
|
```kotlin:no-line-numbers
|
||||||
|
fun Context.prefs(name: String): YukiHookPrefsBridge
|
||||||
|
```
|
||||||
|
|
||||||
|
**Change Records**
|
||||||
|
|
||||||
|
`v1.1.9` `added`
|
||||||
|
|
||||||
**Function Illustrate**
|
**Function Illustrate**
|
||||||
|
|
||||||
> 获取模块的存取对象,可设置 `name` 为自定义 Sp 存储名称。
|
> 获取 `YukiHookPrefsBridge` 对象。
|
||||||
|
|
||||||
|
可以同时在模块与 (Xposed) 宿主环境中使用。
|
||||||
|
|
||||||
|
如果你想在 (Xposed) 宿主环境将数据存入当前宿主的私有空间,请使用 `YukiHookPrefsBridge.native` 方法。
|
||||||
|
|
||||||
|
在未声明任何条件的情况下 (Xposed) 宿主环境默认读取模块中的数据。
|
||||||
|
|
||||||
## Context.dataChannel <span class="symbol">- ext-method</span>
|
## Context.dataChannel <span class="symbol">- ext-method</span>
|
||||||
|
|
||||||
|
@@ -243,7 +243,7 @@ val moduleAppResources: YukiModuleResources
|
|||||||
## prefs <span class="symbol">- field</span>
|
## prefs <span class="symbol">- field</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
val prefs: YukiHookModulePrefs
|
val prefs: YukiHookPrefsBridge
|
||||||
```
|
```
|
||||||
|
|
||||||
**Change Records**
|
**Change Records**
|
||||||
@@ -263,7 +263,7 @@ val prefs: YukiHookModulePrefs
|
|||||||
## prefs <span class="symbol">- method</span>
|
## prefs <span class="symbol">- method</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
fun prefs(name: String): YukiHookModulePrefs
|
fun prefs(name: String): YukiHookPrefsBridge
|
||||||
```
|
```
|
||||||
|
|
||||||
**Change Records**
|
**Change Records**
|
||||||
|
@@ -10,25 +10,29 @@ You can use the **Chrome Translation Plugin** to translate entire pages for refe
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
# YukiHookModulePrefs <span class="symbol">- class</span>
|
# YukiHookPrefsBridge <span class="symbol">- class</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
class YukiHookModulePrefs private constructor(private var context: Context?)
|
class YukiHookPrefsBridge private constructor(private var context: Context?)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Change Records**
|
**Change Records**
|
||||||
|
|
||||||
`v1.0` `first`
|
`v1.0` `first`
|
||||||
|
|
||||||
|
`v1.1.9` `modified`
|
||||||
|
|
||||||
|
~~`YukiHookModulePrefs`~~ 更名为 `YukiHookPrefsBridge`
|
||||||
|
|
||||||
**Function Illustrate**
|
**Function Illustrate**
|
||||||
|
|
||||||
> 实现 Xposed 模块的数据存取,对接 `SharedPreferences` 和 `XSharedPreferences`。
|
> `YukiHookAPI` 对 `SharedPreferences`、`XSharedPreferences` 的扩展存储桥实现。
|
||||||
|
|
||||||
在不同环境智能选择存取使用的对象。
|
在不同环境智能选择存取使用的对象。
|
||||||
|
|
||||||
::: danger
|
::: danger
|
||||||
|
|
||||||
此功能为实验性功能,仅在 LSPosed 环境测试通过,EdXposed 理论也可以使用但不再推荐。
|
模块与宿主之前共享数据存储为实验性功能,仅在 LSPosed 环境测试通过,EdXposed 理论也可以使用但不再推荐。
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -42,13 +46,7 @@ class YukiHookModulePrefs private constructor(private var context: Context?)
|
|||||||
|
|
||||||
太极请参阅 [文件权限/配置/XSharedPreference](https://taichi.cool/zh/doc/for-xposed-dev.html#文件权限-配置-xsharedpreference)。
|
太极请参阅 [文件权限/配置/XSharedPreference](https://taichi.cool/zh/doc/for-xposed-dev.html#文件权限-配置-xsharedpreference)。
|
||||||
|
|
||||||
::: danger
|
对于在模块环境中使用 `PreferenceFragmentCompat`,`YukiHookAPI` 提供了 `ModulePreferenceFragment` 来实现同样的功能。
|
||||||
|
|
||||||
当你在 Xposed 模块中存取数据的时候 **context** 必须不能是空的。
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
若你正在使用 `PreferenceFragmentCompat`,请迁移到 `ModulePreferenceFragment` 以适配上述功能特性。
|
|
||||||
|
|
||||||
**Optional Configuration**
|
**Optional Configuration**
|
||||||
|
|
||||||
@@ -96,7 +94,7 @@ val isPreferencesAvailable: Boolean
|
|||||||
|
|
||||||
**Function Illustrate**
|
**Function Illustrate**
|
||||||
|
|
||||||
> 获取当前 `YukiHookModulePrefs` 的可用状态。
|
> 获取当前 `YukiHookPrefsBridge` 的可用状态。
|
||||||
|
|
||||||
在 (Xposed) 宿主环境中返回 `XSharedPreferences` 可用状态 (可读)。
|
在 (Xposed) 宿主环境中返回 `XSharedPreferences` 可用状态 (可读)。
|
||||||
|
|
||||||
@@ -105,7 +103,7 @@ val isPreferencesAvailable: Boolean
|
|||||||
## name <span class="symbol">- method</span>
|
## name <span class="symbol">- method</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
fun name(name: String): YukiHookModulePrefs
|
fun name(name: String): YukiHookPrefsBridge
|
||||||
```
|
```
|
||||||
|
|
||||||
**Change Records**
|
**Change Records**
|
||||||
@@ -123,7 +121,7 @@ fun name(name: String): YukiHookModulePrefs
|
|||||||
> The following example
|
> The following example
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
modulePrefs("custom_name").getString("custom_key")
|
prefs("custom_name").getString("custom_key")
|
||||||
```
|
```
|
||||||
|
|
||||||
在 (Xposed) 宿主环境 `PackageParam` 中的使用方法。
|
在 (Xposed) 宿主环境 `PackageParam` 中的使用方法。
|
||||||
@@ -137,7 +135,7 @@ prefs("custom_name").getString("custom_key")
|
|||||||
## direct <span class="symbol">- method</span>
|
## direct <span class="symbol">- method</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
fun direct(): YukiHookModulePrefs
|
fun direct(): YukiHookPrefsBridge
|
||||||
```
|
```
|
||||||
|
|
||||||
**Change Records**
|
**Change Records**
|
||||||
@@ -148,10 +146,24 @@ fun direct(): YukiHookModulePrefs
|
|||||||
|
|
||||||
> 忽略缓存直接读取键值。
|
> 忽略缓存直接读取键值。
|
||||||
|
|
||||||
无论是否开启 `YukiHookAPI.Configs.isEnableModulePrefsCache`。
|
无论是否开启 `YukiHookAPI.Configs.isEnablePrefsBridgeCache`。
|
||||||
|
|
||||||
仅在 `XSharedPreferences` 下生效。
|
仅在 `XSharedPreferences` 下生效。
|
||||||
|
|
||||||
|
## native <span class="symbol">- method</span>
|
||||||
|
|
||||||
|
```kotlin:no-line-numbers
|
||||||
|
fun native(): YukiHookPrefsBridge
|
||||||
|
```
|
||||||
|
|
||||||
|
**Change Records**
|
||||||
|
|
||||||
|
`v1.1.9` `added`
|
||||||
|
|
||||||
|
**Function Illustrate**
|
||||||
|
|
||||||
|
> 忽略当前环境直接使用 `Context.getSharedPreferences` 存取数据。
|
||||||
|
|
||||||
## getString <span class="symbol">- method</span>
|
## getString <span class="symbol">- method</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
@@ -434,7 +446,7 @@ fun clearCache()
|
|||||||
|
|
||||||
> 清除 `XSharedPreferences` 中缓存的键值数据。
|
> 清除 `XSharedPreferences` 中缓存的键值数据。
|
||||||
|
|
||||||
无论是否开启 `YukiHookAPI.Configs.isEnableModulePrefsCache`。
|
无论是否开启 `YukiHookAPI.Configs.isEnablePrefsBridgeCache`。
|
||||||
|
|
||||||
调用此方法将清除当前存储的全部键值缓存。
|
调用此方法将清除当前存储的全部键值缓存。
|
||||||
|
|
||||||
@@ -454,7 +466,7 @@ inner class Editor internal constructor()
|
|||||||
|
|
||||||
**Function Illustrate**
|
**Function Illustrate**
|
||||||
|
|
||||||
> `YukiHookModulePrefs` 的存储代理类。
|
> `YukiHookPrefsBridge` 的存储代理类。
|
||||||
|
|
||||||
请使用 `edit` 方法来获取 `Editor`。
|
请使用 `edit` 方法来获取 `Editor`。
|
||||||
|
|
@@ -28,7 +28,7 @@ data class PrefsData<T>(var key: String, var value: T) : Serializable
|
|||||||
|
|
||||||
> 键值对存储构造类。
|
> 键值对存储构造类。
|
||||||
|
|
||||||
这个类是对 `YukiHookModulePrefs` 的一个扩展用法。
|
这个类是对 `YukiHookPrefsBridge` 的一个扩展用法。
|
||||||
|
|
||||||
**Function Example**
|
**Function Example**
|
||||||
|
|
||||||
@@ -51,9 +51,9 @@ object DataConst {
|
|||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
// 读取
|
// 读取
|
||||||
val data = modulePrefs.get(DataConst.TEST_KV_DATA_1)
|
val data = prefs().get(DataConst.TEST_KV_DATA_1)
|
||||||
// 写入
|
// 写入
|
||||||
modulePrefs.put(DataConst.TEST_KV_DATA_1, "written value")
|
prefs().edit { put(DataConst.TEST_KV_DATA_1, "written value") }
|
||||||
```
|
```
|
||||||
|
|
||||||
> 宿主示例如下
|
> 宿主示例如下
|
||||||
|
@@ -10,7 +10,7 @@ The native `Xposed` provides us with a `XSharedPreferences` for reading the `Sp`
|
|||||||
|
|
||||||
## Use in Activity
|
## Use in Activity
|
||||||
|
|
||||||
> Loading `YukiHookModulePrefs` in `Activity` is described here.
|
> Loading `YukiHookPrefsBridge` in `Activity` is described here.
|
||||||
|
|
||||||
Usually we can initialize it in Host App like this.
|
Usually we can initialize it in Host App like this.
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ When you store data in a Module App, you can use the following methods if you ar
|
|||||||
> The following example
|
> The following example
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
modulePrefs.putString("test_name", "saved_value")
|
prefs().edit { putString("test_name", "saved_value") }
|
||||||
```
|
```
|
||||||
|
|
||||||
When you read data in a Host App, you can use the following methods.
|
When you read data in a Host App, you can use the following methods.
|
||||||
@@ -40,7 +40,7 @@ When you read data in a Host App, you can use the following methods.
|
|||||||
val testName = prefs.getString("test_name", "default_value")
|
val testName = prefs.getString("test_name", "default_value")
|
||||||
```
|
```
|
||||||
|
|
||||||
You don't need to consider the module package name and a series of complicated permission configurations, everything is handled by `YukiHookModulePrefs`.
|
You don't need to consider the module package name and a series of complicated permission configurations, everything is handled by `YukiHookPrefsBridge`.
|
||||||
|
|
||||||
To achieve localization of storage, you can specify the name of each `prefs` file.
|
To achieve localization of storage, you can specify the name of each `prefs` file.
|
||||||
|
|
||||||
@@ -50,9 +50,9 @@ This is used in the `Activity` of the Module App.
|
|||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
// Recommended usage
|
// Recommended usage
|
||||||
modulePrefs("specify_file_name").putString("test_name", "saved_value")
|
prefs("specify_file_name").edit { putString("test_name", "saved_value") }
|
||||||
// Can also be used like this
|
// Can also be used like this
|
||||||
modulePrefs.name("specify_file_name").putString("test_name", "saved_value")
|
prefs().name("specify_file_name").edit { putString("test_name", "saved_value") }
|
||||||
```
|
```
|
||||||
|
|
||||||
Read like this in Host App.
|
Read like this in Host App.
|
||||||
@@ -68,21 +68,40 @@ val testName = prefs.name("specify_file_name").getString("test_name", "default_v
|
|||||||
|
|
||||||
If your project has a lot of fixed data that needs to be stored and read, it is recommended to use `PrefsData` to create templates.
|
If your project has a lot of fixed data that needs to be stored and read, it is recommended to use `PrefsData` to create templates.
|
||||||
|
|
||||||
|
Through the above example, you can call the `edit` method to store data in batches in the following two ways.
|
||||||
|
|
||||||
|
> The following example
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// <Scenario 1>
|
||||||
|
prefs().edit {
|
||||||
|
putString("test_name_1", "saved_value_1")
|
||||||
|
putString("test_name_2", "saved_value_2")
|
||||||
|
putString("test_name_3", "saved_value_3")
|
||||||
|
}
|
||||||
|
// <Scenario 2>
|
||||||
|
prefs(). edit()
|
||||||
|
.putString("test_name_1", "saved_value_1")
|
||||||
|
.putString("test_name_2", "saved_value_2")
|
||||||
|
.putString("test_name_3", "saved_value_3")
|
||||||
|
.apply()
|
||||||
|
```
|
||||||
|
|
||||||
::: tip
|
::: tip
|
||||||
|
|
||||||
For more functions, please refer to [YukiHookModulePrefs](../public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookModulePrefs), [PrefsData](../public/com/highcapable/yukihookapi/hook/xposed/prefs/data/PrefsData).
|
For more functions, please refer to [YukiHookPrefsBridge](../public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge), [PrefsData](../public/com/highcapable/yukihookapi/hook/xposed/prefs/data/PrefsData).
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Use in PreferenceFragment
|
## Use in PreferenceFragment
|
||||||
|
|
||||||
> Loading `YukiHookModulePrefs` in `PreferenceFragment` is described here.
|
> Loading `YukiHookPrefsBridge` in `PreferenceFragment` is described here.
|
||||||
|
|
||||||
If your Module App uses `PreferenceFragmentCompat`, you can now start migrating its extends `ModulePreferenceFragment`.
|
If your Module App uses `PreferenceFragmentCompat`, you can now start migrating its extends `ModulePreferenceFragment`.
|
||||||
|
|
||||||
::: danger
|
::: danger
|
||||||
|
|
||||||
You must extends **ModulePreferenceFragment** to implement the module storage function of **YukiHookModulePrefs**.
|
You must extends **ModulePreferenceFragment** to implement the module storage function of **YukiHookPrefsBridge**.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -91,3 +110,49 @@ You must extends **ModulePreferenceFragment** to implement the module storage fu
|
|||||||
For more functions, please refer to [ModulePreferenceFragment](../public/com/highcapable/yukihookapi/hook/xposed/prefs/ui/ModulePreferenceFragment).
|
For more functions, please refer to [ModulePreferenceFragment](../public/com/highcapable/yukihookapi/hook/xposed/prefs/ui/ModulePreferenceFragment).
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
## Use Native Storage
|
||||||
|
|
||||||
|
In the Module environment, `YukiHookPrefsBridge` will store data in the Module App's own private directory (or the shared directory provided by Hook Framework) by default.
|
||||||
|
|
||||||
|
Using `YukiHookPrefsBridge` in the Host environment will read the data in the Module App's own private directory (or the shared directory provided by Hook Framework) by default.
|
||||||
|
|
||||||
|
If you want to store data directly into a Module App or Host App's own private directory, you can use the `native` method.
|
||||||
|
|
||||||
|
For example, the directory of the Module App is `.../com.demo.test.module/shared_prefs`, and the directory of the Host App is `.../com.demo.test.host/shared_prefs`.
|
||||||
|
|
||||||
|
The following is the usage in `Activity`.
|
||||||
|
|
||||||
|
> The following example
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// Store private data
|
||||||
|
prefs().native().edit { putBoolean("isolation_data", true) }
|
||||||
|
// Read private data
|
||||||
|
val privateData = prefs().native().getBoolean("isolation_data")
|
||||||
|
// Store shared data
|
||||||
|
prefs().edit { putBoolean("public_data", true) }
|
||||||
|
// Read shared data
|
||||||
|
val publicData = prefs().getBoolean("public_data")
|
||||||
|
```
|
||||||
|
|
||||||
|
The following is the usage in `PackageParam`.
|
||||||
|
|
||||||
|
> The following example
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// Store private data
|
||||||
|
prefs.native().edit { putBoolean("isolation_data", true) }
|
||||||
|
// Read private data
|
||||||
|
val privateData = prefs.native().getBoolean("isolation_data")
|
||||||
|
// Read shared data
|
||||||
|
val publicData = prefs.getBoolean("public_data")
|
||||||
|
```
|
||||||
|
|
||||||
|
After using the `native` method, no matter in `Activity` or `PackageParam`, the data <u>**will be stored and read in the private directory of the corresponding environment**</u>, and the data will be isolated from each other.
|
||||||
|
|
||||||
|
::: tip
|
||||||
|
|
||||||
|
For more functions, please refer to [YukiHookPrefsBridge](../public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge).
|
||||||
|
|
||||||
|
:::
|
@@ -218,6 +218,6 @@ For configuration details related to use as a Hook API, you can [click here](../
|
|||||||
|
|
||||||
::: warning
|
::: warning
|
||||||
|
|
||||||
**YukiHookModulePrefs**, **YukiHookDataChannel** and Resources Hook functionality will not work when using a custom Hook Framework instead of the full Xposed Module.
|
**YukiHookPrefsBridge**, **YukiHookDataChannel** and Resources Hook functionality will not work when using a custom Hook Framework instead of the full Xposed Module.
|
||||||
|
|
||||||
:::
|
:::
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
> 这里收录了 `YukiHookAPI` 尚未解决的问题。
|
> 这里收录了 `YukiHookAPI` 尚未解决的问题。
|
||||||
|
|
||||||
### YukiHookModulePrefs
|
### YukiHookPrefsBridge
|
||||||
|
|
||||||
目前仅限完美支持 LSPosed,其它 Xposed 框架需要降级模块 API。
|
目前仅限完美支持 LSPosed,其它 Xposed 框架需要降级模块 API。
|
||||||
|
|
||||||
|
@@ -396,23 +396,33 @@ var isDebug: Boolean
|
|||||||
|
|
||||||
请转移到 `YukiHookLogger.Configs.isEnable`
|
请转移到 `YukiHookLogger.Configs.isEnable`
|
||||||
|
|
||||||
### isEnableModulePrefsCache <span class="symbol">- field</span>
|
<h3 class="deprecated">isEnableModulePrefsCache - field</h3>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
|
||||||
var isEnableModulePrefsCache: Boolean
|
|
||||||
```
|
|
||||||
|
|
||||||
**变更记录**
|
**变更记录**
|
||||||
|
|
||||||
`v1.0.5` `新增`
|
`v1.0.5` `新增`
|
||||||
|
|
||||||
|
`v1.1.9` `作废`
|
||||||
|
|
||||||
|
请转移到 `isEnablePrefsBridgeCache`
|
||||||
|
|
||||||
|
### isEnablePrefsBridgeCache <span class="symbol">- field</span>
|
||||||
|
|
||||||
|
```kotlin:no-line-numbers
|
||||||
|
var isEnablePrefsBridgeCache: Boolean
|
||||||
|
```
|
||||||
|
|
||||||
|
**变更记录**
|
||||||
|
|
||||||
|
`v1.1.9` `新增`
|
||||||
|
|
||||||
**功能描述**
|
**功能描述**
|
||||||
|
|
||||||
> 是否启用 `YukiHookModulePrefs` 的键值缓存功能。
|
> 是否启用 `YukiHookPrefsBridge` 的键值缓存功能。
|
||||||
|
|
||||||
为防止内存复用过高问题,此功能默认启用。
|
为防止内存复用过高问题,此功能默认启用。
|
||||||
|
|
||||||
你可以手动在 `YukiHookModulePrefs` 中自由开启和关闭缓存功能以及清除缓存。
|
你可以手动在 `YukiHookPrefsBridge` 中自由开启和关闭缓存功能以及清除缓存。
|
||||||
|
|
||||||
### isEnableModuleAppResourcesCache <span class="symbol">- field</span>
|
### isEnableModuleAppResourcesCache <span class="symbol">- field</span>
|
||||||
|
|
||||||
@@ -480,7 +490,7 @@ var isEnableHookSharedPreferences: Boolean
|
|||||||
|
|
||||||
这是一个可选的实验性功能,此功能默认不启用。
|
这是一个可选的实验性功能,此功能默认不启用。
|
||||||
|
|
||||||
仅用于修复某些系统可能会出现在启用了 **New XSharedPreferences** 后依然出现文件权限错误问题,若你能正常使用 **YukiHookModulePrefs** 就不建议启用此功能。
|
仅用于修复某些系统可能会出现在启用了 **New XSharedPreferences** 后依然出现文件权限错误问题,若你能正常使用 **YYukiHookPrefsBridge** 就不建议启用此功能。
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -564,7 +574,7 @@ object HookEntry : IYukiHookXposedInit {
|
|||||||
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
|
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
|
||||||
}
|
}
|
||||||
isDebug = BuildConfig.DEBUG
|
isDebug = BuildConfig.DEBUG
|
||||||
isEnableModulePrefsCache = true
|
isEnablePrefsBridgeCache = true
|
||||||
isEnableModuleAppResourcesCache = true
|
isEnableModuleAppResourcesCache = true
|
||||||
isEnableHookModuleStatus = true
|
isEnableHookModuleStatus = true
|
||||||
isEnableHookSharedPreferences = false
|
isEnableHookSharedPreferences = false
|
||||||
@@ -594,7 +604,7 @@ object HookEntry : IYukiHookXposedInit {
|
|||||||
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
|
elements(TAG, PRIORITY, PACKAGE_NAME, USER_ID)
|
||||||
}
|
}
|
||||||
isDebug = BuildConfig.DEBUG
|
isDebug = BuildConfig.DEBUG
|
||||||
isEnableModulePrefsCache = true
|
isEnablePrefsBridgeCache = true
|
||||||
isEnableModuleAppResourcesCache = true
|
isEnableModuleAppResourcesCache = true
|
||||||
isEnableHookModuleStatus = true
|
isEnableHookModuleStatus = true
|
||||||
isEnableHookSharedPreferences = false
|
isEnableHookSharedPreferences = false
|
||||||
@@ -626,7 +636,7 @@ object HookEntry : IYukiHookXposedInit {
|
|||||||
YukiHookLogger.Configs.USER_ID
|
YukiHookLogger.Configs.USER_ID
|
||||||
)
|
)
|
||||||
YukiHookAPI.Configs.isDebug = BuildConfig.DEBUG
|
YukiHookAPI.Configs.isDebug = BuildConfig.DEBUG
|
||||||
YukiHookAPI.Configs.isEnableModulePrefsCache = true
|
YukiHookAPI.Configs.isEnablePrefsBridgeCache = true
|
||||||
YukiHookAPI.Configs.isEnableModuleAppResourcesCache = true
|
YukiHookAPI.Configs.isEnableModuleAppResourcesCache = true
|
||||||
YukiHookAPI.Configs.isEnableHookModuleStatus = true
|
YukiHookAPI.Configs.isEnableHookModuleStatus = true
|
||||||
YukiHookAPI.Configs.isEnableHookSharedPreferences = false
|
YukiHookAPI.Configs.isEnableHookSharedPreferences = false
|
||||||
|
@@ -56,33 +56,45 @@ fun IYukiHookXposedInit.encase(vararg hooker: YukiBaseHooker)
|
|||||||
|
|
||||||
> 在 `IYukiHookXposedInit` 中调用 `YukiHookAPI`。
|
> 在 `IYukiHookXposedInit` 中调用 `YukiHookAPI`。
|
||||||
|
|
||||||
## Context.modulePrefs <span class="symbol">- ext-field</span>
|
<h2 class="deprecated">Context.modulePrefs - ext-field</h2>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
|
||||||
val Context.modulePrefs: YukiHookModulePrefs
|
|
||||||
```
|
|
||||||
|
|
||||||
**变更记录**
|
**变更记录**
|
||||||
|
|
||||||
`v1.0` `添加`
|
`v1.0` `添加`
|
||||||
|
|
||||||
**功能描述**
|
`v1.1.9` `作废`
|
||||||
|
|
||||||
> 获取模块的存取对象。
|
请转移到 `prefs` 方法
|
||||||
|
|
||||||
## Context.modulePrefs <span class="symbol">- ext-method</span>
|
<h2 class="deprecated">Context.modulePrefs - ext-method</h2>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
|
||||||
fun Context.modulePrefs(name: String): YukiHookModulePrefs
|
|
||||||
```
|
|
||||||
|
|
||||||
**变更记录**
|
**变更记录**
|
||||||
|
|
||||||
`v1.0` `添加`
|
`v1.0` `添加`
|
||||||
|
|
||||||
|
`v1.1.9` `作废`
|
||||||
|
|
||||||
|
请转移到 `prefs` 方法
|
||||||
|
|
||||||
|
## Context.prefs <span class="symbol">- ext-method</span>
|
||||||
|
|
||||||
|
```kotlin:no-line-numbers
|
||||||
|
fun Context.prefs(name: String): YukiHookPrefsBridge
|
||||||
|
```
|
||||||
|
|
||||||
|
**变更记录**
|
||||||
|
|
||||||
|
`v1.1.9` `新增`
|
||||||
|
|
||||||
**功能描述**
|
**功能描述**
|
||||||
|
|
||||||
> 获取模块的存取对象,可设置 `name` 为自定义 Sp 存储名称。
|
> 获取 `YukiHookPrefsBridge` 对象。
|
||||||
|
|
||||||
|
可以同时在模块与 (Xposed) 宿主环境中使用。
|
||||||
|
|
||||||
|
如果你想在 (Xposed) 宿主环境将数据存入当前宿主的私有空间,请使用 `YukiHookPrefsBridge.native` 方法。
|
||||||
|
|
||||||
|
在未声明任何条件的情况下 (Xposed) 宿主环境默认读取模块中的数据。
|
||||||
|
|
||||||
## Context.dataChannel <span class="symbol">- ext-method</span>
|
## Context.dataChannel <span class="symbol">- ext-method</span>
|
||||||
|
|
||||||
|
@@ -235,7 +235,7 @@ val moduleAppResources: YukiModuleResources
|
|||||||
## prefs <span class="symbol">- field</span>
|
## prefs <span class="symbol">- field</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
val prefs: YukiHookModulePrefs
|
val prefs: YukiHookPrefsBridge
|
||||||
```
|
```
|
||||||
|
|
||||||
**变更记录**
|
**变更记录**
|
||||||
@@ -255,7 +255,7 @@ val prefs: YukiHookModulePrefs
|
|||||||
## prefs <span class="symbol">- method</span>
|
## prefs <span class="symbol">- method</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
fun prefs(name: String): YukiHookModulePrefs
|
fun prefs(name: String): YukiHookPrefsBridge
|
||||||
```
|
```
|
||||||
|
|
||||||
**变更记录**
|
**变更记录**
|
||||||
|
@@ -2,25 +2,29 @@
|
|||||||
pageClass: code-page
|
pageClass: code-page
|
||||||
---
|
---
|
||||||
|
|
||||||
# YukiHookModulePrefs <span class="symbol">- class</span>
|
# YukiHookPrefsBridge <span class="symbol">- class</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
class YukiHookModulePrefs private constructor(private var context: Context?)
|
class YukiHookPrefsBridge private constructor(private var context: Context?)
|
||||||
```
|
```
|
||||||
|
|
||||||
**变更记录**
|
**变更记录**
|
||||||
|
|
||||||
`v1.0` `添加`
|
`v1.0` `添加`
|
||||||
|
|
||||||
|
`v1.1.9` `修改`
|
||||||
|
|
||||||
|
~~`YukiHookModulePrefs`~~ 更名为 `YukiHookPrefsBridge`
|
||||||
|
|
||||||
**功能描述**
|
**功能描述**
|
||||||
|
|
||||||
> 实现 Xposed 模块的数据存取,对接 `SharedPreferences` 和 `XSharedPreferences`。
|
> `YukiHookAPI` 对 `SharedPreferences`、`XSharedPreferences` 的扩展存储桥实现。
|
||||||
|
|
||||||
在不同环境智能选择存取使用的对象。
|
在不同环境智能选择存取使用的对象。
|
||||||
|
|
||||||
::: danger
|
::: danger
|
||||||
|
|
||||||
此功能为实验性功能,仅在 LSPosed 环境测试通过,EdXposed 理论也可以使用但不再推荐。
|
模块与宿主之前共享数据存储为实验性功能,仅在 LSPosed 环境测试通过,EdXposed 理论也可以使用但不再推荐。
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -34,13 +38,7 @@ class YukiHookModulePrefs private constructor(private var context: Context?)
|
|||||||
|
|
||||||
太极请参阅 [文件权限/配置/XSharedPreference](https://taichi.cool/zh/doc/for-xposed-dev.html#文件权限-配置-xsharedpreference)。
|
太极请参阅 [文件权限/配置/XSharedPreference](https://taichi.cool/zh/doc/for-xposed-dev.html#文件权限-配置-xsharedpreference)。
|
||||||
|
|
||||||
::: danger
|
对于在模块环境中使用 `PreferenceFragmentCompat`,`YukiHookAPI` 提供了 `ModulePreferenceFragment` 来实现同样的功能。
|
||||||
|
|
||||||
当你在 Xposed 模块中存取数据的时候 **context** 必须不能是空的。
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
若你正在使用 `PreferenceFragmentCompat`,请迁移到 `ModulePreferenceFragment` 以适配上述功能特性。
|
|
||||||
|
|
||||||
**可选配置**
|
**可选配置**
|
||||||
|
|
||||||
@@ -88,7 +86,7 @@ val isPreferencesAvailable: Boolean
|
|||||||
|
|
||||||
**功能描述**
|
**功能描述**
|
||||||
|
|
||||||
> 获取当前 `YukiHookModulePrefs` 的可用状态。
|
> 获取当前 `YukiHookPrefsBridge` 的可用状态。
|
||||||
|
|
||||||
在 (Xposed) 宿主环境中返回 `XSharedPreferences` 可用状态 (可读)。
|
在 (Xposed) 宿主环境中返回 `XSharedPreferences` 可用状态 (可读)。
|
||||||
|
|
||||||
@@ -97,7 +95,7 @@ val isPreferencesAvailable: Boolean
|
|||||||
## name <span class="symbol">- method</span>
|
## name <span class="symbol">- method</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
fun name(name: String): YukiHookModulePrefs
|
fun name(name: String): YukiHookPrefsBridge
|
||||||
```
|
```
|
||||||
|
|
||||||
**变更记录**
|
**变更记录**
|
||||||
@@ -115,7 +113,7 @@ fun name(name: String): YukiHookModulePrefs
|
|||||||
> 示例如下
|
> 示例如下
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
modulePrefs("custom_name").getString("custom_key")
|
prefs("custom_name").getString("custom_key")
|
||||||
```
|
```
|
||||||
|
|
||||||
在 (Xposed) 宿主环境 `PackageParam` 中的使用方法。
|
在 (Xposed) 宿主环境 `PackageParam` 中的使用方法。
|
||||||
@@ -129,7 +127,7 @@ prefs("custom_name").getString("custom_key")
|
|||||||
## direct <span class="symbol">- method</span>
|
## direct <span class="symbol">- method</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
fun direct(): YukiHookModulePrefs
|
fun direct(): YukiHookPrefsBridge
|
||||||
```
|
```
|
||||||
|
|
||||||
**变更记录**
|
**变更记录**
|
||||||
@@ -140,10 +138,24 @@ fun direct(): YukiHookModulePrefs
|
|||||||
|
|
||||||
> 忽略缓存直接读取键值。
|
> 忽略缓存直接读取键值。
|
||||||
|
|
||||||
无论是否开启 `YukiHookAPI.Configs.isEnableModulePrefsCache`。
|
无论是否开启 `YukiHookAPI.Configs.isEnablePrefsBridgeCache`。
|
||||||
|
|
||||||
仅在 `XSharedPreferences` 下生效。
|
仅在 `XSharedPreferences` 下生效。
|
||||||
|
|
||||||
|
## native <span class="symbol">- method</span>
|
||||||
|
|
||||||
|
```kotlin:no-line-numbers
|
||||||
|
fun native(): YukiHookPrefsBridge
|
||||||
|
```
|
||||||
|
|
||||||
|
**变更记录**
|
||||||
|
|
||||||
|
`v1.1.9` `新增`
|
||||||
|
|
||||||
|
**功能描述**
|
||||||
|
|
||||||
|
> 忽略当前环境直接使用 `Context.getSharedPreferences` 存取数据。
|
||||||
|
|
||||||
## getString <span class="symbol">- method</span>
|
## getString <span class="symbol">- method</span>
|
||||||
|
|
||||||
```kotlin:no-line-numbers
|
```kotlin:no-line-numbers
|
||||||
@@ -426,7 +438,7 @@ fun clearCache()
|
|||||||
|
|
||||||
> 清除 `XSharedPreferences` 中缓存的键值数据。
|
> 清除 `XSharedPreferences` 中缓存的键值数据。
|
||||||
|
|
||||||
无论是否开启 `YukiHookAPI.Configs.isEnableModulePrefsCache`。
|
无论是否开启 `YukiHookAPI.Configs.isEnablePrefsBridgeCache`。
|
||||||
|
|
||||||
调用此方法将清除当前存储的全部键值缓存。
|
调用此方法将清除当前存储的全部键值缓存。
|
||||||
|
|
||||||
@@ -446,7 +458,7 @@ inner class Editor internal constructor()
|
|||||||
|
|
||||||
**功能描述**
|
**功能描述**
|
||||||
|
|
||||||
> `YukiHookModulePrefs` 的存储代理类。
|
> `YukiHookPrefsBridge` 的存储代理类。
|
||||||
|
|
||||||
请使用 `edit` 方法来获取 `Editor`。
|
请使用 `edit` 方法来获取 `Editor`。
|
||||||
|
|
@@ -20,7 +20,7 @@ data class PrefsData<T>(var key: String, var value: T) : Serializable
|
|||||||
|
|
||||||
> 键值对存储构造类。
|
> 键值对存储构造类。
|
||||||
|
|
||||||
这个类是对 `YukiHookModulePrefs` 的一个扩展用法。
|
这个类是对 `YukiHookPrefsBridge` 的一个扩展用法。
|
||||||
|
|
||||||
**功能示例**
|
**功能示例**
|
||||||
|
|
||||||
@@ -43,9 +43,9 @@ object DataConst {
|
|||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
// 读取
|
// 读取
|
||||||
val data = modulePrefs.get(DataConst.TEST_KV_DATA_1)
|
val data = prefs().get(DataConst.TEST_KV_DATA_1)
|
||||||
// 写入
|
// 写入
|
||||||
modulePrefs.put(DataConst.TEST_KV_DATA_1, "written value")
|
prefs().edit { put(DataConst.TEST_KV_DATA_1, "written value") }
|
||||||
```
|
```
|
||||||
|
|
||||||
> 宿主示例如下
|
> 宿主示例如下
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
## 在 Activity 中使用
|
## 在 Activity 中使用
|
||||||
|
|
||||||
> 这里描述了在 `Activity` 中装载 `YukiHookModulePrefs` 的场景。
|
> 这里描述了在 `Activity` 中装载 `YukiHookPrefsBridge` 的场景。
|
||||||
|
|
||||||
通常情况下我们可以这样在 Hook APP (宿主) 内对其进行初始化。
|
通常情况下我们可以这样在 Hook APP (宿主) 内对其进行初始化。
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ XSharedPreferences(BuildConfig.APPLICATION_ID)
|
|||||||
> 示例如下
|
> 示例如下
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
modulePrefs.putString("test_name", "saved_value")
|
prefs().edit { putString("test_name", "saved_value") }
|
||||||
```
|
```
|
||||||
|
|
||||||
当你在 Hook APP (宿主) 中读取数据时,可以使用如下方法。
|
当你在 Hook APP (宿主) 中读取数据时,可以使用如下方法。
|
||||||
@@ -36,7 +36,7 @@ modulePrefs.putString("test_name", "saved_value")
|
|||||||
val testName = prefs.getString("test_name", "default_value")
|
val testName = prefs.getString("test_name", "default_value")
|
||||||
```
|
```
|
||||||
|
|
||||||
你不需要考虑传入模块的包名以及一系列复杂的权限配置,一切都交给 `YukiHookModulePrefs` 来处理。
|
你不需要考虑传入模块的包名以及一系列复杂的权限配置,一切都交给 `YukiHookPrefsBridge` 来处理。
|
||||||
|
|
||||||
若要实现存储的区域划分,你可以指定每个 `prefs` 文件的名称。
|
若要实现存储的区域划分,你可以指定每个 `prefs` 文件的名称。
|
||||||
|
|
||||||
@@ -46,9 +46,9 @@ val testName = prefs.getString("test_name", "default_value")
|
|||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
// 推荐用法
|
// 推荐用法
|
||||||
modulePrefs("specify_file_name").putString("test_name", "saved_value")
|
prefs("specify_file_name").edit { putString("test_name", "saved_value") }
|
||||||
// 也可以这样用
|
// 也可以这样用
|
||||||
modulePrefs.name("specify_file_name").putString("test_name", "saved_value")
|
prefs().name("specify_file_name").edit { putString("test_name", "saved_value") }
|
||||||
```
|
```
|
||||||
|
|
||||||
在 Hook APP (宿主) 中这样读取。
|
在 Hook APP (宿主) 中这样读取。
|
||||||
@@ -64,21 +64,40 @@ val testName = prefs.name("specify_file_name").getString("test_name", "default_v
|
|||||||
|
|
||||||
若你的项目中有大量的固定数据需要存储和读取,推荐使用 `PrefsData` 来创建模板。
|
若你的项目中有大量的固定数据需要存储和读取,推荐使用 `PrefsData` 来创建模板。
|
||||||
|
|
||||||
|
通过上面的示例,你可以调用 `edit` 方法使用以下两种方式来批量存储数据。
|
||||||
|
|
||||||
|
> 示例如下
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// <方案 1>
|
||||||
|
prefs().edit {
|
||||||
|
putString("test_name_1", "saved_value_1")
|
||||||
|
putString("test_name_2", "saved_value_2")
|
||||||
|
putString("test_name_3", "saved_value_3")
|
||||||
|
}
|
||||||
|
// <方案 2>
|
||||||
|
prefs().edit()
|
||||||
|
.putString("test_name_1", "saved_value_1")
|
||||||
|
.putString("test_name_2", "saved_value_2")
|
||||||
|
.putString("test_name_3", "saved_value_3")
|
||||||
|
.apply()
|
||||||
|
```
|
||||||
|
|
||||||
::: tip
|
::: tip
|
||||||
|
|
||||||
更多功能请参考 [YukiHookModulePrefs](../public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookModulePrefs)、[PrefsData](../public/com/highcapable/yukihookapi/hook/xposed/prefs/data/PrefsData)。
|
更多功能请参考 [YukiHookPrefsBridge](../public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge)、[PrefsData](../public/com/highcapable/yukihookapi/hook/xposed/prefs/data/PrefsData)。
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## 在 PreferenceFragment 中使用
|
## 在 PreferenceFragment 中使用
|
||||||
|
|
||||||
> 这里描述了在 `PreferenceFragment` 中装载 `YukiHookModulePrefs` 的场景。
|
> 这里描述了在 `PreferenceFragment` 中装载 `YukiHookPrefsBridge` 的场景。
|
||||||
|
|
||||||
若你的模块使用了 `PreferenceFragmentCompat`,你现在可以将其继承类开始迁移到 `ModulePreferenceFragment`。
|
若你的模块使用了 `PreferenceFragmentCompat`,你现在可以将其继承类开始迁移到 `ModulePreferenceFragment`。
|
||||||
|
|
||||||
::: danger
|
::: danger
|
||||||
|
|
||||||
你必须继承 **ModulePreferenceFragment** 才能实现 **YukiHookModulePrefs** 的模块存储功能。
|
你必须继承 **ModulePreferenceFragment** 才能实现 **YukiHookPrefsBridge** 的模块存储功能。
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -87,3 +106,49 @@ val testName = prefs.name("specify_file_name").getString("test_name", "default_v
|
|||||||
更多功能请参考 [ModulePreferenceFragment](../public/com/highcapable/yukihookapi/hook/xposed/prefs/ui/ModulePreferenceFragment)。
|
更多功能请参考 [ModulePreferenceFragment](../public/com/highcapable/yukihookapi/hook/xposed/prefs/ui/ModulePreferenceFragment)。
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
## 使用原生方式存储
|
||||||
|
|
||||||
|
在模块环境中 `YukiHookPrefsBridge` 默认会将数据存储到模块自己的私有目录 (或 Hook Framework 提供的共享目录) 中。
|
||||||
|
|
||||||
|
在宿主环境中使用 `YukiHookPrefsBridge` 默认会读取模块自己的私有目录 (或 Hook Framework 提供的共享目录) 中的数据。
|
||||||
|
|
||||||
|
如果你想直接将数据存储到模块或宿主当前环境自身的私有目录,你可以使用 `native` 方法。
|
||||||
|
|
||||||
|
例如模块的目录是 `.../com.demo.test.module/shared_prefs`,宿主的目录是 `.../com.demo.test.host/shared_prefs`。
|
||||||
|
|
||||||
|
以下是在 `Activity` 中的用法。
|
||||||
|
|
||||||
|
> 示例如下
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// 存储私有数据
|
||||||
|
prefs().native().edit { putBoolean("isolation_data", true) }
|
||||||
|
// 读取私有数据
|
||||||
|
val privateData = prefs().native().getBoolean("isolation_data")
|
||||||
|
// 存储共享数据
|
||||||
|
prefs().edit { putBoolean("public_data", true) }
|
||||||
|
// 读取共享数据
|
||||||
|
val publicData = prefs().getBoolean("public_data")
|
||||||
|
```
|
||||||
|
|
||||||
|
以下是在 `PackageParam` 中的用法。
|
||||||
|
|
||||||
|
> 示例如下
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// 存储私有数据
|
||||||
|
prefs.native().edit { putBoolean("isolation_data", true) }
|
||||||
|
// 读取私有数据
|
||||||
|
val privateData = prefs.native().getBoolean("isolation_data")
|
||||||
|
// 读取共享数据
|
||||||
|
val publicData = prefs.getBoolean("public_data")
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 `native` 方法后,无论在 `Activity` 还是 `PackageParam` 中都会将数据<u>**在对应环境的私有目录中**</u>存储、读取,数据相互隔离。
|
||||||
|
|
||||||
|
::: tip
|
||||||
|
|
||||||
|
更多功能请参考 [YukiHookPrefsBridge](../public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge)。
|
||||||
|
|
||||||
|
:::
|
@@ -215,6 +215,6 @@ override fun attachBaseContext(base: Context?) {
|
|||||||
|
|
||||||
::: warning
|
::: warning
|
||||||
|
|
||||||
使用自定义的 Hook Framework 而并非完整的 Xposed 模块时,**YukiHookModulePrefs**、**YukiHookDataChannel** 以及 Resources Hook 功能将失效。
|
使用自定义的 Hook Framework 而并非完整的 Xposed 模块时,**YukiHookPrefsBridge**、**YukiHookDataChannel** 以及 Resources Hook 功能将失效。
|
||||||
|
|
||||||
:::
|
:::
|
@@ -57,7 +57,7 @@ import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule
|
|||||||
import com.highcapable.yukihookapi.hook.xposed.bridge.status.YukiXposedModuleStatus
|
import com.highcapable.yukihookapi.hook.xposed.bridge.status.YukiXposedModuleStatus
|
||||||
import com.highcapable.yukihookapi.hook.xposed.bridge.type.HookEntryType
|
import com.highcapable.yukihookapi.hook.xposed.bridge.type.HookEntryType
|
||||||
import com.highcapable.yukihookapi.hook.xposed.channel.YukiHookDataChannel
|
import com.highcapable.yukihookapi.hook.xposed.channel.YukiHookDataChannel
|
||||||
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookModulePrefs
|
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookPrefsBridge
|
||||||
import java.lang.reflect.Constructor
|
import java.lang.reflect.Constructor
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.lang.reflect.Member
|
import java.lang.reflect.Member
|
||||||
@@ -281,13 +281,27 @@ object YukiHookAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否启用 [YukiHookModulePrefs] 的键值缓存功能
|
* 是否启用 [YukiHookPrefsBridge] 的键值缓存功能
|
||||||
|
*
|
||||||
|
* - ❗此方法已弃用 - 在之后的版本中将直接被删除
|
||||||
|
*
|
||||||
|
* - ❗请现在转移到 [isEnablePrefsBridgeCache]
|
||||||
|
*/
|
||||||
|
@Deprecated(message = "请使用新的命名方法来实现此功能", ReplaceWith("isEnablePrefsBridgeCache"))
|
||||||
|
var isEnableModulePrefsCache
|
||||||
|
get() = isEnablePrefsBridgeCache
|
||||||
|
set(value) {
|
||||||
|
isEnablePrefsBridgeCache = value
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用 [YukiHookPrefsBridge] 的键值缓存功能
|
||||||
*
|
*
|
||||||
* - 为防止内存复用过高问题 - 此功能默认启用
|
* - 为防止内存复用过高问题 - 此功能默认启用
|
||||||
*
|
*
|
||||||
* 你可以手动在 [YukiHookModulePrefs] 中自由开启和关闭缓存功能以及清除缓存
|
* 你可以手动在 [YukiHookPrefsBridge] 中自由开启和关闭缓存功能以及清除缓存
|
||||||
*/
|
*/
|
||||||
var isEnableModulePrefsCache = true
|
var isEnablePrefsBridgeCache = true
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否启用当前 Xposed 模块自身 [Resources] 缓存功能
|
* 是否启用当前 Xposed 模块自身 [Resources] 缓存功能
|
||||||
@@ -316,7 +330,7 @@ object YukiHookAPI {
|
|||||||
*
|
*
|
||||||
* - ❗这是一个可选的实验性功能 - 此功能默认不启用
|
* - ❗这是一个可选的实验性功能 - 此功能默认不启用
|
||||||
*
|
*
|
||||||
* - 仅用于修复某些系统可能会出现在启用了 New XSharedPreferences 后依然出现文件权限错误问题 - 若你能正常使用 [YukiHookModulePrefs] 就不建议启用此功能
|
* - 仅用于修复某些系统可能会出现在启用了 New XSharedPreferences 后依然出现文件权限错误问题 - 若你能正常使用 [YukiHookPrefsBridge] 就不建议启用此功能
|
||||||
*/
|
*/
|
||||||
var isEnableHookSharedPreferences = false
|
var isEnableHookSharedPreferences = false
|
||||||
|
|
||||||
|
@@ -49,7 +49,7 @@ import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics
|
|||||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.activity.base.ModuleAppActivity
|
import com.highcapable.yukihookapi.hook.xposed.parasitic.activity.base.ModuleAppActivity
|
||||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.activity.base.ModuleAppCompatActivity
|
import com.highcapable.yukihookapi.hook.xposed.parasitic.activity.base.ModuleAppCompatActivity
|
||||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.context.wrapper.ModuleContextThemeWrapper
|
import com.highcapable.yukihookapi.hook.xposed.parasitic.context.wrapper.ModuleContextThemeWrapper
|
||||||
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookModulePrefs
|
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookPrefsBridge
|
||||||
import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit
|
import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -76,16 +76,38 @@ fun IYukiHookXposedInit.encase(vararg hooker: YukiBaseHooker) = YukiHookAPI.enca
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取模块的存取对象
|
* 获取模块的存取对象
|
||||||
* @return [YukiHookModulePrefs]
|
*
|
||||||
|
* - ❗此方法已弃用 - 在之后的版本中将直接被删除
|
||||||
|
*
|
||||||
|
* - ❗请现在转移到 [Context.prefs] 方法
|
||||||
|
* @return [YukiHookPrefsBridge]
|
||||||
*/
|
*/
|
||||||
val Context.modulePrefs get() = YukiHookModulePrefs.instance(context = this)
|
@Deprecated(message = "请使用新的命名方法", ReplaceWith("prefs()"))
|
||||||
|
val Context.modulePrefs get() = prefs()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取模块的存取对象
|
* 获取模块的存取对象
|
||||||
* @param name 自定义 Sp 存储名称
|
*
|
||||||
* @return [YukiHookModulePrefs]
|
* - ❗此方法已弃用 - 在之后的版本中将直接被删除
|
||||||
|
*
|
||||||
|
* - ❗请现在转移到 [Context.prefs] 方法
|
||||||
|
* @return [YukiHookPrefsBridge]
|
||||||
*/
|
*/
|
||||||
fun Context.modulePrefs(name: String) = modulePrefs.name(name)
|
@Deprecated(message = "请使用新的命名方法", ReplaceWith("prefs(name)"))
|
||||||
|
fun Context.modulePrefs(name: String) = prefs(name)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 [YukiHookPrefsBridge] 对象
|
||||||
|
*
|
||||||
|
* 可以同时在模块与 (Xposed) 宿主环境中使用
|
||||||
|
*
|
||||||
|
* 如果你想在 (Xposed) 宿主环境将数据存入当前宿主的私有空间 - 请使用 [YukiHookPrefsBridge.native] 方法
|
||||||
|
*
|
||||||
|
* 在未声明任何条件的情况下 (Xposed) 宿主环境默认读取模块中的数据
|
||||||
|
* @param name 自定义 Sp 存储名称 - 默认空
|
||||||
|
* @return [YukiHookPrefsBridge]
|
||||||
|
*/
|
||||||
|
fun Context.prefs(name: String = "") = YukiHookPrefsBridge.instance(context = this).let { if (name.isNotBlank()) it.name(name) else it }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取模块的数据通讯桥命名空间对象
|
* 获取模块的数据通讯桥命名空间对象
|
||||||
|
@@ -56,7 +56,7 @@ import com.highcapable.yukihookapi.hook.xposed.bridge.resources.YukiResources
|
|||||||
import com.highcapable.yukihookapi.hook.xposed.bridge.type.HookEntryType
|
import com.highcapable.yukihookapi.hook.xposed.bridge.type.HookEntryType
|
||||||
import com.highcapable.yukihookapi.hook.xposed.channel.YukiHookDataChannel
|
import com.highcapable.yukihookapi.hook.xposed.channel.YukiHookDataChannel
|
||||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics
|
import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics
|
||||||
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookModulePrefs
|
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookPrefsBridge
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 装载 Hook 的目标 APP 入口对象实现类
|
* 装载 Hook 的目标 APP 入口对象实现类
|
||||||
@@ -181,16 +181,16 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper:
|
|||||||
* 获得当前使用的存取数据对象缓存实例
|
* 获得当前使用的存取数据对象缓存实例
|
||||||
*
|
*
|
||||||
* - ❗作为 Hook API 装载时无法使用 - 会抛出异常
|
* - ❗作为 Hook API 装载时无法使用 - 会抛出异常
|
||||||
* @return [YukiHookModulePrefs]
|
* @return [YukiHookPrefsBridge]
|
||||||
*/
|
*/
|
||||||
val prefs get() = YukiHookModulePrefs.instance()
|
val prefs get() = YukiHookPrefsBridge.instance()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得当前使用的存取数据对象缓存实例
|
* 获得当前使用的存取数据对象缓存实例
|
||||||
*
|
*
|
||||||
* - ❗作为 Hook API 装载时无法使用 - 会抛出异常
|
* - ❗作为 Hook API 装载时无法使用 - 会抛出异常
|
||||||
* @param name 自定义 Sp 存储名称
|
* @param name 自定义 Sp 存储名称
|
||||||
* @return [YukiHookModulePrefs]
|
* @return [YukiHookPrefsBridge]
|
||||||
*/
|
*/
|
||||||
fun prefs(name: String) = prefs.name(name)
|
fun prefs(name: String) = prefs.name(name)
|
||||||
|
|
||||||
|
@@ -37,42 +37,35 @@ 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.bridge.delegate.XSharedPreferencesDelegate
|
||||||
|
import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics
|
||||||
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
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实现 Xposed 模块的数据存取
|
* [YukiHookAPI] 对 [SharedPreferences]、[XSharedPreferences] 的扩展存储桥实现
|
||||||
*
|
|
||||||
* 对接 [SharedPreferences] 和 [XSharedPreferences]
|
|
||||||
*
|
*
|
||||||
* 在不同环境智能选择存取使用的对象
|
* 在不同环境智能选择存取使用的对象
|
||||||
*
|
*
|
||||||
* - ❗请注意此功能为实验性功能 - 仅在 LSPosed 环境测试通过 - EdXposed 理论也可以使用但不再推荐
|
* - ❗模块与宿主之前共享数据存储为实验性功能 - 仅在 LSPosed 环境测试通过 - EdXposed 理论也可以使用但不再推荐
|
||||||
*
|
*
|
||||||
* - 使用 LSPosed 环境请在 AndroidManifests.xml 中将 "xposedminversion" 最低设置为 93
|
* 对于在模块环境中使用 [PreferenceFragmentCompat] - [YukiHookAPI] 提供了 [ModulePreferenceFragment] 来实现同样的功能
|
||||||
*
|
*
|
||||||
* - 未使用 LSPosed 环境请将你的模块 API 降至 26 以下 - [YukiHookAPI] 将会尝试使用 [makeWorldReadable] 但仍有可能不成功
|
* 详情请参考 [API 文档 - YukiHookPrefsBridge](https://fankes.github.io/YukiHookAPI/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge)
|
||||||
*
|
*
|
||||||
* - ❗当你在模块中存取数据的时候 [context] 必须不能是空的
|
* For English version, see [API Document - YukiHookPrefsBridge](https://fankes.github.io/YukiHookAPI/en/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookPrefsBridge)
|
||||||
*
|
|
||||||
* - 若你正在使用 [PreferenceFragmentCompat] - 请迁移到 [ModulePreferenceFragment] 以适配上述功能特性
|
|
||||||
*
|
|
||||||
* 详情请参考 [API 文档 - YukiHookModulePrefs](https://fankes.github.io/YukiHookAPI/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookModulePrefs)
|
|
||||||
*
|
|
||||||
* For English version, see [API Document - YukiHookModulePrefs](https://fankes.github.io/YukiHookAPI/en/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/YukiHookModulePrefs)
|
|
||||||
* @param context 上下文实例 - 默认空
|
* @param context 上下文实例 - 默认空
|
||||||
*/
|
*/
|
||||||
class YukiHookModulePrefs private constructor(private var context: Context? = null) {
|
class YukiHookPrefsBridge private constructor(private var context: Context? = null) {
|
||||||
|
|
||||||
internal companion object {
|
internal companion object {
|
||||||
|
|
||||||
/** 当前是否为 (Xposed) 宿主环境 */
|
/** 当前是否为 (Xposed) 宿主环境 */
|
||||||
private val isXposedEnvironment = YukiXposedModule.isXposedEnvironment
|
private val isXposedEnvironment = YukiXposedModule.isXposedEnvironment
|
||||||
|
|
||||||
/** 当前 [YukiHookModulePrefs] 单例 */
|
/** 当前 [YukiHookPrefsBridge] 单例 */
|
||||||
private var instance: YukiHookModulePrefs? = null
|
private var instance: YukiHookPrefsBridge? = null
|
||||||
|
|
||||||
/** 当前缓存的 [XSharedPreferencesDelegate] 实例数组 */
|
/** 当前缓存的 [XSharedPreferencesDelegate] 实例数组 */
|
||||||
private val xPrefs = HashMap<String, XSharedPreferencesDelegate>()
|
private val xPrefs = HashMap<String, XSharedPreferencesDelegate>()
|
||||||
@@ -81,12 +74,12 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
private val sPrefs = HashMap<String, SharedPreferences>()
|
private val sPrefs = HashMap<String, SharedPreferences>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 [YukiHookModulePrefs] 单例
|
* 获取 [YukiHookPrefsBridge] 单例
|
||||||
* @param context 实例 - (Xposed) 宿主环境为空
|
* @param context 实例 - (Xposed) 宿主环境为空
|
||||||
* @return [YukiHookModulePrefs]
|
* @return [YukiHookPrefsBridge]
|
||||||
*/
|
*/
|
||||||
internal fun instance(context: Context? = null) =
|
internal fun instance(context: Context? = null) =
|
||||||
instance?.apply { if (context != null) this.context = context } ?: YukiHookModulePrefs(context).apply { instance = this }
|
instance?.apply { if (context != null) this.context = context } ?: YukiHookPrefsBridge(context).apply { instance = this }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置全局可读可写
|
* 设置全局可读可写
|
||||||
@@ -105,15 +98,28 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 存储名称 - 默认包名 + _preferences */
|
/** 存储名称 */
|
||||||
private var prefsName = "${YukiXposedModule.modulePackageName.ifBlank { context?.packageName ?: "" }}_preferences"
|
private var prefsName = ""
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前存储名称 - 默认包名 + _preferences
|
||||||
|
* @return [String]
|
||||||
|
*/
|
||||||
|
private val currentPrefsName
|
||||||
|
get() = prefsName.ifBlank {
|
||||||
|
if (isUsingNativeStorage) "${context?.packageName ?: "unknown"}_preferences"
|
||||||
|
else "${YukiXposedModule.modulePackageName.ifBlank { context?.packageName ?: "unknown" }}_preferences"
|
||||||
|
}
|
||||||
|
|
||||||
/** 是否使用键值缓存 */
|
/** 是否使用键值缓存 */
|
||||||
private var isUsingKeyValueCache = YukiHookAPI.Configs.isEnableModulePrefsCache
|
private var isUsingKeyValueCache = YukiHookAPI.Configs.isEnablePrefsBridgeCache
|
||||||
|
|
||||||
/** 是否使用新版存储方式 EdXposed/LSPosed */
|
/** 是否使用新版存储方式 EdXposed、LSPosed */
|
||||||
private var isUsingNewXSharedPreferences = false
|
private var isUsingNewXSharedPreferences = false
|
||||||
|
|
||||||
|
/** 是否启用原生存储方式 */
|
||||||
|
private var isUsingNativeStorage = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [XSharedPreferences] 缓存的键值数据
|
* [XSharedPreferences] 缓存的键值数据
|
||||||
*/
|
*/
|
||||||
@@ -150,7 +156,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
|
|
||||||
/** 检查 API 装载状态 */
|
/** 检查 API 装载状态 */
|
||||||
private fun checkApi() {
|
private fun checkApi() {
|
||||||
if (YukiHookAPI.isLoadedFromBaseContext) error("YukiHookModulePrefs not allowed in Custom Hook API")
|
if (YukiHookAPI.isLoadedFromBaseContext) error("YukiHookPrefsBridge not allowed in Custom Hook API")
|
||||||
if (isXposedEnvironment && YukiXposedModule.modulePackageName.isBlank())
|
if (isXposedEnvironment && YukiXposedModule.modulePackageName.isBlank())
|
||||||
error("Xposed modulePackageName load failed, please reset and rebuild it")
|
error("Xposed modulePackageName load failed, please reset and rebuild it")
|
||||||
}
|
}
|
||||||
@@ -162,8 +168,9 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
private val currentXsp
|
private val currentXsp
|
||||||
get() = checkApi().let {
|
get() = checkApi().let {
|
||||||
runCatching {
|
runCatching {
|
||||||
(xPrefs[prefsName]?.instance ?: XSharedPreferencesDelegate.from(YukiXposedModule.modulePackageName, prefsName).also {
|
(xPrefs[currentPrefsName]?.instance ?: XSharedPreferencesDelegate.from(YukiXposedModule.modulePackageName, currentPrefsName)
|
||||||
xPrefs[prefsName] = it
|
.also {
|
||||||
|
xPrefs[currentPrefsName] = it
|
||||||
}.instance).apply {
|
}.instance).apply {
|
||||||
makeWorldReadable()
|
makeWorldReadable()
|
||||||
reload()
|
reload()
|
||||||
@@ -180,21 +187,22 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
get() = checkApi().let {
|
get() = checkApi().let {
|
||||||
runCatching {
|
runCatching {
|
||||||
@Suppress("DEPRECATION", "WorldReadableFiles")
|
@Suppress("DEPRECATION", "WorldReadableFiles")
|
||||||
sPrefs[context.toString() + prefsName] ?: context?.getSharedPreferences(prefsName, Context.MODE_WORLD_READABLE)?.also {
|
sPrefs[context.toString() + currentPrefsName] ?: context?.getSharedPreferences(currentPrefsName, Context.MODE_WORLD_READABLE)
|
||||||
|
?.also {
|
||||||
isUsingNewXSharedPreferences = true
|
isUsingNewXSharedPreferences = true
|
||||||
sPrefs[context.toString() + prefsName] = it
|
sPrefs[context.toString() + currentPrefsName] = it
|
||||||
} ?: error("YukiHookModulePrefs missing Context instance")
|
} ?: error("YukiHookPrefsBridge missing Context instance")
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
sPrefs[context.toString() + prefsName] ?: context?.getSharedPreferences(prefsName, Context.MODE_PRIVATE)?.also {
|
sPrefs[context.toString() + currentPrefsName] ?: context?.getSharedPreferences(currentPrefsName, Context.MODE_PRIVATE)?.also {
|
||||||
isUsingNewXSharedPreferences = false
|
isUsingNewXSharedPreferences = false
|
||||||
sPrefs[context.toString() + prefsName] = it
|
sPrefs[context.toString() + currentPrefsName] = it
|
||||||
} ?: error("YukiHookModulePrefs missing Context instance")
|
} ?: error("YukiHookPrefsBridge missing Context instance")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 设置全局可读可写 */
|
/** 设置全局可读可写 */
|
||||||
private fun makeWorldReadable() = runCatching {
|
private fun makeWorldReadable() = runCatching {
|
||||||
if (isUsingNewXSharedPreferences.not()) makeWorldReadable(context, prefsFileName = "${prefsName}.xml")
|
if (isUsingNewXSharedPreferences.not()) makeWorldReadable(context, prefsFileName = "${currentPrefsName}.xml")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -209,7 +217,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
val isXSharePrefsReadable get() = isPreferencesAvailable
|
val isXSharePrefsReadable get() = isPreferencesAvailable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 [YukiHookModulePrefs] 是否正处于 EdXposed/LSPosed 的最高权限运行
|
* 获取 [YukiHookPrefsBridge] 是否正处于 EdXposed/LSPosed 的最高权限运行
|
||||||
*
|
*
|
||||||
* - ❗此方法已弃用 - 在之后的版本中将直接被删除
|
* - ❗此方法已弃用 - 在之后的版本中将直接被删除
|
||||||
*
|
*
|
||||||
@@ -220,7 +228,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
val isRunInNewXShareMode get() = isPreferencesAvailable
|
val isRunInNewXShareMode get() = isPreferencesAvailable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前 [YukiHookModulePrefs] 的可用状态
|
* 获取当前 [YukiHookPrefsBridge] 的可用状态
|
||||||
*
|
*
|
||||||
* - 在 (Xposed) 宿主环境中返回 [XSharedPreferences] 可用状态 (可读)
|
* - 在 (Xposed) 宿主环境中返回 [XSharedPreferences] 可用状态 (可读)
|
||||||
*
|
*
|
||||||
@@ -239,10 +247,10 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
/**
|
/**
|
||||||
* 自定义 Sp 存储名称
|
* 自定义 Sp 存储名称
|
||||||
* @param name 自定义的 Sp 存储名称
|
* @param name 自定义的 Sp 存储名称
|
||||||
* @return [YukiHookModulePrefs]
|
* @return [YukiHookPrefsBridge]
|
||||||
*/
|
*/
|
||||||
fun name(name: String): YukiHookModulePrefs {
|
fun name(name: String): YukiHookPrefsBridge {
|
||||||
isUsingKeyValueCache = YukiHookAPI.Configs.isEnableModulePrefsCache
|
isUsingKeyValueCache = YukiHookAPI.Configs.isEnablePrefsBridgeCache
|
||||||
prefsName = name
|
prefsName = name
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -253,13 +261,25 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
* 无论是否开启 [YukiHookAPI.Configs.isEnableModulePrefsCache]
|
* 无论是否开启 [YukiHookAPI.Configs.isEnableModulePrefsCache]
|
||||||
*
|
*
|
||||||
* - 仅在 [XSharedPreferences] 下生效
|
* - 仅在 [XSharedPreferences] 下生效
|
||||||
* @return [YukiHookModulePrefs]
|
* @return [YukiHookPrefsBridge]
|
||||||
*/
|
*/
|
||||||
fun direct(): YukiHookModulePrefs {
|
fun direct(): YukiHookPrefsBridge {
|
||||||
isUsingKeyValueCache = false
|
isUsingKeyValueCache = false
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 忽略当前环境直接使用 [Context.getSharedPreferences] 存取数据
|
||||||
|
* @return [YukiHookPrefsBridge]
|
||||||
|
* @throws IllegalStateException 如果 [context] 为空
|
||||||
|
*/
|
||||||
|
fun native(): YukiHookPrefsBridge {
|
||||||
|
if (isXposedEnvironment && context == null) context = AppParasitics.currentApplication
|
||||||
|
?: error("The Host App's Context has not yet initialized successfully, the native function cannot be used at this time")
|
||||||
|
isUsingNativeStorage = true
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 [String] 键值
|
* 获取 [String] 键值
|
||||||
*
|
*
|
||||||
@@ -271,7 +291,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
* @return [String]
|
* @return [String]
|
||||||
*/
|
*/
|
||||||
fun getString(key: String, value: String = "") =
|
fun getString(key: String, value: String = "") =
|
||||||
(if (isXposedEnvironment)
|
(if (isXposedEnvironment && isUsingNativeStorage.not())
|
||||||
if (isUsingKeyValueCache)
|
if (isUsingKeyValueCache)
|
||||||
XSharedPreferencesCaches.stringData[key].let {
|
XSharedPreferencesCaches.stringData[key].let {
|
||||||
(it ?: currentXsp.getString(key, value) ?: value).let { value ->
|
(it ?: currentXsp.getString(key, value) ?: value).let { value ->
|
||||||
@@ -282,7 +302,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
else resetCacheSet { currentXsp.getString(key, value) ?: value }
|
else resetCacheSet { currentXsp.getString(key, value) ?: value }
|
||||||
else currentSp.getString(key, value) ?: value).let {
|
else currentSp.getString(key, value) ?: value).let {
|
||||||
makeWorldReadable()
|
makeWorldReadable()
|
||||||
it
|
resetNativeSet { it }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,7 +316,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
* @return [Set]<[String]>
|
* @return [Set]<[String]>
|
||||||
*/
|
*/
|
||||||
fun getStringSet(key: String, value: Set<String>) =
|
fun getStringSet(key: String, value: Set<String>) =
|
||||||
(if (isXposedEnvironment)
|
(if (isXposedEnvironment && isUsingNativeStorage.not())
|
||||||
if (isUsingKeyValueCache)
|
if (isUsingKeyValueCache)
|
||||||
XSharedPreferencesCaches.stringSetData[key].let {
|
XSharedPreferencesCaches.stringSetData[key].let {
|
||||||
(it ?: currentXsp.getStringSet(key, value) ?: value).let { value ->
|
(it ?: currentXsp.getStringSet(key, value) ?: value).let { value ->
|
||||||
@@ -307,7 +327,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
else resetCacheSet { currentXsp.getStringSet(key, value) ?: value }
|
else resetCacheSet { currentXsp.getStringSet(key, value) ?: value }
|
||||||
else currentSp.getStringSet(key, value) ?: value).let {
|
else currentSp.getStringSet(key, value) ?: value).let {
|
||||||
makeWorldReadable()
|
makeWorldReadable()
|
||||||
it
|
resetNativeSet { it }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -321,7 +341,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
* @return [Boolean]
|
* @return [Boolean]
|
||||||
*/
|
*/
|
||||||
fun getBoolean(key: String, value: Boolean = false) =
|
fun getBoolean(key: String, value: Boolean = false) =
|
||||||
(if (isXposedEnvironment)
|
(if (isXposedEnvironment && isUsingNativeStorage.not())
|
||||||
if (isUsingKeyValueCache)
|
if (isUsingKeyValueCache)
|
||||||
XSharedPreferencesCaches.booleanData[key].let {
|
XSharedPreferencesCaches.booleanData[key].let {
|
||||||
it ?: currentXsp.getBoolean(key, value).let { value ->
|
it ?: currentXsp.getBoolean(key, value).let { value ->
|
||||||
@@ -332,7 +352,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
else resetCacheSet { currentXsp.getBoolean(key, value) }
|
else resetCacheSet { currentXsp.getBoolean(key, value) }
|
||||||
else currentSp.getBoolean(key, value)).let {
|
else currentSp.getBoolean(key, value)).let {
|
||||||
makeWorldReadable()
|
makeWorldReadable()
|
||||||
it
|
resetNativeSet { it }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -346,7 +366,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
* @return [Int]
|
* @return [Int]
|
||||||
*/
|
*/
|
||||||
fun getInt(key: String, value: Int = 0) =
|
fun getInt(key: String, value: Int = 0) =
|
||||||
(if (isXposedEnvironment)
|
(if (isXposedEnvironment && isUsingNativeStorage.not())
|
||||||
if (isUsingKeyValueCache)
|
if (isUsingKeyValueCache)
|
||||||
XSharedPreferencesCaches.intData[key].let {
|
XSharedPreferencesCaches.intData[key].let {
|
||||||
it ?: currentXsp.getInt(key, value).let { value ->
|
it ?: currentXsp.getInt(key, value).let { value ->
|
||||||
@@ -357,7 +377,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
else resetCacheSet { currentXsp.getInt(key, value) }
|
else resetCacheSet { currentXsp.getInt(key, value) }
|
||||||
else currentSp.getInt(key, value)).let {
|
else currentSp.getInt(key, value)).let {
|
||||||
makeWorldReadable()
|
makeWorldReadable()
|
||||||
it
|
resetNativeSet { it }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -371,7 +391,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
* @return [Float]
|
* @return [Float]
|
||||||
*/
|
*/
|
||||||
fun getFloat(key: String, value: Float = 0f) =
|
fun getFloat(key: String, value: Float = 0f) =
|
||||||
(if (isXposedEnvironment)
|
(if (isXposedEnvironment && isUsingNativeStorage.not())
|
||||||
if (isUsingKeyValueCache)
|
if (isUsingKeyValueCache)
|
||||||
XSharedPreferencesCaches.floatData[key].let {
|
XSharedPreferencesCaches.floatData[key].let {
|
||||||
it ?: currentXsp.getFloat(key, value).let { value ->
|
it ?: currentXsp.getFloat(key, value).let { value ->
|
||||||
@@ -382,7 +402,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
else resetCacheSet { currentXsp.getFloat(key, value) }
|
else resetCacheSet { currentXsp.getFloat(key, value) }
|
||||||
else currentSp.getFloat(key, value)).let {
|
else currentSp.getFloat(key, value)).let {
|
||||||
makeWorldReadable()
|
makeWorldReadable()
|
||||||
it
|
resetNativeSet { it }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -396,7 +416,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
* @return [Long]
|
* @return [Long]
|
||||||
*/
|
*/
|
||||||
fun getLong(key: String, value: Long = 0L) =
|
fun getLong(key: String, value: Long = 0L) =
|
||||||
(if (isXposedEnvironment)
|
(if (isXposedEnvironment && isUsingNativeStorage.not())
|
||||||
if (isUsingKeyValueCache)
|
if (isUsingKeyValueCache)
|
||||||
XSharedPreferencesCaches.longData[key].let {
|
XSharedPreferencesCaches.longData[key].let {
|
||||||
it ?: currentXsp.getLong(key, value).let { value ->
|
it ?: currentXsp.getLong(key, value).let { value ->
|
||||||
@@ -407,7 +427,7 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
else resetCacheSet { currentXsp.getLong(key, value) }
|
else resetCacheSet { currentXsp.getLong(key, value) }
|
||||||
else currentSp.getLong(key, value)).let {
|
else currentSp.getLong(key, value)).let {
|
||||||
makeWorldReadable()
|
makeWorldReadable()
|
||||||
it
|
resetNativeSet { it }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -617,12 +637,22 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
* @return [T]
|
* @return [T]
|
||||||
*/
|
*/
|
||||||
private inline fun <T> resetCacheSet(result: () -> T): T {
|
private inline fun <T> resetCacheSet(result: () -> T): T {
|
||||||
isUsingKeyValueCache = YukiHookAPI.Configs.isEnableModulePrefsCache
|
isUsingKeyValueCache = YukiHookAPI.Configs.isEnablePrefsBridgeCache
|
||||||
return result()
|
return result()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [YukiHookModulePrefs] 的存储代理类
|
* 恢复 [isUsingNativeStorage] 为默认状态
|
||||||
|
* @param result 回调方法体的结果
|
||||||
|
* @return [T]
|
||||||
|
*/
|
||||||
|
private inline fun <T> resetNativeSet(result: () -> T): T {
|
||||||
|
isUsingNativeStorage = false
|
||||||
|
return result()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [YukiHookPrefsBridge] 的存储代理类
|
||||||
*
|
*
|
||||||
* - ❗请使用 [edit] 方法来获取 [Editor]
|
* - ❗请使用 [edit] 方法来获取 [Editor]
|
||||||
*
|
*
|
||||||
@@ -770,10 +800,10 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
* 提交更改 (同步)
|
* 提交更改 (同步)
|
||||||
* @return [Boolean] 是否成功
|
* @return [Boolean] 是否成功
|
||||||
*/
|
*/
|
||||||
fun commit() = editor?.commit()?.also { makeWorldReadable() } ?: false
|
fun commit() = resetNativeSet { editor?.commit()?.also { makeWorldReadable() } ?: false }
|
||||||
|
|
||||||
/** 提交更改 (异步) */
|
/** 提交更改 (异步) */
|
||||||
fun apply() = editor?.apply().also { makeWorldReadable() } ?: Unit
|
fun apply() = resetNativeSet { editor?.apply().also { makeWorldReadable() } ?: Unit }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 仅在模块环境执行
|
* 仅在模块环境执行
|
||||||
@@ -783,8 +813,8 @@ class YukiHookModulePrefs private constructor(private var context: Context? = nu
|
|||||||
* @return [Editor]
|
* @return [Editor]
|
||||||
*/
|
*/
|
||||||
private inline fun moduleEnvironment(callback: () -> Unit): Editor {
|
private inline fun moduleEnvironment(callback: () -> Unit): Editor {
|
||||||
if (isXposedEnvironment.not()) callback()
|
if (isXposedEnvironment.not() || isUsingNativeStorage) callback()
|
||||||
else yLoggerW(msg = "YukiHookModulePrefs.Editor not allowed in Xposed Environment")
|
else yLoggerW(msg = "YukiHookPrefsBridge.Editor not allowed in Xposed Environment")
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -27,13 +27,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.highcapable.yukihookapi.hook.xposed.prefs.data
|
package com.highcapable.yukihookapi.hook.xposed.prefs.data
|
||||||
|
|
||||||
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookModulePrefs
|
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookPrefsBridge
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 键值对存储构造类
|
* 键值对存储构造类
|
||||||
*
|
*
|
||||||
* 这个类是对 [YukiHookModulePrefs] 的一个扩展用法
|
* 这个类是对 [YukiHookPrefsBridge] 的一个扩展用法
|
||||||
*
|
*
|
||||||
* 详情请参考 [API 文档 - PrefsData](https://fankes.github.io/YukiHookAPI/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/data/PrefsData)
|
* 详情请参考 [API 文档 - PrefsData](https://fankes.github.io/YukiHookAPI/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/prefs/data/PrefsData)
|
||||||
*
|
*
|
||||||
|
@@ -38,7 +38,7 @@ import androidx.preference.PreferenceManager
|
|||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import com.highcapable.yukihookapi.YukiHookAPI
|
import com.highcapable.yukihookapi.YukiHookAPI
|
||||||
import com.highcapable.yukihookapi.hook.utils.unit
|
import com.highcapable.yukihookapi.hook.utils.unit
|
||||||
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookModulePrefs
|
import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookPrefsBridge
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 这是对使用 [YukiHookAPI] Xposed 模块实现中的一个扩展功能
|
* 这是对使用 [YukiHookAPI] Xposed 模块实现中的一个扩展功能
|
||||||
@@ -105,5 +105,5 @@ abstract class ModulePreferenceFragment : PreferenceFragmentCompat(), SharedPref
|
|||||||
private fun makeNewXShareReadableIfPossible() = runCatching {
|
private fun makeNewXShareReadableIfPossible() = runCatching {
|
||||||
@Suppress("DEPRECATION", "WorldReadableFiles")
|
@Suppress("DEPRECATION", "WorldReadableFiles")
|
||||||
currentActivity.getSharedPreferences(prefsName, Context.MODE_WORLD_READABLE)
|
currentActivity.getSharedPreferences(prefsName, Context.MODE_WORLD_READABLE)
|
||||||
}.onFailure { YukiHookModulePrefs.makeWorldReadable(currentActivity, prefsFileName = "$prefsName.xml") }.unit()
|
}.onFailure { YukiHookPrefsBridge.makeWorldReadable(currentActivity, prefsFileName = "$prefsName.xml") }.unit()
|
||||||
}
|
}
|
Reference in New Issue
Block a user