天天看点

xamarin android网络请求总结

xamarin android中网络请求的框架非常多,在项目中使用的是第三方的一个网络请求框架restsharp,应该是github上.net网络请求最多star的框架,没有之一。这里就简单汇总了其他的一些网络请求的例子,主要还是分为android和.net两种平台。.net 中可以使用HttpWebRequest、HttpClient、RestSharp第三框的一些框架,android的有HttpURLConnectin、HttpClient、OkHttp、Retrofit、Volley
xamarin android网络请求总结

下面就用.net中的httpwebrequest、httpclient、restsharp和android中的httpURLConnection、okhttp实现一个get方式获取图片、post方式提交表单,适合新手入门看看总结一下。 

效果图如下: 

xamarin android网络请求总结

1.HttpWebRquest、HttpWebResponse

命名空间: System.Net;程序集: System(位于 System.dll)

1   public class HttpWebRequestUtil
 2     {
 3         //发送get请求获取bytes
 4         public static async System.Threading.Tasks.Task<byte[]> GetBytes(string path)
 5         {
 6             try
 7             {
 8                 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(path);
 9                 request.Method = "get";
10                 request.Timeout = 500;
11                 //request.Proxy设置代理
12                 //path 中可添加querystring参数
13                 //request.UserAgent 请求的代理
14                 HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
15                 if (response.StatusCode == HttpStatusCode.OK)
16                 {
17                     Stream responseStream = response.GetResponseStream();
18                     //将流转成字节
19                     byte[] bytes = StreamUtil.StreamToBytes(responseStream);
20                     return bytes;
21                 }
22                 else
23                     return null;
24             }
25             catch (Exception ex)
26             {
27                 return null;
28             }
29         }
30 
31         public static async System.Threading.Tasks.Task<bool> PostForm(string path, string name, string pwd)
32         {
33             try
34             {
35                 string formData = "name=" + name +"&pwd=" +pwd ;
36                 byte[] bytes = Encoding.UTF8.GetBytes(formData);
37                 StringBuilder strBuilder = new StringBuilder();
38                 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(path);
39                 request.Method = "get";
40                 request.Timeout = 500;
41                 request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
42                 request.ContentLength = bytes.Length;
43                 request.Method = "Post";
44                 Stream requestStream = request.GetRequestStream();
45                 requestStream.Write(bytes, 0,  bytes.Length);
46                 requestStream.Close();
47 
48                 HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
49                 if (response.StatusCode == HttpStatusCode.OK)
50                 {
51                     StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
52                     string content = JsonConvert.DeserializeObject<string>(streamReader.ReadToEnd());
53                     streamReader.Close();
54                     if (content == "success")
55                     {
56                         return true;
57                     }
58                     else
59                         return false;
60                 }
61                 return false;
62             }
63             catch (Exception ex)
64             {
65                 return false;
66             }
67         }
68     }      

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有一下这么几个重要的有点:

  1. 轻量级的、基于HttpWebRequest的封装(不依赖任何第三方组件、支持.net 任何平台上)
  2. 支持异步操作、支持http的get、post、put、delete等操作
  3. 使用简单、易调试、request和response的类型齐全
  4. 功能齐全,支持oAuth 1, oAuth 2, Basic等授权验证、可上传文件
  5. 自定义序列化和反序列化、自动检测返回的内容类型
1     public class RestSharpUtil
 2     {
 3         internal static RestClient Instance(string url)
 4         {
 5             var restClient = new RestClient(url)
 6             {
 7                 Timeout = 5000,
 8                 ReadWriteTimeout = 5000
 9             };
10             return  restClient;
11         }
12         public static async System.Threading.Tasks.Task<bool> Post(string url, User user)
13         {
14             RestClient restClient = Instance(url);
15             RestRequest request = new RestRequest();
16             //request.AddQueryParameter("id","")  添加url的参数(AddUrlSegment)
17             //request.AddHeader("Authorization","token");添加请求头参数
18             // request.AddHeader("content-type", "application/x-www-form-urlencoded; charset=UTF-8");
19             request.AddJsonBody(user);
20             //request.AddParameter("application/x-www-form-urlencoded; charset=UTF-8", user, ParameterType.RequestBody);
21             var response = await restClient.ExecutePostTaskAsync(request);
22             //var response = await restClient.ExecutePostTaskAsync<string>(request); 自动序列化
23             if (response.StatusCode == System.Net.HttpStatusCode.OK)
24             {
25                 var result = JsonConvert.DeserializeObject<string>(response.Content);
26                 if (result == "success")
27                 {
28                     return true;
29                 }
30                 return false;
31             }
32             else
33             {
34                 return false;
35             }
36         }
37         public static async System.Threading.Tasks.Task<byte[]> Get(string url)
38         {
39             RestClient restClient = Instance(url);
40             RestRequest request = new RestRequest();
41             var response = await restClient.ExecuteGetTaskAsync(request);
42             if (response.StatusCode == System.Net.HttpStatusCode.OK)
43             {
44                 var bytes = response.RawBytes;
45                 return  bytes;
46             }
47             return null;
48         }
49     }      
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。

