Xamarin.Android下获取与解析JSON
一、新建项目
1.新建一个Android项目,并命名为为NetJsonList

2.右击引用,选择添加引用,引用System.Json.dll

二、同步请求
既然是跨平台,我们自然不能按照java下的方式进行编写,否则如何跨平台呢,所以我们需要使用Syste.Net命名空间下的两个类:HttpWebRequest和HttpWebResponse。
首先打开Resources/layout/Main.axml文件

删除其他上面的控件,并拖拽一个Text(large)到其中。
接着打开MainActivity.cs文件,并将如下代码写入其中
namespace NetJsonList
{
[Activity(Label = "NetJsonList", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
TextView tv; protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main); tv = FindViewById<TextView>(Resource.Id.textView1); LoadXamarin();
} public void LoadXamarin()
{
//测试用
string url = "http://www.xamarin-cn.com/test.json"; //创建一个请求
var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url)); //获取响应
var httpRes = (HttpWebResponse)httpReq.GetResponse(); //读取响应的字符串
String text = new StreamReader(httpRes.GetResponseStream()).ReadToEnd();
tv.Text = text;
}
}
}
这里我们通过HttpWebRequest的Create静态方法创建了一个请求,那么下面我们可以获取响应了,笔者这里直接使用StreamReader读取了,以便显示出来。
注:如果要在在短时间内高频率的使用HTTP请改用HttpURLConnection。
最终显示的结果如下所示:

但是我们在编码的过程中绝对不能这么做,因为这样会使UI线程阻塞。意思就是用户使用这个app时会出现卡顿,这样对于任何一个人使用者来说都是很难忍受的,所以下面我们要采用异步的方式来实现。
三、异步请求
首先我们先把异步请求回调的方法写出来:
//异步回调方法
public void ReadXamarin(IAsyncResult asyn)
{
var httpReq = (HttpWebRequest)asyn.AsyncState; //获取响应
using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse(asyn))
{
//判断是否成功获取响应
if (httpRes.StatusCode == HttpStatusCode.OK)
{
//读取响应
var text = new StreamReader(httpRes.GetResponseStream()).ReadToEnd(); //切换到UI线程,否则无法对控件进行操作
RunOnUiThread(() =>
{
tv.Text = text;
});
}
}
}
通过AsyncState获取HttpWebRequest的引用,然后再调用其EndGetResponse方法获取响应,并将响应的字符串显示,特别需要注意的是我们这里使用了RunOnUiThread方法,因为异步回调的方法不是使用UI线程执行的,这也是为什么这样做就不会阻塞UI线程了。
当然有了异步操作的回调方法,自然在调用的时候需要使用特殊的方法:
public void LoadXamarin()
{
//测试用
string url = "http://www.xamarin-cn.com/test.json"; //创建一个请求
var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
httpReq.BeginGetResponse(new AsyncCallback(ReadXamarin), httpReq);
}
所有的代码如下所示:
namespace NetJsonList
{
[Activity(Label = "NetJsonList", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
TextView tv; protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main); tv = FindViewById<TextView>(Resource.Id.textView1); LoadXamarin();
} public void LoadXamarin()
{
//测试用
string url = "http://www.xamarin-cn.com/test.json"; //创建一个请求
var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
httpReq.BeginGetResponse(new AsyncCallback(ReadXamarin), httpReq);
} //异步回调方法
public void ReadXamarin(IAsyncResult asyn)
{
var httpReq = (HttpWebRequest)asyn.AsyncState; //获取响应
using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse(asyn))
{
//判断是否成功获取响应
if (httpRes.StatusCode == HttpStatusCode.OK)
{
//读取响应
var text = new StreamReader(httpRes.GetResponseStream()).ReadToEnd(); //切换到UI线程,否则无法对控件进行操作
RunOnUiThread(() =>
{
tv.Text = text;
});
}
}
}
}
}
四、利用await的异步请求
通过c# 5.0 的新特性await我们可以写更少的代码实现异步,我们修改LoadXamarin方法:
public async void LoadXamarin()
{
//测试用
string url = "http://www.xamarin-cn.com/test.json"; //创建一个请求
var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
var httpRes = (HttpWebResponse)await httpReq.GetResponseAsync();
if (httpRes.StatusCode == HttpStatusCode.OK)
{
var text = new StreamReader(httpRes.GetResponseStream()).ReadToEnd();
tv.Text = text;
}
}
可以看到我们给这个方法加了一个async关键字,如果不加这个关键字,在该方法中是无法使用await的,下面我们就看到了这句代码:
var httpRes = (HttpWebResponse)await httpReq.GetResponseAsync();
当Ui线程执行到这句后,直接就会跳过去,不会等待。当然下面的方法也不会去执行了,只有当这个方法返回了结果之后,UI线程才会回到这句代码,并继续执行下面的方法。当然这些只是障眼法,其实c#已经把下面的代码作为了异步回调执行的方法了:
if (httpRes.StatusCode == HttpStatusCode.OK)
{
var text = new StreamReader(httpRes.GetResponseStream()).ReadToEnd();
tv.Text = text;
}
并且执行的线程依然是之前执行该方法的线程,如果你创建一个新的线程去执行。那么就必须使用RunOnUiThread方法了。还有一个缺点就是不能在其中进行复杂的运算,否则还是会造成UI线程的阻塞。
五、解析JSON
在开始本节前,必须确保引用了正确的System.Json类库,否则无法使用。
首先我们先看看json数据的格式:
{
"T": [
"T1",
"T2",
"T3",
"T4"
]
}
知道了json数据格式了,我们还要理解下System.Json中有哪些类:
JsonValue:是基础类,代表一个Json值
JsonObject:继承JsonValue,代表一个Json对象
JsonArray:继承JsonValue,代表一个Json数组
JsonPrimitive:继承JsonValue,组织Json数据时用
JsonType:枚举,区分是什么类型
而我们今天只需要使用到JsonObject和JsonArray,首先是JsonObject代表整个Json对象,我们可以通过它的静态方法Load直接读取流,比如下面的方式:
var text = JsonObject.Load(httpRes.GetResponseStream());
但是Load返回的是JsonValue,但是大多数情况都是代表一个Json对象,所以我们需要将它强制转换成JsonObject类型,这样我们就可以读取其中的T了:
var text = (JsonObject)JsonObject.Load(httpRes.GetResponseStream());
var array = (JsonArray)text["T"];
当然我们还需要使用Linq读取这个数组(注意要using System.Linq命名空间)
var text = (JsonObject)JsonObject.Load(httpRes.GetResponseStream());
var result = (from item in (JsonArray)text["T"]
select item.ToString()).ToArray();
这样我们获取了一个字符串组了,result类型为string[]。为了显示这个数组,我们需要将当前的活动继承自ListActivity:

