SettingsProvider 之 SqlArguments

本文详细解析了如何通过ContentUri获取数据表名、投影和条件参数等信息,并介绍了SqlArguments类的具体实现细节。

转载请注明出处:http://blog.youkuaiyun.com/droyon/article/details/35558611

SqlArguments

    /**
     * Decode a content URL into the table, projection, and arguments
     * used to access the corresponding database rows.
     */

包装请求的ContentUri,插入的数据表、projection,where cause等。

1、限定请求的url地址
if (url.getPathSegments().size() == 1) {
                // of the form content://settings/secure, arbitrary where clause
2、必须为content://settings/secure/brightness,包含两级pathSegmentselse if (url.getPathSegments().size() != 2) { throw new IllegalArgumentException("Invalid URI: " + url);

SqlArguments(Uri url, String where, String[] args) {
            if (url.getPathSegments().size() == 1) {
                // of the form content://settings/secure, arbitrary where clause
                this.table = url.getPathSegments().get(0);
                if (!DatabaseHelper.isValidTable(this.table)) {
                    throw new IllegalArgumentException("Bad root path: " + this.table);
                }
                this.where = where;
                this.args = args;
            } else if (url.getPathSegments().size() != 2) {
                throw new IllegalArgumentException("Invalid URI: " + url);
            } else if (!TextUtils.isEmpty(where)) {
                throw new UnsupportedOperationException("WHERE clause not supported: " + url);
            } else {
                // of the form content://settings/secure/element_name, no where clause
                this.table = url.getPathSegments().get(0);
                if (!DatabaseHelper.isValidTable(this.table)) {
                    throw new IllegalArgumentException("Bad root path: " + this.table);
                }
                if (TABLE_SYSTEM.equals(this.table) || TABLE_SECURE.equals(this.table) ||
                    TABLE_GLOBAL.equals(this.table)) {
                    this.where = Settings.NameValueTable.NAME + "=?";
                    final String name = url.getPathSegments().get(1);
                    this.args = new String[] { name };
                    // Rewrite the table for known-migrated names
                    if (TABLE_SYSTEM.equals(this.table) || TABLE_SECURE.equals(this.table)) {
                        if (sSecureGlobalKeys.contains(name) || sSystemGlobalKeys.contains(name)) {
                            this.table = TABLE_GLOBAL;
                        }
                    }
                } else {
                    // of the form content://bookmarks/19
                    this.where = "_id=" + ContentUris.parseId(url);
                    this.args = null;
                }
            }
        }

3、where必须为empty
else if (!TextUtils.isEmpty(where)) {
                throw new UnsupportedOperationException("WHERE clause not supported: " + url);
            }
4、
               this.table = url.getPathSegments().get(0);
                if (!DatabaseHelper.isValidTable(this.table)) {
                    throw new IllegalArgumentException("Bad root path: " + this.table);
                }
                if (TABLE_SYSTEM.equals(this.table) || TABLE_SECURE.equals(this.table) ||
                    TABLE_GLOBAL.equals(this.table)) {
                    this.where = Settings.NameValueTable.NAME + "=?";
                    final String name = url.getPathSegments().get(1);
                    this.args = new String[] { name };
                    // Rewrite the table for known-migrated names
                    if (TABLE_SYSTEM.equals(this.table) || TABLE_SECURE.equals(this.table)) {
                        if (sSecureGlobalKeys.contains(name) || sSystemGlobalKeys.contains(name)) {//更改table名
                            this.table = TABLE_GLOBAL;
                        }
                    }
                } else {
                    // of the form content://bookmarks/19
                    this.where = "_id=" + ContentUris.parseId(url);
                    this.args = null;
                }


<think>我们正在讨论Unity SettingsProvider的使用方法。SettingsProvider是Unity Editor中的一个重要功能,它允许开发者创建自定义的设置窗口,将项目相关的配置集中管理。根据Unity文档,SettingsProvider通常用于Project Settings或Preferences窗口中。 步骤指南: 1. 创建SettingsProvider类:需要继承自SettingsProvider类,并实现相应的回调方法。 2. 注册SettingsProvider:使用[SettingsProvider]属性或SettingsProvider.GetSettingsProviders()来注册。 3. 绘制GUI:在OnGUI或CreateProvider中使用GUI绘制设置界面。 下面是一个简单的示例,创建一个名为"MyCustomSettings"的设置页面: ```csharp using UnityEditor; using UnityEngine; public class MyCustomSettingsProvider : SettingsProvider { // 使用序列化对象来存储设置 private SerializedObject m_CustomSettings; private static MyCustomSettings _settings; // 构造函数,指定路径和范围(ProjectSettings或Preferences) public MyCustomSettingsProvider(string path, SettingsScope scope = SettingsScope.Project) : base(path, scope) { } // 在设置界面被激活时调用 public override void OnActivate(string searchContext, UnityEngine.UIElements.VisualElement rootElement) { // 确保设置对象存在 if (_settings == null) { _settings = MyCustomSettings.GetOrCreateSettings(); } m_CustomSettings = new SerializedObject(_settings); } // 绘制设置界面 public override void OnGUI(string searchContext) { // 开始绘制 EditorGUILayout.LabelField("My Custom Settings", EditorStyles.boldLabel); EditorGUILayout.PropertyField(m_CustomSettings.FindProperty("someProperty")); // 应用修改 if (m_CustomSettings.ApplyModifiedProperties()) { // 保存设置 MyCustomSettings.SaveSettings(_settings); } } // 注册设置提供者 [SettingsProvider] public static SettingsProvider CreateMyCustomSettingsProvider() { var provider = new MyCustomSettingsProvider("Project/My Custom Settings", SettingsScope.Project); // 可以在这里设置关键字,用于搜索 provider.keywords = GetSearchKeywordsFromGUIContentProperties<MyCustomSettings>(); return provider; } } // 自定义设置数据类,通常使用ScriptableObject来存储 public class MyCustomSettings : ScriptableObject { public int someProperty = 0; private static MyCustomSettings _instance; public static MyCustomSettings GetOrCreateSettings() { if (_instance == null) { // 尝试加载已有的设置 _instance = AssetDatabase.LoadAssetAtPath<MyCustomSettings>("Assets/Editor/MyCustomSettings.asset"); if (_instance == null) { _instance = CreateInstance<MyCustomSettings>(); AssetDatabase.CreateAsset(_instance, "Assets/Editor/MyCustomSettings.asset"); AssetDatabase.SaveAssets(); } } return _instance; } public static void SaveSettings(MyCustomSettings settings) { EditorUtility.SetDirty(settings); AssetDatabase.SaveAssets(); } } ``` 说明: 1. 我们创建了一个`MyCustomSettingsProvider`类,继承自`SettingsProvider`。 2. 在`OnActivate`中,我们初始化设置对象(这里使用ScriptableObject存储)。 3. 在`OnGUI`中,我们绘制设置界面,并使用`SerializedObject`来支持撤销和序列化。 4. 通过`[SettingsProvider]`属性静态方法注册提供者。 5. 设置数据保存在一个ScriptableObject中,放置在Assets/Editor目录下。 注意: - 设置的范围(Scope)可以是`SettingsScope.Project`(项目设置)或`SettingsScope.User`(用户偏好设置,即Preferences)。 - 对于用户偏好设置,通常不需要保存为资产,可以使用EditorPrefs或其他方式存储。 另外,Unity还提供了`SettingsProvider.GetSettingsProviders()`方法,可以在运行时动态添加设置提供者,但通常使用属性注册更简便。 更多高级用法,如使用UI Toolkit绘制界面,可以参考Unity官方文档[^2]。 请确保将设置提供者脚本放在Editor文件夹中。 如果您需要将设置同时显示在Project Settings和Preferences中,可以创建两个不同的提供者,分别指定不同的路径和范围。 相关问题: §§相关问题§§ 1. 如何在Unity中创建用户偏好设置(Preferences)? 2. SettingsProvider如何使用UI Toolkit绘制界面? 3. 如何将自定义设置保存为可共享的配置文件?</think>### Unity SettingsProvider 使用指南 SettingsProvider 是 Unity Editor 扩展的核心功能,允许开发者在 Unity 编辑器的 **Project Settings** 或 **Preferences** 窗口中创建自定义设置面板。以下是完整使用指南: #### 一、基础使用步骤 1. **创建 SettingsProvider 类** ```csharp using UnityEditor; using UnityEngine; public class CustomSettingsProvider : SettingsProvider { // 构造函数指定设置位置 public CustomSettingsProvider(string path, SettingsScope scope = SettingsScope.Project) : base(path, scope) { } // 核心方法:绘制设置界面 public override void OnGUI(string searchContext) { EditorGUILayout.LabelField("自定义设置", EditorStyles.boldLabel); EditorGUILayout.Space(); // 示例:添加设置字段 EditorPrefs.SetInt("MySetting", EditorGUILayout.IntField("数值设置", EditorPrefs.GetInt("MySetting", 0))); } // 注册提供者(关键步骤) [SettingsProvider] public static SettingsProvider CreateProvider() { return new CustomSettingsProvider( "Project/Custom Settings", // 在Project Settings中的路径 SettingsScope.Project // 作用域(项目/用户) ); } } ``` 2. **作用域说明** - `SettingsScope.Project`:存储在 **ProjectSettings** 文件夹(项目共享) - `SettingsScope.User`:存储在用户偏好中(编辑器 → Preferences) 3. **数据存储位置** ```csharp // 项目级存储(推荐) ProjectSettings/MyCustomSettings.asset // 用户级存储 EditorPrefs.SetInt("UserSetting", 123); ``` #### 二、高级功能实现 1. **搜索功能支持** ```csharp public override void OnGUI(string searchContext) { if (!string.IsNullOrEmpty(searchContext) && !this.path.Contains(searchContext)) return; // 过滤非匹配项 // ...绘制设置项 } ``` 2. **序列化对象存储** ```csharp private SerializedObject m_Settings; public override void OnActivate(string searchContext, VisualElement root) { // 加载或创建ScriptableObject m_Settings = new SerializedObject(MySettings.GetOrCreate()); } public override void OnGUI(string searchContext) { SerializedProperty prop = m_Settings.FindProperty("m_Data"); EditorGUILayout.PropertyField(prop); m_Settings.ApplyModifiedProperties(); } ``` 3. **多语言支持** ```csharp [InitializeOnLoad] public static class Localization { static Localization() { L10n.Tr("Custom Settings"); // 注册可翻译文本 } } ``` #### 三、最佳实践 1. **目录结构建议** ``` Assets/ └── Editor/ ├── Settings/ │ ├── CustomSettingsProvider.cs │ └── MySettings.asset // ScriptableObject数据 ``` 2. **调试技巧** - 使用 `EditorWindow.GetWindow<SettingsService>()` 查看注册状态 - 通过 `[MenuItem("Window/Refresh Settings")]` 强制刷新 3. **注意事项** - 脚本必须放在 **Editor 文件夹** - 修改后需重启 Unity 使新设置生效 - 使用 `SettingsProvider.GetSettingsProviders()` 动态注册 完整文档参考 Unity 官方手册:[SettingsProvider API](https://docs.unity3d.com/ScriptReference/SettingsProvider.html) [^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hailushijie

您的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值