.NET MAUI中AppShell ViewModel无法留存用户数据的求助
解决.NET MAUI Flyout休眠唤醒后用户信息丢失问题
核心问题在于内存中的UserInfo数据会在应用休眠时被系统回收,仅依赖单例ViewModel无法持久化数据。以下是具体解决方案:
1. 持久化用户信息
登录成功后将用户数据序列化存储到本地,注销时清除。可根据数据敏感程度选择:
Preferences:存储非敏感数据(如用户名、头像URL)SecureStorage:存储敏感数据(如用户ID、令牌)
示例代码(登录成功时):
// 序列化用户对象 var userJson = System.Text.Json.JsonSerializer.Serialize(currentUser); // 存储到Preferences Preferences.Set("CurrentAuthenticatedUser", userJson); // 敏感数据用SecureStorage // await SecureStorage.SetAsync("CurrentAuthenticatedUser", userJson);
2. 修改AppShellViewModel
在ViewModel中添加持久化逻辑,确保初始化、应用唤醒时都能加载用户信息:
public partial class AppShellViewModel : BaseViewModel, IDisposable { public AppShellViewModel() { // 初始化时先加载本地存储的用户信息 LoadUserFromStorage(); MessagingCenter.Subscribe<User>(this, "userUpdated", (user) => { UserInfo = user; // 收到更新后同步持久化 SaveUserToStorage(user); }); // 订阅应用唤醒事件 Application.Current.Resumed += OnAppResumed; } [ObservableProperty] User userInfo; [RelayCommand] async Task SignOff() { // 注销时清除本地存储 Preferences.Remove("CurrentAuthenticatedUser"); // await SecureStorage.RemoveAsync("CurrentAuthenticatedUser"); UserInfo = null; // 执行其他注销逻辑(如跳转登录页) } private void LoadUserFromStorage() { var userJson = Preferences.Get("CurrentAuthenticatedUser", string.Empty); // var userJson = await SecureStorage.GetAsync("CurrentAuthenticatedUser"); if (!string.IsNullOrEmpty(userJson)) { UserInfo = System.Text.Json.JsonSerializer.Deserialize<User>(userJson); } } private void SaveUserToStorage(User user) { var userJson = System.Text.Json.JsonSerializer.Serialize(user); Preferences.Set("CurrentAuthenticatedUser", userJson); // await SecureStorage.SetAsync("CurrentAuthenticatedUser", userJson); } private void OnAppResumed(object sender, EventArgs e) { // 应用唤醒时重新加载用户信息 LoadUserFromStorage(); } // 清理事件订阅,避免内存泄漏 public void Dispose() { Application.Current.Resumed -= OnAppResumed; MessagingCenter.Unsubscribe<User>(this, "userUpdated"); } }
3. 清理ViewModel订阅
在AppShell中实现ViewModel的资源释放:
public partial class AppShell : Shell { private readonly AppShellViewModel _viewModel; public AppShell(AppShellViewModel viewModel) { InitializeComponent(); _viewModel = viewModel; BindingContext = _viewModel; } protected override void OnDisappearing() { base.OnDisappearing(); _viewModel.Dispose(); } }
4. 确保User类可序列化
给User类添加可序列化标识,或确保所有属性都是基础可序列化类型:
[Serializable] public class User { public string Name { get; set; } public string AvatarUrl { get; set; } // 其他属性 }
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

