diff --git a/Runtime/GuruCore/Runtime/Analytics/Analytics.cs b/Runtime/GuruCore/Runtime/Analytics/Analytics.cs
index 3654715..68e83c2 100644
--- a/Runtime/GuruCore/Runtime/Analytics/Analytics.cs
+++ b/Runtime/GuruCore/Runtime/Analytics/Analytics.cs
@@ -12,8 +12,8 @@ namespace Guru
 		public class EventSetting
 		{
 			public bool EnableFirebaseAnalytics;
-			public bool EnableFacebookAnalytics;
 			public bool EnableAdjustAnalytics;
+			public bool EnableFacebookAnalytics;
 		}
 
 		private static EventSetting _defaultEventSetting;
@@ -142,16 +142,16 @@ namespace Guru
 			{
 				FirebaseAnalytics.LogEvent(eventName);
 			}
+			
+			if (eventSetting.EnableAdjustAnalytics)
+			{
+				Adjust.trackEvent(CreateAdjustEvent(eventName));
+			}
 
 			if (eventSetting.EnableFacebookAnalytics)
 			{
 				FB.LogAppEvent(eventName);
 			}
-
-			if (eventSetting.EnableAdjustAnalytics)
-			{
-				Adjust.trackEvent(CreateAdjustEvent(eventName));
-			}
 		}
 
 		/// 
@@ -191,11 +191,6 @@ namespace Guru
 			}
 
 			Dictionary dict = new Dictionary(extras);
-			if (eventSetting.EnableFacebookAnalytics)
-			{
-				FB.LogAppEvent(eventName, null, dict);
-			}
-
 			if (eventSetting.EnableAdjustAnalytics)
 			{
 				AdjustEvent adjustEvent = Analytics.CreateAdjustEvent(eventName);
@@ -208,6 +203,11 @@ namespace Guru
 					Adjust.trackEvent(adjustEvent);
 				}
 			}
+			
+			if (eventSetting.EnableFacebookAnalytics)
+			{
+				FB.LogAppEvent(eventName, null, dict);
+			}
 		}
 
 		#endregion
diff --git a/Runtime/GuruCore/Runtime/Settings/GuruSettings.cs b/Runtime/GuruCore/Runtime/Settings/GuruSettings.cs
index 41cd4b0..b7f1425 100644
--- a/Runtime/GuruCore/Runtime/Settings/GuruSettings.cs
+++ b/Runtime/GuruCore/Runtime/Settings/GuruSettings.cs
@@ -28,7 +28,7 @@ namespace Guru
 		[Header("产品包名")]
 		public string GameIdentifier = "com.guru.default.product";
 		[Header("产品反馈邮箱(评分反馈邮箱)")]
-		public string SupportEmail =  "xxxx@fungame.studio";
+		public string SupportEmail =  "test@fungame.studio";
 		[Header("隐私协议URL")]
 		public string PriacyUrl = "";
 		[Header("服务条款URL")]
@@ -52,6 +52,45 @@ namespace Guru
 		{
 			return Resources.Load("GuruSettings");
 		}
+		/// 
+		/// 运行时更新Adjust 的 AppToken
+		/// 
+		/// 
+		/// 
+		public void UpdateAdjustTokens(string androidToken, string iosToken)
+		{
+			if(!string.IsNullOrEmpty(androidToken))
+				AdjustSetting.androidAppToken = androidToken;
+			if(!string.IsNullOrEmpty(iosToken))
+				AdjustSetting.iOSAppToken = iosToken;
+		}
+
+		/// 
+		/// 运行时更新 Adjust 的事件列表
+		/// 
+		public void UpdateAdjustEvents(IList events)
+		{
+			if (events != null && events.Count > 0)
+			{
+				List evtList = new List(events.Count);
+				string key, atk, itk;
+				string[] tmp;
+				for (int i = 0; i < events.Count; i++)
+				{
+					tmp = events[i].Split(',');
+					if (tmp != null && tmp.Length > 2)
+					{
+						evtList.Add(new AnalyticsSetting.AdjustEvent()
+						{
+							EventName = tmp[0],
+							AndroidToken = tmp[1],
+							IOSToken = tmp[2],
+						});
+					}
+				}
+				AnalyticsSetting.adjustEventList = evtList;
+			}
+		}
 	}
 	
 	[Serializable]
@@ -73,7 +112,7 @@ namespace Guru
 		[SerializeField] private bool enalbeFirebaseAnalytics = true;
 		[SerializeField] private bool enalbeFacebookAnalytics = true;
 		[SerializeField] private bool enalbeAdjustAnalytics = true;
