xamarin android 中网络请求的框架非常多, 在项目中使用的是第三方的一个网络请求框架 restsharp, 应该是 github 上. net 网络请求最多 star 的框架, 没有之一. 这里就简单汇总了其他的一些网络请求的例子, 主要还是分为 android 和. net 两种平台..net 中可以使用 HttpWebRequest,HttpClient,RestSharp 第三框的一些框架, android 的有 HttpURLConnectin,HttpClient,OkHttp,Retrofit,Volley
下面就用. net 中的 httpwebrequest,httpclient,restsharp 和 android 中的 httpURLConnection,okhttp 实现一个 get 方式获取图片, post 方式提交表单, 适合新手入门看看总结一下.
效果图如下:
1.HttpWebRquest,HttpWebResponse
命名空间: System.Net; 程序集: System(位于 System.dll)
- public class HttpWebRequestUtil
- {
- // 发送 get 请求获取 bytes
- public static async System.Threading.Tasks.Task<byte[]> GetBytes(string path)
- {
- try
- {
- HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(path);
- request.Method = "get";
- request.Timeout = 500;
- //request.Proxy 设置代理
- //path 中可添加 querystring 参数
- //request.UserAgent 请求的代理
- HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
- if (response.StatusCode == HttpStatusCode.OK)
- {
- Stream responseStream = response.GetResponseStream();
- // 将流转成字节
- byte[] bytes = StreamUtil.StreamToBytes(responseStream);
- return bytes;
- }
- else
- return null;
- }
- catch (Exception ex)
- {
- return null;
- }
- }
- public static async System.Threading.Tasks.Task<bool> PostForm(string path, string name, string pwd)
- {
- try
- {
- string formData = "name=" + name +"&pwd=" +pwd ;
- byte[] bytes = Encoding.UTF8.GetBytes(formData);
- StringBuilder strBuilder = new StringBuilder();
- HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(path);
- request.Method = "get";
- request.Timeout = 500;
- request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
- request.ContentLength = bytes.Length;
- request.Method = "Post";
- Stream requestStream = request.GetRequestStream();
- requestStream.Write(bytes, 0, bytes.Length);
- requestStream.Close();
- HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
- if (response.StatusCode == HttpStatusCode.OK)
- {
- StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
- string content = JsonConvert.DeserializeObject<string>(streamReader.ReadToEnd());
- streamReader.Close();
- if (content == "success")
- {
- return true;
- }
- else
- return false;
- }
- return false;
- }
- catch (Exception ex)
- {
- return false;
- }
- }
- }
2.RestSharp .net 常用的 http 网络请求库
当然重点还是说一下这个的. restsharp 在 github 上的 star 应该是. net 网络请求库最多的,(和第二名的差距比较大). 可以在 nuget 上直接添加引用 restsharp.
github 地址: https://github.com/restsharp/RestSharp
restSharp 官网: http://restsharp.org/
stackoverflow 上 restsharp 的相关问题汇总: https://stackoverflow.com/questions/tagged/RestSharp
restsharp 有一下这么几个重要的有点:
轻量级的, 基于 HttpWebRequest 的封装 (不依赖任何第三方组件, 支持. net 任何平台上)
支持异步操作, 支持 http 的 get,post,put,delete 等操作
使用简单, 易调试, request 和 response 的类型齐全
功能齐全, 支持 oAuth 1, oAuth 2, Basic 等授权验证, 可上传文件
自定义序列化和反序列化, 自动检测返回的内容类型
- public class RestSharpUtil
- {
- internal static RestClient Instance(string url)
- {
- var restClient = new RestClient(url)
- {
- Timeout = 5000,
- ReadWriteTimeout = 5000
- };
- return restClient;
- }
- public static async System.Threading.Tasks.Task<bool> Post(string url, User user)
- {
- RestClient restClient = Instance(url);
- RestRequest request = new RestRequest();
- //request.AddQueryParameter("id","") 添加 url 的参数 (AddUrlSegment)
- //request.AddHeader("Authorization","token"); 添加请求头参数
- // request.AddHeader("content-type", "application/x-www-form-urlencoded; charset=UTF-8");
- request.AddJsonBody(user);
- //request.AddParameter("application/x-www-form-urlencoded; charset=UTF-8", user, ParameterType.RequestBody);
- var response = await restClient.ExecutePostTaskAsync(request);
- //var response = await restClient.ExecutePostTaskAsync<string>(request); 自动序列化
- if (response.StatusCode == System.Net.HttpStatusCode.OK)
- {
- var result = JsonConvert.DeserializeObject<string>(response.Content);
- if (result == "success")
- {
- return true;
- }
- return false;
- }
- else
- {
- return false;
- }
- }
- public static async System.Threading.Tasks.Task<byte[]> Get(string url)
- {
- RestClient restClient = Instance(url);
- RestRequest request = new RestRequest();
- var response = await restClient.ExecuteGetTaskAsync(request);
- if (response.StatusCode == System.Net.HttpStatusCode.OK)
- {
- var bytes = response.RawBytes;
- return bytes;
- }
- return null;
- }
- }
post 请求和 get 请求在编码类型不同, get: 仅一种 application/x-www-form-urlencoded,post:application/x-www-form-urlencoded 或 multipart/form-data...... 等多种编码方式.
restsharp 在发送 post 请求方式时必须设置 header 的 content-type 解码方式.
request.AddJsonBody(user); 等同于:
request.AddParameter("application/x-www-form-urlencoded; charset=UTF-8", user, ParameterType.RequestBody); 等同于:
- request.RequestFormat =DataFormat.Json;
- request.AddBody(user);
这里备注一下以前犯的一个错误, 用了 AddBody 方法必须添加 request.RequestFormat =DataFormat.Json; , 不然会出异常
我们看看下面的 AddBody 的源码可以知道, 除 restsharp,.net 第三方的网络请求框架还有 flurl.http.
- /// <summary>
- /// Serializes obj to format specified by RequestFormat, but passes xmlNamespace if using the default XmlSerializer
- /// The default format is XML. Change RequestFormat if you wish to use a different serialization format.
- /// </summary>
- /// <param name="obj">The object to serialize</param>
- /// <param name="xmlNamespace">The XML namespace to use when serializing</param>
- /// <returns>This request</returns>
- public IRestRequest AddBody(object obj, string xmlNamespace)
- {
- string serialized;
- string contentType;
- // TODO: Make it possible to change the serialiser
- switch (RequestFormat)
- {
- case DataFormat.Json:
- serialized = JsonSerializer.Serialize(obj);
- contentType = JsonSerializer.ContentType;
- break;
- case DataFormat.Xml:
- XmlSerializer.Namespace = xmlNamespace;
- serialized = XmlSerializer.Serialize(obj);
- contentType = XmlSerializer.ContentType;
- break;
- default:
- serialized = "";
- contentType = "";
- break;
- }
- // passing the content type as the parameter name because there can only be
- // one parameter with ParameterType.RequestBody so name isn't used otherwise
- // it's a hack, but it works :)
- return AddParameter(contentType, serialized, ParameterType.RequestBody);
- }
- /// <summary>
- /// Serializes obj to data format specified by RequestFormat and adds it to the request body.
- /// The default format is XML. Change RequestFormat if you wish to use a different serialization format.
- /// </summary>
- /// <param name="obj">The object to serialize</param>
- /// <returns>This request</returns>
- public IRestRequest AddBody(object obj)
- {
- return AddBody(obj, "");
- }
- /// <summary>
- /// Serializes obj to JSON format and adds it to the request body.
- /// </summary>
- /// <param name="obj">The object to serialize</param>
- /// <returns>This request</returns>
- public IRestRequest AddJsonBody(object obj)
- {
- RequestFormat = DataFormat.Json;
- return AddBody(obj, "");
- }
- 3.HttpClient
性能上不如 httpwebrequest, 用的非常少, 据说使用的时候要注意不少, 这里只是写一个简单的例子, 不喜勿喷.
需要添加引用 System.Http.Http
- public class HttpClientUtil
- {
- public static async System.Threading.Tasks.Task<byte[]> GetBytes(string path)
- {
- HttpClient client = new HttpClient();
- try
- {
- HttpResponseMessage response = await client.GetAsync(path);
- if (response.StatusCode == System.Net.HttpStatusCode.OK)
- {
- byte[] bytes = await response.Content.ReadAsByteArrayAsync();
- return bytes;
- }
- return null;
- }
- catch (Exception ex)
- {
- return null;
- }
- finally
- {
- client.Dispose();
- }
- }
- public static async System.Threading.Tasks.Task<bool> PostForm(string path, Dictionary<string,string> _params)
- {
- var handler = new HttpClientHandler() { AutomaticDecompression = System.Net.DecompressionMethods.GZip };
- HttpClient client = new HttpClient();
- try
- {
- client.Timeout = TimeSpan.FromSeconds(5);
- //HttpContent httpContent = new StringContent(postData);
- //httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
- HttpContent httpContent = new FormUrlEncodedContent(_params);
- var response = await client.PostAsync(path, httpContent);
- if (response.StatusCode == System.Net.HttpStatusCode.OK)
- {
- string result = await response.Content.ReadAsStringAsync();
- result = JsonConvert.DeserializeObject<string>(result);
- if (result == "success")
- return true;
- return false;
- }
- return false;
- }
- catch (Exception ex)
- {
- return false;
- }
- finally
- {
- client.Dispose();
- }
- }
- }
上面介绍了三种. net 方面的网络请求的方法, 下面就来说说 android 方面的网络请求 HttpUrlConnection, 第三方 okhttp.
4.HttpURLConnection
httpURLConnection 和 HttpWebRequest 很相似, 是 java 平台上的一种多用途, 轻量级的 http 客户端, 提供的 api 都非常简单, 这一点也是好处, 可以使得我们非常方便去拓展他. 下面我们简单看下如何使用 HttpURLConnection.
引用来自: Java.Net
HttpURLConnection conn = (HttpURLConnection)url.OpenConnection(); 创建一个 URL 对象
conn.ConnectTimeout = 5000; conn.RequestMethod = "get"; 设置请求方式和连接超时的时间
inputStream = conn.InputStream; 获取服务器返回的输入流
conn.Disconnect(); 最后调用 disconnect 方法将 http 连接关掉
- public class HttpUrlConnecUtil
- {
- /// <summary>
- /// get 方式获取 byte 数组
- /// </summary>
- /// <param name="path"></param>
- /// <returns></returns>
- public static byte[] getImage(string path)
- {
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection)url.OpenConnection();
- conn.ConnectTimeout = 5000;
- conn.RequestMethod = "GET";// 小写会报错
- System.IO.Stream inputStream=null;
- try
- {
- if (conn.ResponseCode == HttpStatus.Ok)
- {
- inputStream = conn.InputStream;
- return StreamUtil.StreamToBytes(inputStream);
- }
- return null;
- }
- catch (Exception ex)
- {
- return null;
- }
- finally
- {
- inputStream.Close();
- conn.Disconnect();
- }
- }
- public static string post(string path,string name,string pwd)
- {
- string result = string.Empty;
- HttpURLConnection conn = (HttpURLConnection)new URL(path).OpenConnection();
- conn.RequestMethod = "POST";
- conn.ReadTimeout = 5000;
- conn.ConnectTimeout = 5000;
- // 设置运行输入, 输出
- conn.DoOutput = true;
- conn.DoInput = true;
- //post 方式不能缓存, 需要手动设置 false
- conn.UseCaches = false;
- string data = "name=" + URLEncoder.Encode(name, "UTF-8") + "&pwd=" + URLEncoder.Encode(pwd,"UTF-8");
- Stream outSteam=null;
- // 获取输出流
- try
- {
- outSteam = conn.OutputStream;
- outSteam.Write(Encoding.UTF8.GetBytes(data), 0, data.Length);
- outSteam.Flush();
- if (conn.ResponseCode == HttpStatus.Ok)
- {
- Stream input = conn.InputStream;
- byte[] bytes = StreamUtil.StreamToBytes(input);
- result = bytes.ToString();
- }
- return result;
- }
- catch (Exception ex)
- {
- return "";
- }
- finally {
- outSteam.Close();
- conn.Disconnect();
- }
- }
- }
- /// <summary>
- /// 将流转成 byte 数组
- /// </summary>
- /// <param name="stream"></param>
- /// <param name="bytes"></param>
- public static byte[] StreamToBytes(Stream stream)
- {
- MemoryStream memoryStream = new MemoryStream();
- byte[] buffer = new byte[64 * 1024];
- int i;
- try
- {
- while ((i = stream.Read(buffer, 0, buffer.Length))> 0)
- {
- memoryStream.Write(buffer, 0, i);
- }
- var bytes = memoryStream.ToArray();
- return bytes;
- }
- catch (Exception ex)
- {
- return null;
- }
- finally {
- memoryStream.Close();
- stream.Close();
- }
- }
5.OkHttp 最火的 android 网络请求框架
okhttp 是一个第三方的网络请求框架, 被广泛适用于 android 中请求网络数据, 是一个一个轻量级的框架, 有移动支付 Square 公司贡献 (Picasso 和 LeakCanary), 和 HttpURLConnection 和 api 是一致的. 在 xamarin android 中使用的时候需要在 nuget 中添加引用 OkHttp, 命名空间: using Square.OkHttp3;
okhttp 官网: http://square.github.io/okhttp/
github 地址: https://github.com/square/okhttp
除了 okhttp 外, android 中比较流行的网络请求框架还有
retrofit,retrofit2 依赖于 okhttp;github 地址: http://square.github.io/retrofit/ , 拓展性比较强
volley:google 在 2013 年推出的 android 异步网络请求框架和图片加载框架
下面看看, 如何在 xamarin android 中使用 okhttp 发送 get,post 请求吧.
- public class OkHttpClientUtil
- {
- private OkHttpClient httpClient;
- public OkHttpClientUtil()
- {
- httpClient = new OkHttpClient.Builder()
- .ConnectTimeout(5, TimeUnit.Seconds)// 连接超时 5 秒
- .WriteTimeout(5, TimeUnit.Seconds)// 写入数据超时 5 秒
- .ReadTimeout(5, TimeUnit.Seconds)// 读取数据超时 5 秒
- .Build();
- }
- public static OkHttpClientUtil Instance()
- {
- return new OkHttpClientUtil();
- }
- public async System.Threading.Tasks.Task<bool> Post(string url, User user)
- {
- FormBody.Builder formBody = new FormBody.Builder(); // 创建表单请求体
- formBody.Add("name", user.Name);
- formBody.Add("pwd", user.Pwd);
- Request request = new Request.Builder().AddHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").Url(url).Post(formBody.Build()).Build();
- var response = await httpClient.NewCall(request).ExecuteAsync();
- if (response.Code() == 200)
- {
- var result =JsonConvert.DeserializeObject<string>(response.Body().String());
- if (result == "success")
- {
- return true;
- }
- return false;
- }
- return false;
- }
- public async System.Threading.Tasks.Task<byte[]> Get(string url)
- {
- Request request = new Request.Builder().Url(url).Build();
- Response response = await httpClient.NewCall(request).ExecuteAsync();
- if (response.Code() == 200)
- {
- var stream = response.Body().ByteStream();
- var bytes = StreamUtil.StreamToBytes(stream);
- return bytes;
- }
- return null;
- }
- }
来源: https://www.cnblogs.com/zhangmumu/p/9081726.html