然后将代码修改成如下所示:
namespace NetJsonList
{
[Activity(Label = "NetJsonList", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : ListActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
LoadXamarin();
} public async void LoadXamarin()
{
//测试用
string url = "http://www.xamarin-cn.com/test.json"; //创建一个请求
var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
var httpRes = (HttpWebResponse)await httpReq.GetResponseAsync();
if (httpRes.StatusCode == HttpStatusCode.OK)
{
var text = (JsonObject)JsonObject.Load(httpRes.GetResponseStream());
var result = (from item in (JsonArray)text["T"]
select item.ToString()).ToArray();
ListAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, result);
}
}
}
}
六、解决翻转后重复执行
做到这步的可以在LoadXamarin中下一个断点,当你点击模拟器并按下Ctrl+F12翻转后你会发现LoadXamarin又重新执行了一次。这样就带来了一个问题,有时候我们仅仅只需要第一次获取即可,该翻转则会导致重复执行,那么就会浪费用户的流量同时也会浪费资源,所以我们这里就需要能够将这种状态维持,这里我们就需要重写OnRetainNonConfigurationInstance事件,当然该方法需要返回一个Java.Lang.Object类型的返回值,而这个返回值就是我们需要保存的状态,当然这个状态不会存在于OnCreate的bundle中,还是有一个专门的属性LastNonConfigurationInstance,这样我们可以将上面的代码改写成如下:
namespace NetJsonList
{
[Activity(Label = "NetJsonList", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : ListActivity
{
class Test : Java.Lang.Object
{
public string[] Results { get; set; }
} Test t; protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
LoadXamarin();
} //重写该方法
public override Java.Lang.Object OnRetainNonConfigurationInstance()
{
return t;
} public async void LoadXamarin()
{
t = LastNonConfigurationInstance as Test;
//判断是否存在之前的状态
if (t != null)
{
ListAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, t.Results);
}
else
{ //测试用
string url = "http://www.xamarin-cn.com/test.json"; //创建一个请求
var httpReq = (HttpWebRequest)HttpWebRequest.Create(new Uri(url));
var httpRes = (HttpWebResponse)await httpReq.GetResponseAsync();
if (httpRes.StatusCode == HttpStatusCode.OK)
{
var text = (JsonObject)JsonObject.Load(httpRes.GetResponseStream());
var result = (from item in (JsonArray)text["T"]
select item.ToString()).ToArray();
t = new Test()
{
Results = result
};
ListAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, result);
}
}
}
}
}
七、小结
通过上面的学习我们仅仅掌握了在跨平台下最基础的网络访问以及Json数据解析的方法,还有在活动如何保存当前的状态。
Xamarin.Android下获取与解析JSON的更多相关文章
- Android中使用Gson解析JSON数据的两种方法
Json是一种类似于XML的通用数据交换格式,具有比XML更高的传输效率;本文将介绍两种方法解析JSON数据,需要的朋友可以参考下 Json是一种类似于XML的通用数据交换格式,具有比XML更高的 ...
- Android中使用Gson解析JSON数据
Android中使用Gson解析JSON数据 在Android中可以使用Gson解析JSON数据 首先,从 code.google.com/p/google-gson/downloads/list ...
- android下获取无线wif信号、ssid、MAC等操作类
一个android下获取无线wif信号.ssid.MAC等操作的类. WifiAdmin.java package com.afu; import java.util.List; import and ...
- Android下获取FPS的几种方法
FPS(Frames Per Second)是关乎Android用户体验最为重要的指标之一,而在VR中更是如此.为了评估VR系统.VR SDK及Unity应用的性能,通常会实时获取FPS并将其显示出来 ...
- Mono for android 访问Webservice和WebApi以及获取和解析JSON
先看效果,注意:(1)这里由于我的模拟器不支持中文输入,所以,对于这张效果图,我是直接在代码中写死了我的查询城市,在下面的代码中我是没有把要查询的城市写死的. (2)读者要想成功使用本示例的所有代码的 ...
- Android 下用 Pull 解析和生成 XML
Java 中是可以用 SAX 和 DOM 解析 XML 的,虽然在 Android 下也可以用这2中方式,但是还是推荐用 Pull.Pull 使用简单,效率相对高,Android 下是集成了 Pul ...
- 【Android进阶】Gson解析json字符串的简单应用
在客户端与服务器之间进行数据传输,一般采用两种数据格式,一种是xml,一种是json.这两种数据交换形式各有千秋,比如使用json数据格式,数据量会比较小,传输速度快,放便解析,而采用xml数据格式, ...
- Android开发中如何解析Json
解析Json 有了请求,自然会有响应,那我们该如何解析服务端响应返回给我们的Json数据呢? 了解什么是Json JSON(JavaScript object notation)是一种轻量级的数据交换 ...
- android使用Gson来解析json
Gson是一种对象的解析json,非常好用,介绍一个站点http://json.parser.online.fr/能够帮我们看一个字符串是不是Json 对于Json文件 { "id" ...
随机推荐
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
- 从零开始编写自己的C#框架(27)——什么是开发框架
前言 做为一个程序员,在开发的过程中会发现,有框架同无框架,做起事来是完全不同的概念,关系到开发的效率.程序的健壮.性能.团队协作.后续功能维护.扩展......等方方面面的事情.很多朋友在学习搭建自 ...
- SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
Insert是T-sql中常用语句,Insert INTO table(field1,field2,...) values(value1,value2,...)这种形式的在应用程序开发中必不可少.但我 ...
- 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之集群概念介绍(一)
集群概念介绍(一)) 白宁超 2015年7月16日 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习 ...
- 玩转spring boot——开篇
很久没写博客了,而这一转眼就是7年.这段时间并不是我没学习东西,而是园友们的技术提高的非常快,这反而让我不知道该写些什么.我做程序已经有十几年之久了,可以说是彻彻底底的“程序老炮”,至于技术怎么样?我 ...
- BPM配置故事之案例10-获取外部数据
老李:Hi,小明,我又来了 小明:--这次又怎么了. 老李:之前的物资管理方式太混乱了,这段时间我整理了采购物资清单,现在都录入到我们的ERP中了,以后申请物资改成从ERP数据选择吧.物资明细表我也做 ...
- git基本操作
一.在Windows平台上安装Git,可以下载一个msysGit的安装包,点击exe即可安装运行.安装包下载地址:https://git-for-windows.github.io/备注:git命令行 ...
- 解决开启服务器防火墙导致ftp不能连接的问题
在防火墙设置的"高级"选项卡中的"网络连接设置"--"本地连接"--"设置"中添加了"FTP服务器" ...
- 《徐徐道来话Java》:PriorityQueue和最小堆
在讲解PriorityQueue之前,需要先熟悉一个有序数据结构:最小堆. 最小堆是一种经过排序的完全二叉树,其中任一非终端节点数值均不大于其左孩子和右孩子节点的值. 可以得出结论,如果一棵二叉树满足 ...
- NodeJs 开发微信公众号(三)微信事件交互
微信公众号有个规则,一旦开启了开发者模式,其他的常规功能就都必须通过接口调用完成.比如说自定义菜单功能,必须通过发送post请求的方式生成.本章就通过关注到取消关注的整个过程来谈一谈nodejs是怎么 ...