-		[SerializeField] private List adjustEventList;
+		[SerializeField] internal List adjustEventList;
 
 		public int LevelEndSuccessNum => levelEndSuccessNum;
 		public bool EnalbeFirebaseAnalytics => enalbeFirebaseAnalytics;
@@ -132,8 +171,8 @@ namespace Guru
 	[Serializable]
 	public class AdjustSetting
 	{
-		[SerializeField] private string androidAppToken;
-		[SerializeField] private string iOSAppToken;
+		[SerializeField] internal string androidAppToken;
+		[SerializeField] internal string iOSAppToken;
 
 		public string AndroidAppToken => androidAppToken;
 		public string IOSAppToken => iOSAppToken;
diff --git a/Runtime/GuruRating.meta b/Runtime/GuruRating.meta
new file mode 100644
index 0000000..3c1c4c7
--- /dev/null
+++ b/Runtime/GuruRating.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 53abb1f4e73b4b44907c0a3c0a406079
+timeCreated: 1687327402
\ No newline at end of file
diff --git a/Runtime/GuruRating/README.md b/Runtime/GuruRating/README.md
new file mode 100644
index 0000000..84845a4
--- /dev/null
+++ b/Runtime/GuruRating/README.md
@@ -0,0 +1,45 @@
+# Guru 评价管理器
+
+Version 0.1.0
+
+## 简介
+
+Guru 评价管理器内置了多平台评价管理实现, 包括
+- GooglePlay 平台的 InAppReview 接口 
+- AppStore 平台的评价接口
+
+
+## 库依赖
+
+### **Android**
+
+- 依赖于 `com.google.play.review` 的插件, 可在插件的 Package 文件夹内直接安装
+- 注意: 由于模板已集成 ExternalDependencyManager (`1.2.174`), 因此无需导入包内的EDM插件.
+
+
+### **iOS**
+
+- 直接使用 Unity 内部的 `iOS` 的 Review 接口
+
+## 实现方式
+
+### 显示评价
+
+只需调用以下代码即可:
+
+```C#
+// 直接显示包内的评价界面
+GuruRating.ShowRating();
+```
+
+
+### 提交反馈
+    
+- 发送反馈时, 实际上是调用了系统的邮件App, 需要提供收件人的邮箱地址
+- 邮件的标题主体可以自由定制, 传入参数即可
+
+```C#
+// 向 support@fungame.com 的邮箱发送反馈信息. 邮件的标题和信息可以定制
+GuruRating.SetEmailFeedback("support@fungame.com", "Thank you for the feedback!");
+```
+
diff --git a/Runtime/GuruRating/README.md.meta b/Runtime/GuruRating/README.md.meta
new file mode 100644
index 0000000..1533867
--- /dev/null
+++ b/Runtime/GuruRating/README.md.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 6fd1be4cf92d4854b9fad97b1bd11b7b
+timeCreated: 1687327432
\ No newline at end of file
diff --git a/Runtime/GuruRating/Runtime.meta b/Runtime/GuruRating/Runtime.meta
new file mode 100644
index 0000000..8d80042
--- /dev/null
+++ b/Runtime/GuruRating/Runtime.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: d608c1853fbb4c4e9538d1af2ee2c65e
+timeCreated: 1687327422
\ No newline at end of file
diff --git a/Runtime/GuruRating/Runtime/Code.meta b/Runtime/GuruRating/Runtime/Code.meta
new file mode 100644
index 0000000..84d8fc7
--- /dev/null
+++ b/Runtime/GuruRating/Runtime/Code.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: b3f63a18067c45da82d3521e18127a88
+timeCreated: 1687328000
\ No newline at end of file
diff --git a/Runtime/GuruRating/Runtime/Code/GuruRating.cs b/Runtime/GuruRating/Runtime/Code/GuruRating.cs
new file mode 100644
index 0000000..8c20898
--- /dev/null
+++ b/Runtime/GuruRating/Runtime/Code/GuruRating.cs
@@ -0,0 +1,188 @@
+namespace Guru
+{
+    using System;
+#if UNITY_ANDROID
+    using Google.Play.Review;
+#endif
+
+#if UNITY_IOS
+    using UnityEngine.iOS;
+#endif
+    using UnityEngine;
+    using UnityEngine.Networking;
+    
+    /// 
+    /// 评价管理器
+    /// 
+    public class GuruRating: Singleton
+    {
+
+        public static bool ShowLog { get; set; } = false;
+
+        #region 初始化
+
+        protected override void Init()
+        {
+            base.Init();
+        }
+
+        #endregion
+        
+        #region 评价显示
+        
+#if UNITY_ANDROID
+
+        private bool _isOnRating = false;
+        /// 
+        /// 显示Google的评价
+        /// 
+        private void ShowGoogleRating()
+        {
+            if (_isOnRating) return;
+            _isOnRating = true;
+            OnGoogleRating();
+        }
+        
+        /// 
+        /// 启动Google评价流程
+        /// 
+        private void OnGoogleRating()
+        {
+            ReviewManager rm = new ReviewManager();
+            rm.RequestReviewFlow().Completed += pao =>
+            {
+                // 请求 PlayReviewInfo 对象
+                if (pao.Error != ReviewErrorCode.NoError)
+                {
+                    if(ShowLog) Debug.Log($"ReviewInfo Error: {pao.Error.ToString()}");
+                    OnGoogleRatingResult(false);
+                }
+                else
+                {
+                    // 启动应用内评价流程, 调用后可以不用关心后继的结果. 游戏继续流程即可
+                    rm.LaunchReviewFlow(pao.GetResult()).Completed += lao =>
+                    {
+                        bool result = true;
+                        if (lao.Error != ReviewErrorCode.NoError)
+                        {
+                            if(ShowLog) Debug.Log($"LaunchReview Error: {lao.Error.ToString()}");
+                            result = false;
+                        }
+                        OnGoogleRatingResult(result);
+                        rm = null;
+                    };
+                }
+            };
+        }
+
+        private void OnGoogleRatingResult(bool success)
+        {
+            // On getting review result
+            if(ShowLog) Debug.Log($"Google Review flow ends, result: {success}");
+            _isOnRating = false;
+        }
+
+#endif
+        
+#if UNITY_IOS
+        /// 
+        /// 显示苹果的Rating
+        /// 
+        private void ShowAppleRating() => Device.RequestStoreReview();  // 显示苹果的评价面板
+#endif
+        
+        #endregion
+
+        #region 发送邮件
+
+        /// 
+        /// 设置邮件显示
+        /// 
+        /// 
+        /// 
+        private void SendEmail(string email, string subject = "", string body = null)
+        {
+            if (string.IsNullOrEmpty(subject)) subject = GetDefaultMailTitle();
+            if (string.IsNullOrEmpty(body)) body = GetDefaultMailBody();
+            
+            string url = $"mailto:{email}&subject={EscapeUrl(subject)}&body={EscapeUrl(body)}";
+            Application.OpenURL(url);
+        }
+        
+        /// 
+        /// 获取默认的邮件标题
+        /// 
+        /// 
+        private string GetDefaultMailTitle()
+        {
+            return $"Some suggestions for improving {GuruSettings.Instance.ProductName}";
+        }
+        
+        /// 
+        /// 获取默认的邮件内容模版
+        /// 
+        private string GetDefaultMailBody()
+        {
+            string body = "Please Enter your message here\n\n\n\n" +
+                          "________" +
+                          "\n\nPlease Do Not Modify This\n\n" +
+                          "Game: " + GuruSettings.Instance.ProductName + "\n\n" +
+                          "Model: " + SystemInfo.deviceModel + "\n\n" +
+                          "OS: " + SystemInfo.operatingSystem + "\n\n" +
+                          "UserId: " + IPMConfig.IPM_UID + "\n\n" +
+                          "Version: " + Application.version + "\n\n" +
+                          "________";
+            return body;
+        }
+
+
+
+        #endregion
+        
+        #region 工具接口
+
+        /// 
+        /// 转换为URL编码
+        /// 
+        /// 
+        /// 
+        public static string EscapeUrl(string str)
+        {
+            return UnityWebRequest.EscapeURL(str).Replace("+", "%20");
+        }
+        
+        
+
+        #endregion
+
+        #region 公开接口
+
+        /// 
+        /// 显示评价面板
+        /// 
+        public static void ShowRating()
+        {
+#if UNITY_EDITOR
+            Console.WriteLine($"Editor is Calling ShowRating api...");
+#elif UNITY_ANDROID
+            Instance.ShowGoogleRating();
+#elif UNITY_IOS
+            Instance.ShowAppleRating();
+#endif
+        }
+
+
+        /// 
+        /// 设置邮件反馈
+        /// 
+        /// 
+        /// 
+        public static void SetEmailFeedback(string email, string subject = "", string body = "")
+        {
+            Instance.SendEmail(email, subject, body);
+        }
+        
+        #endregion
+        
+    }
+}
\ No newline at end of file
diff --git a/Runtime/GuruRating/Runtime/Code/GuruRating.cs.meta b/Runtime/GuruRating/Runtime/Code/GuruRating.cs.meta
new file mode 100644
index 0000000..2543cd0
--- /dev/null
+++ b/Runtime/GuruRating/Runtime/Code/GuruRating.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 8d36e44d41f0423f8f9f6c23600ec512
+timeCreated: 1687328021
\ No newline at end of file
diff --git a/Runtime/GuruRemote/Runtime/IRemoteConfig.cs b/Runtime/GuruRemote/Runtime/IRemoteConfig.cs
index a20bf3d..cc4d018 100644
--- a/Runtime/GuruRemote/Runtime/IRemoteConfig.cs
+++ b/Runtime/GuruRemote/Runtime/IRemoteConfig.cs
@@ -1,5 +1,3 @@
-using Google;
-
 namespace Guru
 {
     using System;
@@ -7,21 +5,10 @@ namespace Guru
     /// 
     /// 运控配置接口类
     /// 
-    public interface IRemoteConfig
+    public interface IRemoteConfig where T : IRemoteConfig
     {
         bool enable { get; set; }
-        string key { get; }
-        string value { get; }
-
-        Action OnValueChanged { get; set; }
-
-        void Init();
+        Action OnValueChanged { get; set; } 
         string ToJson();
-        string GetDefaultValue();
-        string GetRemoteValue();
-
-        void GetRemoteJsonAsync(Action onValueLoaded);
-        
-
     }
 }
\ No newline at end of file
diff --git a/Runtime/GuruRemote/Runtime/RemoteConfigBase.cs b/Runtime/GuruRemote/Runtime/RemoteConfigBase.cs
index 023f3e3..7059290 100644
--- a/Runtime/GuruRemote/Runtime/RemoteConfigBase.cs
+++ b/Runtime/GuruRemote/Runtime/RemoteConfigBase.cs
@@ -1,45 +1,20 @@
-using System;
-
 namespace Guru
 {
-    public abstract class RemoteConfigBase: IRemoteConfig
+    using System;
+    
+    public abstract class RemoteConfigBase: IRemoteConfig where T : IRemoteConfig
     {
-        
         /// 
         /// 配置是否可用
         /// 
         public bool enable { get; set; } = true;
-
-        public virtual string key { get; } = "remote-config-base";
-        public virtual string value { get; } = "{ \"enable\": true }";
-        public Action OnValueChanged { get; set; }
-
-
-        public void Init()
-        {
-            
-        }
-
+        public Action OnValueChanged { get; set; }
         /// 
         /// 转为Json
         /// 
         /// 
-        public virtual string ToJson()
-            => JsonParser.ToJson(this);
-
-        public string GetDefaultValue()
-        {
-            throw new NotImplementedException();
-        }
-
-        public string GetRemoteValue()
-        {
-            throw new NotImplementedException();
-        }
-
-        public void GetRemoteJsonAsync(Action onValueLoaded)
-        {
-            throw new NotImplementedException();
-        }
+        public virtual string ToJson() => JsonParser.ToJson(this);
+        
+        
     }
 }
\ No newline at end of file
diff --git a/Runtime/GuruRemote/Runtime/RemoteConfigManager.cs b/Runtime/GuruRemote/Runtime/RemoteConfigManager.cs
index ed6aae4..1b26dbc 100644
--- a/Runtime/GuruRemote/Runtime/RemoteConfigManager.cs
+++ b/Runtime/GuruRemote/Runtime/RemoteConfigManager.cs
@@ -1,9 +1,11 @@
-using System.Collections.Generic;
-using System.Linq;
+
 
 namespace Guru
 {
     using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using JetBrains.Annotations;
     using UnityEngine;
     using Firebase.RemoteConfig;
     using Firebase.Extensions;
@@ -13,31 +15,29 @@ namespace Guru
     /// 
     public class RemoteConfigManager
     {
-        public const double DefaultUpdateHours = 12;
-        private const string Tag = "[Remote]";
+        public const double DefaultUpdateHours = 2;
+        public const double DefaultFetchTimeout = 15;
+        internal const string Tag = "[Remote]";
         private static bool _initOnce = false;
         private static RemoteConfigManager _instance;
         public static RemoteConfigManager Instance => _instance ??= new RemoteConfigManager();
         
         private FirebaseRemoteConfig _firebaseRemote;
         private static bool _isDebug = false;
-        private static double _updateHours = DefaultUpdateHours;
+        private static double _fetchIntervalHours = DefaultUpdateHours;
 
         private RemoteConfigModel _model;
-
-        internal RemoteConfigModel Model
-        {
-            get
-            {
-                if(_model == null) _model = RemoteConfigModel.LoadOrCreate();
-                return _model;
-            }
-        }
-        private Dictionary _defaults;
+        internal RemoteConfigModel Model => _model ??= RemoteConfigModel.LoadOrCreate();
+        
+        private static Dictionary _defaultValues;
 
         public static event Action OnFetchCompleted;
+
+        private Dictionary> _changeEvents;
+
+        private Dictionary _staticValues;
         
-        public static void Init(Dictionary defaults, double updateHours = DefaultUpdateHours, bool isDebug = false)
+        public static void Init(Dictionary defaults = null, double updateHours = DefaultUpdateHours, bool isDebug = false)
         {
             if (_initOnce) return;
             Instance.InitAssets(defaults, updateHours, isDebug);
@@ -45,19 +45,23 @@ namespace Guru
         
         // 拉取所有的线上配置数据
         // onFetchComplete 传参 true: 拉取成功   false: 拉取失败
-        public static void FetchAll(Action onFetchComplete = null)
+        public static void FetchAll(bool immediately = false)
         {
-            OnFetchCompleted += onFetchComplete;
-            if (!_initOnce) Init(null, _updateHours, _isDebug);
-            Instance.FetchAllConfigs();
+            if (!_initOnce) Init(null, _fetchIntervalHours, _isDebug);
+            Instance.FetchAllConfigs(immediately);
+        }
+
+        public static void AddDefaultValues(Dictionary dict)
+        {
+            if (!_initOnce) return;
+            Instance.AppendDefaultValues(dict);
         }
 
         #region 初始化
 
-        private void InitAssets(Dictionary defaults, double updateHours = DefaultUpdateHours, bool isDebug = false)
+        private void InitAssets(Dictionary defaults = null, double updateHours = DefaultUpdateHours, bool isDebug = false)
         {
-            _defaults = defaults;
-            _updateHours = updateHours;
+            _fetchIntervalHours = updateHours;
             _isDebug = isDebug;
             _firebaseRemote = FirebaseRemoteConfig.DefaultInstance;
             if (_firebaseRemote == null)
@@ -65,37 +69,46 @@ namespace Guru
                 LogE("Can't find FirebaseRemoteConfig.DefaultInstance, init failed.");
                 return;
             }
-      
             
-            if (_defaults != null)
+            // 设置默认配置
+            _firebaseRemote.SetConfigSettingsAsync(new ConfigSettings()
             {
-                _firebaseRemote.SetDefaultsAsync(_defaults);
-            }
+                FetchTimeoutInMilliseconds = (ulong)(DefaultFetchTimeout * 1000),
+                MinimumFetchInternalInMilliseconds = (ulong)(_fetchIntervalHours * 60 * 60 * 1000)
+            });
+
+            // 设置默认值
+            AppendDefaultValues(defaults);
             _initOnce = true;
             
+            // 监听事件合集
+            _changeEvents = new Dictionary>(30);
+            
             FetchAllConfigs();
         }
-        
-        
-        
 
-        // private void OnConfigUpdateListener()
-        // {
-        //     if (evt.Error == RemoteConfigError.None)
-        //     {
-        //         LogI($"------- Config Update -------");
-        //         var list = evt.UpdatedKeys.ToArray();
-        //         for (int i = 0; i < list.Length; i++)
-        //         {
-        //             LogI($"[{i}] : {list[i]}");
-        //         }
-        //     }
-        // }
-
-
-        private void FetchAllConfigs()
+        private void AppendDefaultValues(Dictionary defaults)
         {
-            var span = _isDebug? TimeSpan.Zero : TimeSpan.FromHours(_updateHours);
+            if (defaults != null)
+            {
+                if(_defaultValues == null) _defaultValues = new Dictionary(20);
+                string key;
+                object value;
+                for(int i = 0; i < defaults.Keys.Count; i++)
+                {
+                    key = defaults.Keys.ElementAt(i);
+                    value = defaults.Values.ElementAt(i);
+                    _defaultValues[key] = value;
+                }
+                _firebaseRemote?.SetDefaultsAsync(_defaultValues);
+            }
+        }
+
+
+        private void FetchAllConfigs(bool immediately = false)
+        {
+            var span = TimeSpan.FromHours(_fetchIntervalHours);
+            if(_isDebug || immediately) span = TimeSpan.Zero;
             _firebaseRemote.FetchAsync(span)
                 .ContinueWithOnMainThread(task =>
                 {
@@ -106,6 +119,9 @@ namespace Guru
                         LogE($" --- FetchAllConfigs fails: {res}");
                         success = false;
                     }
+
+                    if (success) OnFetchDataCompleted();
+                    
                     OnFetchCompleted?.Invoke(success);
                 });
         }
@@ -113,6 +129,59 @@ namespace Guru
 
         #endregion
 
+        #region Model
+        
+        /// 
+        /// 判断是否为 Config 参数
+        /// 
+        /// 
+        /// 
+        private bool IsRemoteConfigStr(string rawStr)
+        {
+            if (string.IsNullOrEmpty(rawStr)) return false;
+            
+            if (rawStr.TrimStart().StartsWith("{") 
+                && rawStr.TrimEnd().EndsWith("}") 
+                && rawStr.Contains("\"enable\":"))
+            {
+                return true;
+            }
+            return false;
+        }
+        
+        /// 
+        /// 拉取成功
+        /// 
+        private void OnFetchDataCompleted()
+        {
+            var values = _firebaseRemote.AllValues;
+            var updates = new Dictionary(values.Count);
+            var configs = new Dictionary(values.Count);
+            ConfigValue value;
+            string key, str;
+            for (int i = 0; i < values.Keys.Count; i++)
+            {
+                key = values.Keys.ElementAt(i);
+                value = values.Values.ElementAt(i);
+                str = value.StringValue;
+
+                updates[key] = str;
+                if (IsRemoteConfigStr(str))
+                {
+                    configs[key] = str;
+                }
+            }
+
+            if (configs.Count > 0)
+            {
+                Model.UpdateConfigs(configs);
+            }
+
+            DispatchUpdateValues(updates);
+        }
+        
+        #endregion
+        
         #region 数据接口
 
         public string GetStringValue(string key, string defaultValue = "")
@@ -185,7 +254,7 @@ namespace Guru
             {
                 try
                 {
-                    return _firebaseRemote.GetValue(key).BooleanValue;
+                    return _firebaseRemote?.GetValue(key).BooleanValue ?? defaultValue;
                 }
                 catch (Exception e)
                 {
@@ -195,9 +264,35 @@ namespace Guru
             return defaultValue;
         }
 
+        /// 
+        /// 获取全部值
+        /// 
+        /// 
+        public static Dictionary GetAllValues()
+        {
+            try
+            {
+                return (Dictionary)(Instance._firebaseRemote?.AllValues ?? null);
+            }
+            catch (Exception e)
+            {
+                LogException(e);
+            }
+            return null;
+        }
+
+        [CanBeNull]
+        public static string GetStaticValue(string key)
+        {
+            if (Instance._staticValues != null && Instance._staticValues.TryGetValue(key, out var value))
+            {
+                return value;
+            }
+            return null;
+        }
+
         #endregion
         
-        
         #region 云控值获取
 
         public static string GetString(string key, string defaultValue = "")
@@ -232,14 +327,132 @@ namespace Guru
 
         #endregion
         
-        
         #region 云控配置获取
 
-        
+        /// 
+        /// 注册云控配置对象
+        /// 
+        /// 
+        /// 
+        public static void RegisterConfig(string key, string defaultJson)
+        {
+            Instance.Model.SetDefaultConfig(key, defaultJson); // 配置默认值
+        }
+
+
+        /// 
+        /// 获取云控配置
+        /// 
+        /// 
+        /// 
+        /// 
+        public static T GetConfig(string key) where T : IRemoteConfig
+        {
+            var config = Instance.Model.Get(key);
+            return config;
+        }
 
 
 
         #endregion
+
+        #region 监听云控值变化
+
+        /// 
+        /// 注册值变化事件
+        /// 
+        /// 
+        /// 
+        public static void RegisterOnValueChanged(string key, Action onValueChanged)
+        {
+            Instance.AddOnValueChangeListener(key, onValueChanged);
+        }
+        /// 
+        /// 取消注册值变化事件
+        /// 
+        /// 
+        /// 
+        public static void UnRegisterOnValueChanged(string key, Action onValueChanged)
+        {
+            Instance.RemoveOnValueChangeListener(key, onValueChanged);
+        }
+
+
+        private void AddOnValueChangeListener(string key, Action onValueChanged)
+        {
+            if (_changeEvents == null) _changeEvents = new Dictionary>(30);
+
+            if (HasOnValueChangeListener(key))
+            {
+                _changeEvents[key] += onValueChanged;
+            }
+            else
+            {
+                _changeEvents[key] = onValueChanged;
+            }
+        }
+        
+        private void RemoveOnValueChangeListener(string key, Action onValueChanged)
+        {
+            if (_changeEvents != null && HasOnValueChangeListener(key))
+            {
+                _changeEvents[key] -= onValueChanged;
+            }
+        }
+
+        private bool HasOnValueChangeListener(string key)
+        {
+            if (_changeEvents != null)
+            {
+                return _changeEvents.ContainsKey(key);
+            }
+
+            return false;
+        }
+
+
+        private void DispatchUpdateValues(Dictionary updates)
+        {
+            Dictionary changes = new Dictionary(updates.Count);
+
+            if (_staticValues == null) _staticValues = new Dictionary();
+
+            string key, value;
+            for (int i = 0; i < updates.Keys.Count; i++)
+            {
+                key = updates.Keys.ElementAt(i);
+                value = updates.Values.ElementAt(i);
+
+                if (_staticValues.TryGetValue(key, out var oldValue))
+                {
+                    if (oldValue != updates[key] && _changeEvents.ContainsKey(key))
+                    {
+                        changes[key] = value;
+                    }
+                }
+                else
+                {
+                    changes[key] = value;
+                }
+            }
+            
+            // --------- 发送值变化事件 ------------
+            for (int i = 0; i < changes.Keys.Count; i++)
+            {
+                key = updates.Keys.ElementAt(i);
+                value = updates.Values.ElementAt(i);
+
+                if (_changeEvents.TryGetValue(key, out var callback))
+                {
+                    callback?.Invoke(key, value);
+                }
+            }
+            _staticValues = updates;
+        }
+
+
+        #endregion
+        
         
         #region Log
 
diff --git a/Runtime/GuruRemote/Runtime/RemoteConfigModel.cs b/Runtime/GuruRemote/Runtime/RemoteConfigModel.cs
index abee9d4..19d8ad9 100644
--- a/Runtime/GuruRemote/Runtime/RemoteConfigModel.cs
+++ b/Runtime/GuruRemote/Runtime/RemoteConfigModel.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using UnityEngine;
 
 namespace Guru
@@ -12,7 +13,7 @@ namespace Guru
     {
         private static float SaveInterval = 2f;
         private const string SaveKey = "comr.guru.remote.model.save";
-        public Dictionary Data;
+        public Dictionary configs;
         public long last_modified = 0;
 
         private float _lastSavedTime = 0;
@@ -37,7 +38,7 @@ namespace Guru
         /// 
         /// 默认赋值数据
         /// 
-        private Dictionary _defaultData;
+        private Dictionary _defConfigs;
 
         /// 
         /// 加载数据
@@ -70,8 +71,8 @@ namespace Guru
         /// 
         public RemoteConfigModel()
         {
-            _defaultData = new Dictionary(20);
-            Data = new Dictionary(20);
+            _defConfigs = new Dictionary(20);
+            configs = new Dictionary(20);
         }
 
         /// 
@@ -79,7 +80,7 @@ namespace Guru
         /// 
         /// 
         /// 
-        public bool HasKey(string key) => Data.ContainsKey(key);
+        public bool HasKey(string key) => configs.ContainsKey(key);
 
         /// 
         /// 保存数据
@@ -100,13 +101,12 @@ namespace Guru
         /// 
         /// 
         /// 
-        public void SetDefault(string key, string value)
+        public void SetDefaultConfig(string key, string value)
         {
-            _defaultData[key] = value;
+            _defConfigs[key] = value;
             if (!HasKey(key))
             {
-                Data[key] = value;
-                Save();
+                SetConfigValue(key, value);
             }
         }
         
@@ -115,10 +115,10 @@ namespace Guru
         /// 
         /// 
         /// 
-        public void SetDefault(string key, T config) where T : IRemoteConfig
+        public void SetDefaultConfig(string key, T config) where T : IRemoteConfig
         {
             var json = config.ToJson();
-            SetDefault(key, json);
+            SetDefaultConfig(key, json);
         }
         
         /// 
@@ -127,15 +127,59 @@ namespace Guru
         /// 
         /// 
         /// 
-        public T Get(string key) where T : IRemoteConfig
+        public T Get(string key) where T : IRemoteConfig
         {
-            if(HasKey(key)) return JsonParser.ToObject(Data[key]);
+            string json = "";
+            if (HasKey(key))
+            {
+                json = configs[json];
+            }
+            else if (_defConfigs.TryGetValue(key, out var defValue))
+            {
+                json = defValue;   
+            }
+
+            if (!string.IsNullOrEmpty(json))
+            {
+                return JsonParser.ToObject(json);
+            }
+
+            Log.E(RemoteConfigManager.Tag, $" --- Remote Key {key} has never been registered.");
             return default(T);
         }
-
-        public void Set(string key, T config) where T : IRemoteConfig
+        
+        
+        /// 
+        /// 设置对象值
+        /// 
+        /// 
+        /// 
+        /// 
+        internal void SetConfigValue(string key, string value)
         {
-            
+            configs[key] = value;
+            Save();
+        }
+
+        /// 
+        /// 更新所有的配置
+        /// 
+        /// 
+        public void UpdateConfigs(Dictionary updates)
+        {
+            string key, value;
+            for (int i = 0; i < updates.Keys.Count; i++)
+            {
+                key = updates.Keys.ElementAt(i);
+                value = updates.Values.ElementAt(i);
+
+                if (!HasKey(key) || configs[key] != value)
+                {
+                  // New Key or Value Changed
+                  configs[key] = value;
+                }
+            }
+            Save(true); // 直接保存
         }
 
 
diff --git a/Runtime/GuruWebview/Runtime/GuruWebview.cs b/Runtime/GuruWebview/Runtime/GuruWebview.cs
index 4c512a9..e245c6e 100644
--- a/Runtime/GuruWebview/Runtime/GuruWebview.cs
+++ b/Runtime/GuruWebview/Runtime/GuruWebview.cs
@@ -1,17 +1,17 @@
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-
 namespace Guru
 {
+    using System.Collections;
+    using System.Collections.Generic;
+    using UnityEngine;
     
     /// 
     /// Guru 内置浏览器
     /// 
     public class GuruWebview
     {
-        public const string Version = "0.0.1";
-
+        public const string Version = "0.0.2";
+        public static float WindowFadeDuration = 0.35f;
+        
         private static UniWebView CreateWebView()
         {
             var go = new GameObject("guru_webview");
@@ -23,10 +23,14 @@ namespace Guru
         }
 
         /// 
-        /// 打开链接
+        /// 打开页面
         /// 
-        /// 
-        public static void OpenPage(string url, bool showToolbar = true)
+        /// 页面链接
+        /// 显示工具条
+        /// 等待加载完成后再显示页面
+        /// 淡入显示效果
+        public static void OpenPage(string url, bool showToolbar = true, 
+            bool waitForReady = true, bool fadeIn = true)
         {
             Debug.Log($"---- Guru Open Url: {url}");
             var view = CreateWebView();
@@ -40,14 +44,19 @@ namespace Guru
             }
 
             view.Load(url);
-            view.OnPageFinished += (v, code, msg) =>
+            if (waitForReady)
             {
-                // 加载完成后展示页面
-                view.Show(true);
-            };
-
+                view.OnPageFinished += (v, code, msg) =>
+                {
+                    // 加载完成后展示页面
+                    view.Show(fadeIn, duration:WindowFadeDuration);
+                };
+            }
+            else
+            {
+                view.Show(fadeIn, duration:WindowFadeDuration);   //直接加载页面
+            }
         }
 
     }
-}
-
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 4a437d4..716e80d 100644
--- a/package.json
+++ b/package.json
@@ -12,21 +12,5 @@
   "relatedPackages": {
   },
   "dependencies": {
-    "com.unity.purchasing": "4.10.0",
-    "com.unity.mobile.android-logcat": "1.3.2",
-    "com.unity.editorcoroutines": "1.0.0",
-    "com.coffee.upm-git-extension": "https://github.com/mob-sakai/UpmGitExtension.git",
-    "com.google.external-dependency-manager": "https://github.com/GameWorkstore/com.google.external-dependency-manager.git",
-    "com.google.firebase.crashlytics": "https://github.com/GameWorkstore/com.google.firebase.crashlytics.git#10.1.1",
-    "com.google.firebase.analytics": "https://github.com/GameWorkstore/com.google.firebase.analytics.git#10.1.1",
-    "com.google.firebase.app": "https://github.com/GameWorkstore/com.google.firebase.app.git#10.1.1",
-    "com.google.firebase.auth": "https://github.com/GameWorkstore/com.google.firebase.auth.git#10.1.1",
-    "com.google.firebase.firestore": "https://github.com/GameWorkstore/com.google.firebase.firestore.git#10.1.1",
-    "com.google.firebase.messaging": "https://github.com/GameWorkstore/com.google.firebase.messaging.git#10.1.1",
-    "com.google.firebase.remote-config": "https://github.com/GameWorkstore/com.google.firebase.remote-config.git#10.1.1",
-    "com.google.firebase.dynamic-links": "https://github.com/GameWorkstore/com.google.firebase.dynamic-links.git#10.1.1",
-
-    "com.guru.unity.adjust": "git@git.chengdu.pundit.company:castbox/com.guru.unity.adjust.git",
-    "com.guru.unity.max": "git@git.chengdu.pundit.company:castbox/com.guru.unity.max.git"
   }
 }
\ No newline at end of file