C# Xamarin形成android json-异步调用挂起/从不返回
您好,我正在使用Xamarin表单开发一个android应用程序,它从服务中获取json数据,它应该在ContactInfo类中显示该数据,但是当您单击按钮时,它应该获取该数据,然后显示该数据,然后将您带到ContactInfo类,它将挂起,一分钟后,我的galaxy s7会告诉我该应用程序没有响应。是否要关闭它? 我不知道我做错了什么 这是我的Xaml:C# Xamarin形成android json-异步调用挂起/从不返回,c#,json,xamarin.android,xamarin.forms,C#,Json,Xamarin.android,Xamarin.forms,您好,我正在使用Xamarin表单开发一个android应用程序,它从服务中获取json数据,它应该在ContactInfo类中显示该数据,但是当您单击按钮时,它应该获取该数据,然后显示该数据,然后将您带到ContactInfo类,它将挂起,一分钟后,我的galaxy s7会告诉我该应用程序没有响应。是否要关闭它? 我不知道我做错了什么 这是我的Xaml: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="h
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ReadyMo.ContactInfo">
<ListView ItemsSource="{Binding ContactInfoList}" HasUnevenRows="true">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame Padding="0,0,0,8" BackgroundColor="#d2d5d7">
<Frame.Content>
<Frame Padding="15,15,15,15" OutlineColor="Gray" BackgroundColor="White">
<Frame.Content>
<StackLayout Padding="20,0,0,0" Orientation="Horizontal" HorizontalOptions="CenterAndExpand">
<Label x:Name="FirstName" Text="{Binding First_Name}" HorizontalOptions="Center">
</Label>
<Label x:Name ="LastName" Text="{Binding Last_Name}" HorizontalOptions="Center">
</Label>
<Label x:Name="County" Text="{Binding name}" HorizontalOptions="Center">
</Label>
<Label x:Name ="Adress" Text="{Binding Address1}" HorizontalOptions="Center">
</Label>
<Label x:Name ="City" Text="{Binding Address2}" HorizontalOptions="Center">
</Label>
<Label x:Name="Number" Text="{Binding BusinessPhone}" HorizontalOptions="Center">
</Label>
</StackLayout>
</Frame.Content>
</Frame>
</Frame.Content>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
这是我的代码隐藏:
using Newtonsoft.Json;
using ReadyMo.Data;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace ReadyMo
{
public partial class ContactInfo : ContentPage
{
private County item;
public static async Task<string> GetContactString(string contactid)
{
HttpClient client = new HttpClient();
var url = $"http://sema.dps.mo.gov/county/service.php?id={contactid}";
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var responsetext = await response.Content.ReadAsStringAsync();
return responsetext;
}
throw new Exception(response.ReasonPhrase);
}
public ContactInfo()
{
InitializeComponent();
}
List <ContactInfoModel> ContactInfoList;
public ContactInfo(County item)
{
InitializeComponent();
this.item = item;
var contactpagetext = ContactManager.GetContactString(item.id);
var contact = GetContactString("001").Result;
//need to add update database code
//Convert Jason string to object
ContactInfoList = JsonConvert.DeserializeObject<List<ContactInfoModel>>(contact);
this.BindingContext = ContactInfoList;
//Floodplain Administrators
}
}
}
使用Newtonsoft.Json;
使用ReadyMo.数据;
使用制度;
使用System.Collections.Generic;
使用System.Net.Http;
使用System.Threading.Tasks;
使用Xamarin.Forms;
名称空间ReadyMo
{
公共部分类ContactInfo:ContentPage
{
私营县项目;
公共静态异步任务GetContactString(string contactid)
{
HttpClient=新的HttpClient();
var url=$”http://sema.dps.mo.gov/county/service.php?id={contactid}”;
var response=wait client.GetAsync(url);
if(响应。IsSuccessStatusCode)
{
var responsetext=wait response.Content.ReadAsStringAsync();
返回响应文本;
}
抛出新异常(response.ReasonPhrase);
}
公共联系人信息()
{
初始化组件();
}
列表联系人信息列表;
公共联系人信息(县项目)
{
初始化组件();
this.item=项目;
var contactpagetext=ContactManager.GetContactString(item.id);
var contact=GetContactString(“001”)。结果;
//需要添加更新数据库代码
//将字符串转换为对象
ContactInfoList=JsonConvert.DeserializeObject(联系人);
this.BindingContext=联系人信息列表;
//漫滩管理者
}
}
}
任何帮助都将是惊人的
提前感谢 您的问题在这一行:
var contact = GetContactString("001").Result;
这是我在博客上完整解释的
要解决这个问题,您必须首先意识到UI必须立即显示。当操作系统调用您的代码时,您不能等待HTTP请求完成后再响应;这是绝对不允许的
您可以做的是启动HTTP请求并立即显示其他内容(如微调器或“加载…”消息)。然后,当HTTP请求完成时,用新信息更新显示
我的中有更多详细信息和示例代码。尝试将异步代码移出构造函数。一种常见的方法是重写OnAppearing()以执行工作。您可能还希望在UI中显示
活动指示器
,直到数据加载完毕:
public partial class ContactInfo : ContentPage
{
private County item;
public static async Task<string> GetContactString(string contactid)
{
HttpClient client = new HttpClient();
var url = $"http://sema.dps.mo.gov/county/service.php?id={contactid}";
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var responsetext = await response.Content.ReadAsStringAsync();
return responsetext;
}
throw new Exception(response.ReasonPhrase);
}
public ContactInfo()
{
InitializeComponent();
ContactInfoList = new ObservableCollection<ContactInfoModel>();
}
ObservableCollection<ContactInfoModel> ContactInfoList;
public ContactInfo(County item) : this()
{
this.item = item;
this.BindingContext = ContactInfoList;
}
protected override async void OnAppearing ()
{
if (item == null)
return;
var contact = await GetContactString(item.id);
var models = JsonConvert.DeserializeObject<List<ContactInfoModel>>(contact);
foreach (var model in models)
ContactInfoList.Add(model);
}
}
public部分类联系人信息:ContentPage
{
私营县项目;
公共静态异步任务GetContactString(string contactid)
{
HttpClient=新的HttpClient();
var url=$”http://sema.dps.mo.gov/county/service.php?id={contactid}”;
var response=wait client.GetAsync(url);
if(响应。IsSuccessStatusCode)
{
var responsetext=wait response.Content.ReadAsStringAsync();
返回响应文本;
}
抛出新异常(response.ReasonPhrase);
}
公共联系人信息()
{
初始化组件();
ContactInfoList=新的ObservableCollection();
}
可观察收集联系人信息列表;
公共联系人信息(县项目):此()
{
this.item=项目;
this.BindingContext=联系人信息列表;
}
出现()时受保护的重写异步无效
{
如果(项==null)
返回;
var contact=await GetContactString(item.id);
var models=JsonConvert.DeserializeObject(contact);
foreach(模型中的var模型)
ContactInfoList.Add(型号);
}
}
要解决绑定问题,请认识到您正在将列表本身分配给页面的绑定上下文。您可以执行以下两种操作之一:
ItemsSource=“{Binding ContactInfoList}”
更改为ItemsSource=“{Binding.}”
this.BindingContext=ContactInfoList将构造函数中的code>转换为this.BindingContext=this代码>
首选选项#1。感谢您的回复,那么您建议我如何根据我的代码解决此问题?我读了你的博客文章,这是一个windows应用程序这是一个来自android应用程序的xamrain,那么在从服务中提取数据时,我如何实现加载屏幕呢?再次感谢您的帮助!:)@Phoneswapshop:你读过MSDN的文章吗?它适用于所有XAML堆栈。您应该能够使用本文中的想法以及类似于数据绑定异步操作的内容。我这样做了,但是我在将您的示例合并到我的项目中时遇到了问题。您可以根据我的项目提出建议吗?感谢到目前为止的所有帮助:)感谢您的回复,解决了悬而未决的问题,但事实并非如此是否在listview中显示任何内容?它只是在显示一张白纸,你有什么想法吗?感谢迄今为止的所有帮助!:)当然,我在答案中添加了更多内容来处理这一部分。