1   /// <summary>
 2         ///     Serializes obj to format specified by RequestFormat, but passes xmlNamespace if using the default XmlSerializer
 3         ///     The default format is XML. Change RequestFormat if you wish to use a different serialization format.
 4         /// </summary>
 5         /// <param name="obj">The object to serialize</param>
 6         /// <param name="xmlNamespace">The XML namespace to use when serializing</param>
 7         /// <returns>This request</returns>
 8         public IRestRequest AddBody(object obj, string xmlNamespace)
 9         {
10             string serialized;
11             string contentType;
12 
13             // TODO: Make it possible to change the serialiser
14             switch (RequestFormat)
15             {
16                 case DataFormat.Json:
17                     serialized = JsonSerializer.Serialize(obj);
18                     contentType = JsonSerializer.ContentType;
19                     break;
20 
21                 case DataFormat.Xml:
22                     XmlSerializer.Namespace = xmlNamespace;
23                     serialized = XmlSerializer.Serialize(obj);
24                     contentType = XmlSerializer.ContentType;
25                     break;
26 
27                 default:
28                     serialized = "";
29                     contentType = "";
30                     break;
31             }
32 
33             // passing the content type as the parameter name because there can only be
34             // one parameter with ParameterType.RequestBody so name isn't used otherwise
35             // it's a hack, but it works :)
36             return AddParameter(contentType, serialized, ParameterType.RequestBody);
37         }
38 
39         /// <summary>
40         ///     Serializes obj to data format specified by RequestFormat and adds it to the request body.
41         ///     The default format is XML. Change RequestFormat if you wish to use a different serialization format.
42         /// </summary>
43         /// <param name="obj">The object to serialize</param>
44         /// <returns>This request</returns>
45         public IRestRequest AddBody(object obj)
46         {
47             return AddBody(obj, "");
48         }
49 
50         /// <summary>
51         ///     Serializes obj to JSON format and adds it to the request body.
52         /// </summary>
53         /// <param name="obj">The object to serialize</param>
54         /// <returns>This request</returns>
55         public IRestRequest AddJsonBody(object obj)
56         {
57             RequestFormat = DataFormat.Json;
58 
59             return AddBody(obj, "");
60         }      

3.HttpClient

性能上不如httpwebrequest,用的非常少,据说使用的时候要注意不少,这里只是写一个简单的例子,不喜勿喷。 

需要添加引用System.Http.Http

1   public class HttpClientUtil
 2     {
 3         public static async System.Threading.Tasks.Task<byte[]> GetBytes(string path)
 4         {
 5             HttpClient client = new HttpClient();
 6             try
 7             {
 8                 HttpResponseMessage response = await client.GetAsync(path);
 9                 if (response.StatusCode == System.Net.HttpStatusCode.OK)
10                 {
11                     byte[] bytes = await response.Content.ReadAsByteArrayAsync();
12                     return bytes;
13                 }
14                 return null;
15             }
16             catch (Exception ex)
17             {
18                 return null;
19             }
20             finally
21             {
22                 client.Dispose();
23             }
24         }
25 
26         public static async System.Threading.Tasks.Task<bool> PostForm(string path, Dictionary<string,string> _params)
27         {
28 
29                 var handler = new HttpClientHandler() { AutomaticDecompression = System.Net.DecompressionMethods.GZip };
30                 HttpClient client = new HttpClient();
31             try
32             {
33                 client.Timeout = TimeSpan.FromSeconds(5);
34                 //HttpContent httpContent = new StringContent(postData);
35                 //httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
36                 HttpContent httpContent = new FormUrlEncodedContent(_params);
37                 var response = await client.PostAsync(path, httpContent);
38                 if (response.StatusCode == System.Net.HttpStatusCode.OK)
39                 {
40                     string result = await response.Content.ReadAsStringAsync();
41                     result = JsonConvert.DeserializeObject<string>(result);
42                     if (result == "success")
43                         return true;
44                     return false;
45                 }
46                 return false;
47             }
48             catch (Exception ex)
49             {
50                 return false;
51             }
52             finally
53             {
54                 client.Dispose();
55             }
56         }
57     }      
上面介绍了三种.net方面的网络请求的方法,下面就来说说android方面的网络请求HttpUrlConnection、第三方okhttp。

4.HttpURLConnection

httpURLConnection和HttpWebRequest很相似,是java平台上的一种多用途、轻量级的http客户端,提供的api都非常简单,这一点也是好处,可以使得我们非常方便去拓展他。下面我们简单看下如何使用HttpURLConnection。 

引用来自:Java.Net

  1. HttpURLConnection conn = (HttpURLConnection)url.OpenConnection();创建一个URL对象
  2. conn.ConnectTimeout = 5000; conn.RequestMethod = “get”;设置请求方式和连接超时的时间
  3. inputStream = conn.InputStream;获取服务器返回的输入流
  4. 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/ 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;
        }
    }      

继续阅读