Xamarin + MvvmCross + Azure 移动应用 table 请求无效
Xamarin + MvvmCross + Azure Mobile App table request not working
我一直在构建一个简单的 Xamarin 应用程序,使用 MvvmCross 框架和 Azure 移动应用程序服务来存储和检索来自云的数据。
UI 项目是特定于平台的。
我的应用程序的主视图显示了一个 post 的列表,这个列表应该是从 Azure 云中检索的。
发生的情况是,在启动画面之后,应用程序只显示黑屏。
似乎正确触发了检索数据的调用,但从未收到响应。
这是我的 post 视图模型:
public class PostsViewModel : MvxViewModel
{
readonly IPostService _postService;
readonly IMvxNavigationService _navigationService;
readonly MvxSubscriptionToken token;
public PostsViewModel(IPostService postService, IMvxMessenger messenger, IMvxNavigationService navigationService)
{
_postService = postService;
_navigationService = navigationService;
token = messenger.SubscribeOnMainThread<PostsChangedMessage>
(async mex => await LoadPosts());
Posts = new ObservableCollection<PostViewModel>();
AddNewPostCommand = new MvxAsyncCommand(AddNewPost);
ShowPostDetailsCommand = new MvxAsyncCommand<PostViewModel>(ShowPostDetails);
}
#region Properties
public ObservableCollection<PostViewModel> Posts { get; set; }
private bool isLoading = true;
public bool IsLoading
{
get => isLoading;
set => SetProperty(ref isLoading, value);
}
#endregion
#region Commands
public IMvxAsyncCommand AddNewPostCommand { get; }
private async Task AddNewPost()
{
await _navigationService.Navigate(typeof(PostViewModel), new Post());
}
public IMvxAsyncCommand<PostViewModel> ShowPostDetailsCommand { get; }
private async Task ShowPostDetails(PostViewModel postViewModel)
{
await _navigationService.Navigate(typeof(PostDetailsViewModel), postViewModel);
}
#endregion
#region Functions
public override async Task Initialize()
{
await LoadPosts();
}
private async Task LoadPosts()
{
// Remove all counters before reloading
Posts.Clear();
var posts = await _postService.GetAllPosts();
foreach(var post in posts)
{
var viewModel = new PostViewModel(_postService, _navigationService);
viewModel.Prepare(post);
Posts.Add(viewModel);
}
IsLoading = false;
}
#endregion
}
这是我的 post 服务:
public class PostService : IPostService
{
readonly IPostRepository _repository;
readonly IMvxMessenger _messenger;
public PostService(IPostRepository repository, IMvxMessenger messenger)
{
_repository = repository;
_messenger = messenger;
}
public async Task<Post> AddNewPost(Post post)
{
// Just for testing purposes
post.Date = DateTimeOffset.Now;
// Temporary hard-coded author; this will be get from the user object
post.Author = "John Smith";
await _repository.Save(post).ConfigureAwait(false);
_messenger.Publish(new PostsChangedMessage(this));
return post;
}
public async Task DeletePost(Post post)
{
await _repository.Delete(post).ConfigureAwait(false);
_messenger.Publish(new PostsChangedMessage(this));
}
public Task<List<Post>> GetAllPosts()
{
return _repository.GetAll();
}
这是我的存储库:
public class PostRepository : IPostRepository
{
MobileServiceClient MobileService
= new MobileServiceClient(@"https://vntestapp.azurewebsites.net", new LoggingHandler(true));
IMobileServiceTable<Post> postTable;
public PostRepository()
{
postTable = MobileService.GetTable<Post>();
}
public Task Delete(Post post)
{
return postTable.DeleteAsync(post);
}
public async Task<List<Post>> GetAll()
{
return await postTable.ToListAsync();
}
public async Task<Post> Save(Post post)
{
await postTable.InsertAsync(post);
return post;
}
}
如果 运行 平台是 android,则对 API 调用使用 Task.Run() 构造。
根据我使用 Mvvmcross 的实际经验,在 android 中,有时异步方法内部的等待调用会阻塞该线程,并且它永远不会 returns、
在这种情况下,如果您在 Task.Run() 中调用它,它就可以正常工作。
而 iOS 没有这个问题。
我会寻找更深入的解释来提供它的原因。
我一直在构建一个简单的 Xamarin 应用程序,使用 MvvmCross 框架和 Azure 移动应用程序服务来存储和检索来自云的数据。 UI 项目是特定于平台的。
我的应用程序的主视图显示了一个 post 的列表,这个列表应该是从 Azure 云中检索的。 发生的情况是,在启动画面之后,应用程序只显示黑屏。 似乎正确触发了检索数据的调用,但从未收到响应。
这是我的 post 视图模型:
public class PostsViewModel : MvxViewModel
{
readonly IPostService _postService;
readonly IMvxNavigationService _navigationService;
readonly MvxSubscriptionToken token;
public PostsViewModel(IPostService postService, IMvxMessenger messenger, IMvxNavigationService navigationService)
{
_postService = postService;
_navigationService = navigationService;
token = messenger.SubscribeOnMainThread<PostsChangedMessage>
(async mex => await LoadPosts());
Posts = new ObservableCollection<PostViewModel>();
AddNewPostCommand = new MvxAsyncCommand(AddNewPost);
ShowPostDetailsCommand = new MvxAsyncCommand<PostViewModel>(ShowPostDetails);
}
#region Properties
public ObservableCollection<PostViewModel> Posts { get; set; }
private bool isLoading = true;
public bool IsLoading
{
get => isLoading;
set => SetProperty(ref isLoading, value);
}
#endregion
#region Commands
public IMvxAsyncCommand AddNewPostCommand { get; }
private async Task AddNewPost()
{
await _navigationService.Navigate(typeof(PostViewModel), new Post());
}
public IMvxAsyncCommand<PostViewModel> ShowPostDetailsCommand { get; }
private async Task ShowPostDetails(PostViewModel postViewModel)
{
await _navigationService.Navigate(typeof(PostDetailsViewModel), postViewModel);
}
#endregion
#region Functions
public override async Task Initialize()
{
await LoadPosts();
}
private async Task LoadPosts()
{
// Remove all counters before reloading
Posts.Clear();
var posts = await _postService.GetAllPosts();
foreach(var post in posts)
{
var viewModel = new PostViewModel(_postService, _navigationService);
viewModel.Prepare(post);
Posts.Add(viewModel);
}
IsLoading = false;
}
#endregion
}
这是我的 post 服务:
public class PostService : IPostService
{
readonly IPostRepository _repository;
readonly IMvxMessenger _messenger;
public PostService(IPostRepository repository, IMvxMessenger messenger)
{
_repository = repository;
_messenger = messenger;
}
public async Task<Post> AddNewPost(Post post)
{
// Just for testing purposes
post.Date = DateTimeOffset.Now;
// Temporary hard-coded author; this will be get from the user object
post.Author = "John Smith";
await _repository.Save(post).ConfigureAwait(false);
_messenger.Publish(new PostsChangedMessage(this));
return post;
}
public async Task DeletePost(Post post)
{
await _repository.Delete(post).ConfigureAwait(false);
_messenger.Publish(new PostsChangedMessage(this));
}
public Task<List<Post>> GetAllPosts()
{
return _repository.GetAll();
}
这是我的存储库:
public class PostRepository : IPostRepository
{
MobileServiceClient MobileService
= new MobileServiceClient(@"https://vntestapp.azurewebsites.net", new LoggingHandler(true));
IMobileServiceTable<Post> postTable;
public PostRepository()
{
postTable = MobileService.GetTable<Post>();
}
public Task Delete(Post post)
{
return postTable.DeleteAsync(post);
}
public async Task<List<Post>> GetAll()
{
return await postTable.ToListAsync();
}
public async Task<Post> Save(Post post)
{
await postTable.InsertAsync(post);
return post;
}
}
如果 运行 平台是 android,则对 API 调用使用 Task.Run() 构造。
根据我使用 Mvvmcross 的实际经验,在 android 中,有时异步方法内部的等待调用会阻塞该线程,并且它永远不会 returns、
在这种情况下,如果您在 Task.Run() 中调用它,它就可以正常工作。 而 iOS 没有这个问题。
我会寻找更深入的解释来提供它的原因。