xamarin android网络请求总结

版权声明:本文为博主原创文章,未经博主允许转载随意。 https://blog.csdn.net/kebi007/article/details/80373010

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

这里写图片描述

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

  1. 轻量级的、基于HttpWebRequest的封装(不依赖任何第三方组件、支持.net 任何平台上)
  2. 支持异步操作、支持http的get、post、put、delete等操作
  3. 使用简单、易调试、request和response的类型齐全
  4. 功能齐全,支持oAuth 1, oAuth 2, Basic等授权验证、可上传文件
  5. 自定义序列化和反序列化、自动检测返回的内容类型
    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

  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/
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;
        }
    }

猜你喜欢

转载自blog.csdn.net/kebi007/article/details/80373010