日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Xamarin.Android开发实践(四)

發(fā)布時(shí)間:2023/12/19 Android 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Xamarin.Android开发实践(四) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Xamarin.Android下獲取與解析JSON

一、新建項(xiàng)目

1.新建一個(gè)Android項(xiàng)目,并命名為為NetJsonList

?

2.右擊引用,選擇添加引用,引用System.Json.dll

?

二、同步請(qǐng)求

既然是跨平臺(tái),我們自然不能按照java下的方式進(jìn)行編寫,否則如何跨平臺(tái)呢,所以我們需要使用Syste.Net命名空間下的兩個(gè)類:HttpWebRequestHttpWebResponse

?

首先打開Resources/layout/Main.axml文件

刪除其他上面的控件,并拖拽一個(gè)Text(large)到其中。

?

接著打開MainActivity.cs文件,并將如下代碼寫入其中


1 namespace NetJsonList 2 { 3 [Activity(Label = "NetJsonList", MainLauncher = true, Icon = "@drawable/icon")] 4 public class MainActivity : Activity 5 { 6 TextView tv; 7 8 protected override void OnCreate(Bundle bundle) 9 { 10 base.OnCreate(bundle); 11 SetContentView(Resource.Layout.Main); 12 13 tv = FindViewById<TextView>(Resource.Id.textView1); 14 15 LoadXamarin(); 16 } 17 18 public void LoadXamarin() 19 { 20 //測試用 21 string url = "http://www.xamarin-cn.com/test.json"; 22 23 //創(chuàng)建一個(gè)請(qǐng)求 24 var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url)); 25 26 //獲取響應(yīng) 27 var httpRes = (HttpWebResponse)httpReq.GetResponse(); 28 29 //讀取響應(yīng)的字符串 30 String text = new StreamReader(httpRes.GetResponseStream()).ReadToEnd(); 31 tv.Text = text; 32 } 33 } 34 }

?

?

這里我們通過HttpWebRequestCreate靜態(tài)方法創(chuàng)建了一個(gè)請(qǐng)求,那么下面我們可以獲取響應(yīng)了,筆者這里直接使用StreamReader讀取了,以便顯示出來。

?

注:如果要在在短時(shí)間內(nèi)高頻率的使用HTTP請(qǐng)改用HttpURLConnection。

?

最終顯示的結(jié)果如下所示:

?

但是我們?cè)诰幋a的過程中絕對(duì)不能這么做,因?yàn)檫@樣會(huì)使UI線程阻塞。意思就是用戶使用這個(gè)app時(shí)會(huì)出現(xiàn)卡頓,這樣對(duì)于任何一個(gè)人使用者來說都是很難忍受的,所以下面我們要采用異步的方式來實(shí)現(xiàn)。

?

三、異步請(qǐng)求

首先我們先把異步請(qǐng)求回調(diào)的方法寫出來:


1 //異步回調(diào)方法 2 public void ReadXamarin(IAsyncResult asyn) 3 { 4 var httpReq = (HttpWebRequest)asyn.AsyncState; 5 6 //獲取響應(yīng) 7 using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse(asyn)) 8 { 9 //判斷是否成功獲取響應(yīng) 10 if (httpRes.StatusCode == HttpStatusCode.OK) 11 { 12 //讀取響應(yīng) 13 var text = new StreamReader(httpRes.GetResponseStream()).ReadToEnd(); 14 15 //切換到UI線程,否則無法對(duì)控件進(jìn)行操作 16 RunOnUiThread(() => 17 { 18 tv.Text = text; 19 }); 20 } 21 } 22 }

?

?

通過AsyncState獲取HttpWebRequest的引用,然后再調(diào)用其EndGetResponse方法獲取響應(yīng),并將響應(yīng)的字符串顯示,特別需要注意的是我們這里使用了RunOnUiThread方法,因?yàn)楫惒交卣{(diào)的方法不是使用UI線程執(zhí)行的,這也是為什么這樣做就不會(huì)阻塞UI線程了。

?

當(dāng)然有了異步操作的回調(diào)方法,自然在調(diào)用的時(shí)候需要使用特殊的方法:


1 public void LoadXamarin() 2 { 3 //測試用 4 string url = "http://www.xamarin-cn.com/test.json"; 5 6 //創(chuàng)建一個(gè)請(qǐng)求 7 var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url)); 8 httpReq.BeginGetResponse(new AsyncCallback(ReadXamarin), httpReq); 9 }

?

?

所有的代碼如下所示:


1 namespace NetJsonList 2 { 3 [Activity(Label = "NetJsonList", MainLauncher = true, Icon = "@drawable/icon")] 4 public class MainActivity : Activity 5 { 6 TextView tv; 7 8 protected override void OnCreate(Bundle bundle) 9 { 10 base.OnCreate(bundle); 11 SetContentView(Resource.Layout.Main); 12 13 tv = FindViewById<TextView>(Resource.Id.textView1); 14 15 LoadXamarin(); 16 } 17 18 public void LoadXamarin() 19 { 20 //測試用 21 string url = "http://www.xamarin-cn.com/test.json"; 22 23 //創(chuàng)建一個(gè)請(qǐng)求 24 var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url)); 25 httpReq.BeginGetResponse(new AsyncCallback(ReadXamarin), httpReq); 26 } 27 28 //異步回調(diào)方法 29 public void ReadXamarin(IAsyncResult asyn) 30 { 31 var httpReq = (HttpWebRequest)asyn.AsyncState; 32 33 //獲取響應(yīng) 34 using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse(asyn)) 35 { 36 //判斷是否成功獲取響應(yīng) 37 if (httpRes.StatusCode == HttpStatusCode.OK) 38 { 39 //讀取響應(yīng) 40 var text = new StreamReader(httpRes.GetResponseStream()).ReadToEnd(); 41 42 //切換到UI線程,否則無法對(duì)控件進(jìn)行操作 43 RunOnUiThread(() => 44 { 45 tv.Text = text; 46 }); 47 } 48 } 49 } 50 } 51 }

?

?

四、利用await的異步請(qǐng)求

通過c# 5.0 的新特性await我們可以寫更少的代碼實(shí)現(xiàn)異步,我們修改LoadXamarin方法:


1 public async void LoadXamarin() 2 { 3 //測試用 4 string url = "http://www.xamarin-cn.com/test.json"; 5 6 //創(chuàng)建一個(gè)請(qǐng)求 7 var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url)); 8 var httpRes = (HttpWebResponse)await httpReq.GetResponseAsync(); 9 if (httpRes.StatusCode == HttpStatusCode.OK) 10 { 11 var text = new StreamReader(httpRes.GetResponseStream()).ReadToEnd(); 12 tv.Text = text; 13 } 14 }

?

?

可以看到我們給這個(gè)方法加了一個(gè)async關(guān)鍵字,如果不加這個(gè)關(guān)鍵字,在該方法中是無法使用await的,下面我們就看到了這句代碼:

1 var httpRes = (HttpWebResponse)await httpReq.GetResponseAsync();

?

?

當(dāng)Ui線程執(zhí)行到這句后,直接就會(huì)跳過去,不會(huì)等待。當(dāng)然下面的方法也不會(huì)去執(zhí)行了,只有當(dāng)這個(gè)方法返回了結(jié)果之后,UI線程才會(huì)回到這句代碼,并繼續(xù)執(zhí)行下面的方法。當(dāng)然這些只是障眼法,其實(shí)c#已經(jīng)把下面的代碼作為了異步回調(diào)執(zhí)行的方法了:

1 if (httpRes.StatusCode == HttpStatusCode.OK) 2 { 3 var text = new StreamReader(httpRes.GetResponseStream()).ReadToEnd(); 4 tv.Text = text; 5 }

?

?

并且執(zhí)行的線程依然是之前執(zhí)行該方法的線程,如果你創(chuàng)建一個(gè)新的線程去執(zhí)行。那么就必須使用RunOnUiThread方法了。還有一個(gè)缺點(diǎn)就是不能在其中進(jìn)行復(fù)雜的運(yùn)算,否則還是會(huì)造成UI線程的阻塞。

?

五、解析JSON

在開始本節(jié)前,必須確保引用了正確的System.Json類庫,否則無法使用。

?

首先我們先看看json數(shù)據(jù)的格式:

1 { 2 "T": [ 3 "T1", 4 "T2", 5 "T3", 6 "T4" 7 ] 8 }

?

?

知道了json數(shù)據(jù)格式了,我們還要理解下System.Json中有哪些類:

JsonValue:是基礎(chǔ)類,代表一個(gè)Json值

JsonObject:繼承JsonValue,代表一個(gè)Json對(duì)象

JsonArray:繼承JsonValue,代表一個(gè)Json數(shù)組

JsonPrimitive:繼承JsonValue,組織Json數(shù)據(jù)時(shí)用

JsonType:枚舉,區(qū)分是什么類型

?

而我們今天只需要使用到JsonObjectJsonArray,首先是JsonObject代表整個(gè)Json對(duì)象,我們可以通過它的靜態(tài)方法Load直接讀取流,比如下面的方式:

1 var text = JsonObject.Load(httpRes.GetResponseStream());

?

?

但是Load返回的是JsonValue,但是大多數(shù)情況都是代表一個(gè)Json對(duì)象,所以我們需要將它強(qiáng)制轉(zhuǎn)換成JsonObject類型,這樣我們就可以讀取其中的T了:

1 var text = (JsonObject)JsonObject.Load(httpRes.GetResponseStream()); 2 var array = (JsonArray)text["T"];

?

?

當(dāng)然我們還需要使用Linq讀取這個(gè)數(shù)組(注意要using System.Linq命名空間

1 var text = (JsonObject)JsonObject.Load(httpRes.GetResponseStream()); 2 var result = (from item in (JsonArray)text["T"] 3 select item.ToString()).ToArray();

?

?

這樣我們獲取了一個(gè)字符串組了,result類型為string[]。為了顯示這個(gè)數(shù)組,我們需要將當(dāng)前的活動(dòng)繼承自ListActivity:

?

然后將代碼修改成如下所示:


1 namespace NetJsonList 2 { 3 [Activity(Label = "NetJsonList", MainLauncher = true, Icon = "@drawable/icon")] 4 public class MainActivity : ListActivity 5 { 6 protected override void OnCreate(Bundle bundle) 7 { 8 base.OnCreate(bundle); 9 LoadXamarin(); 10 } 11 12 public async void LoadXamarin() 13 { 14 //測試用 15 string url = "http://www.xamarin-cn.com/test.json"; 16 17 //創(chuàng)建一個(gè)請(qǐng)求 18 var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url)); 19 var httpRes = (HttpWebResponse)await httpReq.GetResponseAsync(); 20 if (httpRes.StatusCode == HttpStatusCode.OK) 21 { 22 var text = (JsonObject)JsonObject.Load(httpRes.GetResponseStream()); 23 var result = (from item in (JsonArray)text["T"] 24 select item.ToString()).ToArray(); 25 ListAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, result); 26 } 27 } 28 } 29 }

?

?

六、解決翻轉(zhuǎn)后重復(fù)執(zhí)行

做到這步的可以在LoadXamarin中下一個(gè)斷點(diǎn),當(dāng)你點(diǎn)擊模擬器并按下Ctrl+F12翻轉(zhuǎn)后你會(huì)發(fā)現(xiàn)LoadXamarin又重新執(zhí)行了一次。這樣就帶來了一個(gè)問題,有時(shí)候我們僅僅只需要第一次獲取即可,該翻轉(zhuǎn)則會(huì)導(dǎo)致重復(fù)執(zhí)行,那么就會(huì)浪費(fèi)用戶的流量同時(shí)也會(huì)浪費(fèi)資源,所以我們這里就需要能夠?qū)⑦@種狀態(tài)維持,這里我們就需要重寫OnRetainNonConfigurationInstance事件,當(dāng)然該方法需要返回一個(gè)Java.Lang.Object類型的返回值,而這個(gè)返回值就是我們需要保存的狀態(tài),當(dāng)然這個(gè)狀態(tài)不會(huì)存在于OnCreate的bundle中,還是有一個(gè)專門的屬性LastNonConfigurationInstance,這樣我們可以將上面的代碼改寫成如下:

1 namespace NetJsonList 2 { 3 [Activity(Label = "NetJsonList", MainLauncher = true, Icon = "@drawable/icon")] 4 public class MainActivity : ListActivity 5 { 6 class Test : Java.Lang.Object 7 { 8 public string[] Results { get; set; } 9 } 10 11 Test t; 12 13 protected override void OnCreate(Bundle bundle) 14 { 15 base.OnCreate(bundle); 16 LoadXamarin(); 17 } 18 19 //重寫該方法 20 public override Java.Lang.Object OnRetainNonConfigurationInstance() 21 { 22 return t; 23 } 24 25 public async void LoadXamarin() 26 { 27 t = LastNonConfigurationInstance as Test; 28 //判斷是否存在之前的狀態(tài) 29 if (t != null) 30 { 31 ListAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, t.Results); 32 } 33 else 34 { 35 36 //測試用 37 string url = "http://www.xamarin-cn.com/test.json"; 38 39 //創(chuàng)建一個(gè)請(qǐng)求 40 var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url)); 41 var httpRes = (HttpWebResponse)await httpReq.GetResponseAsync(); 42 if (httpRes.StatusCode == HttpStatusCode.OK) 43 { 44 var text = (JsonObject)JsonObject.Load(httpRes.GetResponseStream()); 45 var result = (from item in (JsonArray)text["T"] 46 select item.ToString()).ToArray(); 47 t = new Test() 48 { 49 Results = result 50 }; 51 ListAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, result); 52 } 53 } 54 } 55 } 56 }

?

?

七、小結(jié)

通過上面的學(xué)習(xí)我們僅僅掌握了在跨平臺(tái)下最基礎(chǔ)的網(wǎng)絡(luò)訪問以及Json數(shù)據(jù)解析的方法,還有在活動(dòng)如何保存當(dāng)前的狀態(tài)。

轉(zhuǎn)載于:https://www.cnblogs.com/ShaYeBlog/p/4615574.html

總結(jié)

以上是生活随笔為你收集整理的Xamarin.Android开发实践(四)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。