2016-06-03 4 views
1

안녕하세요 저는 Xamarin 양식의 Android 응용 프로그램에서 서비스에서 json 데이터를 가져 오는 중입니다. ContactInfo 클래스에서 해당 데이터를 표시하도록되어 있습니다. 그 데이터를 가져 와서 표시 한 다음 ContactInfo 클래스로 이동합니다. 잠시 후 갤럭시 s7에서 앱이 응답하지 않는다고 알려 주면 닫으시겠습니까? 나는 내가Xamarin forms android json - 비동기 호출이 응답하지 않거나 응답하지 않습니다.

잘못 뭘하는지 몰라 여기 내 XAML의 :

<?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 



     } 
    } 
} 

도움 놀라운 것은!

감사합니다.

답변

1

비동기 코드를 생성자 밖으로 이동해보십시오. 이에 대한 공통적 인 접근 방법은 OnAppearing()을 대체하여 작업을 수행하는 것입니다. 또한 아마 데이터가로드 될 때까지 당신의 UI에 ActivityIndicator을 표시 할 것 :

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); 
    } 
} 

는 페이지의 BindingContext를에 목록 자체를 할당하는 것을 인식, 바인딩 문제를 해결하려면. 두 가지 중 하나를 수행 할 수 있습니다 귀하의 ListView XAML에서

  1. 변경 ItemsSource="{Binding ContactInfoList}"ItemsSource="{Binding .}"에.
  2. 생성자의 this.BindingContext = ContactInfoList;this.BindingContext = this;으로 변경하십시오.

옵션 # 1이 좋습니다.

+0

교수형 문제를 해결 한 답장을 보내 주셔서 감사합니다.하지만 그렇지 않습니다. listview에 모든 내용을 표시 하시겠습니까? 그것의 다만 이것을하는 왜에 관한 어떤 생각든지 백색 페이지를 보여주기? 지금까지 모든 도움에 감사드립니다! :) – Phoneswapshop

+0

물론, 나는 그 부분을 처리하기위한 답에 더 많은 것을 추가했다. –

+0

OMG 그게 정말 고마워! !!!!!!! – Phoneswapshop

3

귀하의 문제는이 라인에 있습니다

var contact = GetContactString("001").Result; 

그것은 내 블로그에 전액 설명 causing a deadlock입니다.

이 문제를 해결하려면 먼저 으로 표시해야한다는 것을 먼저 알아야합니다. OS가 코드를 호출하면 응답하기 전에 HTTP 요청이 완료 될 때까지 기다릴 수 없습니다. 그것은 단순히 허용되지 않습니다. 당신이 입니다 HTTP 요청을 시작하고 즉시 (스피너 또는 "로드 ..."메시지와 같은) 다른 뭔가를 표시 할 수있는

. 그런 다음 HTTP 요청이 완료되면 업데이트 디스플레이에 새 정보가 표시됩니다.

자세한 내용과 샘플 코드는 MSDN article on async MVVM data binding에 있습니다.

+0

응답 해 주셔서 감사합니다. 그럼 내 코드를 기반으로이 문제를 해결할 것을 제안 하시겠습니까? 나는 귀하의 블로그 게시물을 읽고 그것은 xamrain froms android app입니다. 그래서 데이터가 서비스에서 빠져 나가는 동안 로딩 화면을 구현하는 방법은 무엇입니까? 모든 도움을 주셔서 다시 한 번 감사드립니다! :) – Phoneswapshop

+0

@Phoneswapshop : MSDN 기사를 읽었습니까? 모든 XAML 스택에 적용됩니다. 기사의 아이디어를 [NotifyTask] (https://github.com/StephenCleary/Mvvm.Async/blob/master/src/Nito.Mvvm.Async/NotifyTask.cs)와 함께 사용할 수 있어야합니다. 데이터 바인딩 비동기 작업 –

+0

하지만 내 프로젝트에 예제를 통합하는 데 문제가 있습니다. 지금까지 모든 프로젝트에 도움을 주셔서 감사합니다. – Phoneswapshop

관련 문제