简体   繁体   English

从JSON下载信息(Xamarin C#)

[英]Downloading info from JSON(Xamarin C#)

I am writing Android app in Xamarin C#. 我在Xamarin C#中编写Android应用程序。

I parse info from JSON and then show it in fields. 我从JSON解析信息,然后在字段中显示它。

I use this code: 我用这个代码:

string url2 = "http://papajohn.pp.ua/?mkapi=getProductsByCat&cat_id=74";
        JsonValue json = await FetchAsync(url2);
 private async Task<JsonValue> FetchAsync(string url)
    {
        // Create an HTTP web request using the URL:
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
        request.ContentType = "application/json";
        request.Method = "GET";

        // Send the request to the server and wait for the response:
        using (WebResponse response = await request.GetResponseAsync())
        {
            // Get a stream representation of the HTTP web response:
            using (Stream stream = response.GetResponseStream())
            {
                // Use this stream to build a JSON document object:
                JsonValue jsonDoc = await Task.Run(() => JsonObject.Load(stream));
                //dynamic data = JObject.Parse(jsonDoc[15].ToString);
                Console.Out.WriteLine("Response: {0}", jsonDoc.ToString());


                // Return the JSON document:
                return jsonDoc;
            }
        }
    }

But I have one problem. 但我有一个问题。 When I open Activity it freezes for 2-3 seconds and then all info shows in fields. 当我打开Activity时,它会冻结2-3秒,然后所有信息显示在字段中。

Can I make that data download smoothly. 我可以顺利地下载数据吗? First field, then second etc. 第一场,第二场等

And if I can, how? 如果我能,怎么样?

I would recommend implementing the proper usage of async/await in C#, and switching to HttpClient, which also implements the proper usage of async/await. 我建议在C#中正确使用async / await,并切换到HttpClient,它也实现了async / await的正确使用。 Below is a code sample that will retrieve your Json outside of the UI Thread: 下面是一个代码示例,它将在UI线程之外检索您的Json:

var url2 = "http://papajohn.pp.ua/?mkapi=getProductsByCat&cat_id=74";
var jsonValue = await FetchAsync(url2);

private async Task<JsonValue> FetchAsync(string url)
{
   System.IO.Stream jsonStream;
   JsonValue jsonDoc;

   using(var httpClient = new HttpClient())
   {
     jsonStream = await httpClient.GetStreamAsync(url);
     jsonDoc = JsonObject.Load(jsonStream);
   }

   return jsonDoc;
}

If you're writing your code in an Android project, you'll need to add the System.Net.Http DLL as a reference. 如果您在Android项目中编写代码,则需要添加System.Net.Http DLL作为参考。 If you're writing your code in aPCL, then you'll need to install the Microsoft Http Client Libraries Nuget Package . 如果您在aPCL中编写代码,则需要安装Microsoft Http Client Libraries Nuget Package For even improve performance, I recommend using ModernHttpClient , which can also be installed from Nuget. 为了提高性能,我建议使用ModernHttpClient ,它也可以从Nuget安装。

Your Async-Await usage in HttpWebRequest is correct. 您在HttpWebRequest中的Async-Await使用是正确的。 Wrong invocation of this method from Activity might be causing the UI freeze. 从Activity调用此方法的错误可能导致UI冻结。 I will explain how to invoke below. 我将在下面解释如何调用。

I would also recommend to use ModernHttpClient library to speed up the API call. 我还建议使用ModernHttpClient库来加速API调用。

public static async Task<ServiceReturnModel> HttpGetForJson (string url)
    {

        using (var client = new HttpClient(new NativeMessageHandler())) 
        {

            try
            {
                using (var response = await client.GetAsync(new Uri (url))) 
                {
                    using (var responseContent = response.Content) 
                    {
                        var responseString= await responseContent.ReadAsStringAsync();
                        var result =JsonConvert.DeserializeObject<ServiceReturnModel>(responseString);
                    }
                }
            }
            catch(Exception ex) 
            {
               // Include error info here
            }
            return result;

        }

    }

You will need to include Xamarin Components ModernHttpClient and JSON.NET (Newtonsoft.Json) 您将需要包含Xamarin组件ModernHttpClient和JSON.NET(Newtonsoft.Json)

Invoking this method from Activity without blocking UI 从Activity调用此方法而不阻止UI

protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);

        SetContentView (Resource.Layout.Main);
        // After doing initial Setups
        LoadData();
     }

// This method downloads Json asynchronously without blocking UI and without showing a Pre-loader.
async Task LoadData()
    {
        var newRequestsResponse =await ServiceLayer.HttpGetForJson (newRequestsUrl);
      // Use the data here or show proper error message
    }

 // This method downloads Json asynchronously without blocking UI and shows a Pre-loader while downloading.
async Task LoadData()
    {
        ProgressDialog progress = new ProgressDialog (this,Resource.Style.progress_bar_style);
        progress.Indeterminate = true;
        progress.SetProgressStyle (ProgressDialogStyle.Spinner);
        progress.SetCancelable (false);
        progress.Show ();
        var newRequestsResponse =await ServiceLayer.HttpGetForJson (newRequestsUrl);
        progress.Dismiss ();
      // Use the data here or show proper error message
    }

Material type Loader Style. 材料类型装载机样式。 To be included in Resources/Values/Style.xml 要包含在Resources / Values / Style.xml中

<style name="progress_bar_style">
<item name="android:windowFrame">@null</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowTitleStyle">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:background">@android:color/transparent</item>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM