Android网络请求框架比较学习
来源:互联网 发布:wind资讯金融终端 mac 编辑:程序博客网 时间:2024/06/07 23:51
学习Android的Http通信以来,接触了很多网络请求框架,尝试了他们各自的用法,但是没有做过系统的总结,以及对Http通信的理解,所以决定全面的整理一下Android实现Http通信过程,和各个网络请求框架的比较,加深学习印象。
Http请求简介
HyperText Transfer Protocol,超文本传输协议,是网络层的传输协议,Android和服务器通信通常采用HTTP通信和TCP通信,Android完全支持JDK本身的TCP,UDP网络通信,也支持JDK提供的URL,URLConnection,HttpURLConnection等网络通信API.
HttpURLConnection
首先要了解URL(uniform resource locator),他就像指向网络资源的指针,由协议名,主机,端口,和资源组成,通过函数openConnection()
可以返回一个URLConnection对象。URLConnection表示应用程序和URL之间的通信连接,程序通过URLConnection的实例就可以实现向URL发送请求,读取URL应用的资源。
在Java中基础的Http请求访问步骤如下:
- 调用URL实例的openConnection()方法创建URLConnection对象
- 设置URLConnection参数和普通请求属性
- 如果只是发送GET请求,使用
connect()
方法建立和远程资源之间实际连接即可,如果发送POST请求,需要获取URLConnection对应的输出流来发送请求参数 - 连接建立,可以访问远程资源的头字段,也可以通过输入流来读取远程资源的数据
实现代码
public class HttpThread extends Thread { private String url; private WebView webView; private Handler handler; public HttpThread(String url,WebView webView,Handler handler){ this.url=url; this.webView =webView; this.handler =handler; } @Override public void run() { try { URL murl = new URL(url); try { //建立连接 URLConnection coon =murl.openConnection(); coon.setConnectTimeout(5000); coon.connect(); //读取资源 InputStreamReader inputStreamReader =new InputStreamReader(coon.getInputStream()); BufferedReader bufferedReader =new BufferedReader(inputStreamReader); String str; final StringBuffer sb =new StringBuffer(); while((str=bufferedReader.readLine())!=null){ sb.append(str); } //显示资源 handler.post(new Runnable() { @Override public void run() { webView.loadData(sb.toString(),"text/html;charset=utf-8",null); } }); } catch (IOException e) { e.printStackTrace(); } } catch (MalformedURLException e) { e.printStackTrace(); } }}
而HttpConnection类是继承了URLConnection,也是用于向指定服务器发送GET,POST请求,也就是说他是URLConnection的进阶,他实现Http请求步骤如下:
1. 调用URL的openConnection()方法创建HttpURLConnection实例
2. 设置HttpURLConnection参数和普通请求属性
3. 使用setRequestMethond()
方法确定发送哪种请求,如果发送POST请求,需要发送需要的请求参数。
4. 连接建立,可以访问远程资源的头字段,也可以通过输入流来读取远程资源的数据
实现代码:
public class HttpURLThread extends Thread { private String url; private WebView webView; private Handler handler; public HttpURLThread(String url,WebView webView,Handler handler){ this.url=url; this.webView =webView; this.handler =handler; } @Override public void run() { try { URL mUrl =new URL(url); try { HttpURLConnection httpCoon =(HttpURLConnection) mUrl.openConnection(); httpCoon.setConnectTimeout(5000); httpCoon.setRequestMethod("GET"); if(httpCoon.getResponseCode() == HttpURLConnection.HTTP_OK){ InputStreamReader in =new InputStreamReader(httpCoon.getInputStream()); BufferedReader br =new BufferedReader(in); final StringBuilder response = new StringBuilder(); String line; while((line=br.readLine())!=null){ response.append(line); } handler.post(new Runnable() { @Override public void run() { webView.loadData(response.toString(),"text/html;charset=utf-8",null); } }); } } catch (IOException e) { e.printStackTrace(); } } catch (MalformedURLException e) { e.printStackTrace(); } }}
HttpClient
在一般情况下,如果只是需要向web站点的某个简单页面提交请求并获取服务器响应,HttpURLConnection就可以完成,但是对于大部分应用程序而言JDK本身提供的网络功能已远远不够,比如需要用户登录而且具有相应的权限才可以访问某个页面,还有涉及session和cookie的处理等。
为了解决这个问题,Android提供了Apache HttpClient,一个开源项目,功能更加完善,为客户端的Http编程提供高效、最新、功能丰富的工具包支持。
看名字就可以对HttpClient揣摩一二,他是一个简单的Http客户端而不是浏览器,可以用于发送HTTP请求,接受HTTP响应,但不会缓存服务器的响应,不能执行HTML界面中嵌入的JavaScript代码,也不会对页面内容进行任何解析,处理。换句话说:他很专注,他只会关注发送请求,响应请求,以及管理HTTP连接,其他多余的事情他是不会去做的。
通过HttpClient访问被保护资源时,程序需要使用HttpClient来登陆系统,只要程序使用了同一个HttpClient发送请求,HttpClient会自动维护与服务器之间的Session状态,也就是说程序第一次使用HttpClient登陆系统后,接下来使用HttpClient即可访问被保护的资源,这一点和浏览器实现访问被保护资源很像(也是维护与服务器之间的Session)。
如果我们要使用HttpClient的话,使用步骤如下:
- 创建一个DefaultHttpClient实例
- 如果要发起Get请求,需要创建一个HttpGet对象,并传入请求地址;如果要发起Post请求,需要创建一个HttpPost对象。并传入请求地址,通过setEntity函数设置请求参数
- 调用execute方法,传入HttpGet或者HttpPost实例,执行后返回HttpResponse对象,判断响应状态码
- 解析响应结果,通过调用getEntity函数获得一个HttpEntity对象,之后可以通过EntityUtils.toString方法将其转换为字符串。
以GET请求为例
private String get(String url){ HttpClient client=null; HttpGet request=null; try { client=new DefaultHttpClient(); request=new HttpGet(url); HttpResponse response=client.execute(request); if(response.getStatusLine().getStatusCode()== HttpStatus.SC_OK){ String result=EntityUtils.toString(response.getEntity(),"UTF-8"); return result; } } catch (IOException e) { e.printStackTrace(); } return null; }
至此,让我们先来简单比较一下HttpUrlConnection和HttpClient,Android系统最开始使用的网络请求是HttpURLConnection,为了提高http访问的高效和稳定,又引入了HttpClient,但随着时间发展,加之HttpClient的维护成本高昂,android开发团队不愿意再维护HttpClient,而转投开始维护更为轻便的HttpURLConnection,因为HttpURLConnection更加的轻便,灵活,易于扩展。
在android3.0以后及4.0中都对HttpURLConnection进行了改善,添加了对于https的支持,4.0以后还添加了对缓存的支持。
目前的情况是Android6.0已经废弃了HttpClient。所以基于HttpClient的网络请求框架也是不建议再使用的。
AsyncHttpClient
正如之前提到的,AsyncHttpClient 就是基于HttpClient的网络请求架构,所以这个库现在不建议使用了。
我接触这个库并使用还是在大二的时候,由他的名字也可以看出他的特点,异步的HttpClient,所有请求独立在UI主线程之外,通过回调方法处理请求结果,采用Handler-Message机制传递信息。
总结AsyncHttpClient的特点:
- 所以请求在子线程中完成,请求回调在调用该请求的线程中完成
- 使用线程池
- 使用RequestParams类封装请求参数
- 支持文件上传
- 持久化cookie到SharedPreferences,个人感觉这一点也是这个库的重要特点,可以很方便的完成一些模拟登录
- 支持json
- 支持HTTP Basic Auth
volley
既然在android2.2之后不建议使用Http Client,那么有没有一个库是android2.2及以下版本使用Http Client,而android2.3及以上版本使用HttpUrlConnection的呢,答案是肯定的,就是Volley,它是android开发团队在2013年Google I/O大会上推出了一个新的网络通信框架
volley的出现主要是为了提高网络通信的速度和简化网络通信的步骤。Volley可是说是把AsyncHttpClient和Universal-Image-Loader的优点集于了一身,既可以像AsyncHttpClient一样非常简单地进行HTTP通信,也可以像Universal-Image-Loader一样轻松加载网络上的图片。
它提供了如下的便利功能:
- JSON,图像等的异步下载;
- 网络请求的排序(scheduling)
- 网络请求的优先级处理
- 缓存
- 多级别取消请求
- 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求)
它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。
使用volley进行网络通信,主要步骤如下:
创建一个RequestQueue对象。
创建一个Request对象。
将Request对象添加到RequestQueue里面。
以GET请求为例:
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this); String url ="http://www.baidu.com"; StringRequest stringRequest =new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { Log.d("TAG",response.toString()); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }); requestQueue.add(stringRequest);
对于post请求,我们需要重载Request中的getParams()方法来添加对应参数(volley中没有直接设置post参数的方法)
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener) { @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> map = new HashMap<String, String>(); map.put(“params1”, “value1”); map.put(“params2”, “value2”); return map; }};
加载图片和上面类似,只不过把StringRequest换成ImageRequest,他们都是继承自抽象类Request的具体实现类,由此我们也可以看出volley的可扩展性,在实际应用的时候,我们完全可以创建继承Request的自定义Rquest,你可以自由的在里面添加和修改任何的方法,方便你自己的使用。
此外,Volley提供了一个新的控件NetworkImageView来代替传统的ImageView,该控件的图片属性可以通过setImageUrl(url, imageLoader)
来进行设置,而且这个控件在被从父控件detach的时候,会自动取消网络请求的,即完全不用我们担心相关网络请求的生命周期问题。
okHttp
okHttp是Java的HTTP+SPDY客户端开发包,支持Android(2.3以上),我学习的是okHttp3的使用,它相较2.X和1.X使用稍微有些变化,功能更加多,整体使用基本没有区别。
okHttp使用步骤:
- AS开发环境下添加依赖
compile 'com.squareup.okhttp3:okhttp:3.6.0'
okHttp内部依赖okio,因此还需要添加依赖compile 'com.squareup.okio:okio:1.11.0'
- 创建OkHttpClient
- 创建Request (builder模式创建)
- 让OkHttpClient创建request对应的call
- call将请求加入调度,请求结果由callBack处理
以异步get请求为例:
private void doAsyncGet() { mOkHttpClient = new OkHttpClient(); Request.Builder builder =new Request.Builder(); builder.url("http://www.baidu.com") .method("GET",null); Request request =builder.build(); Call call =mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { Log.d(TAG,response.body().string()); } }); }
需要注意的点:
onResponse回调的参数是response,一般情况下,如果我们希望获得返回的字符串,可以通过
response.body().string()
获取,如果希望返回二进制数组,可以调用response.body().bytes()
,如果想返回inputstream,可以调用response.body().byteStream()
对于call,我们可以异步执行,也可以以阻塞的方式运行,如果希望异步,则调用
call.enqueue()
;如果希望阻塞,则调用call.execute()
如果请求方式为post,对应的参数应该在参数体中,通过FormBody.Builder()添加需要的键值对,然后构造RequestBody,在
post(RequestBody)
中直接传入即可
至于okHttp的文件上传下载,在此不做展开,记录于具体的okHttp学习中。
总结okHttp的特点:
- OKHttp是Android版Http客户端。非常高效,支持SPDY、连接池、GZIP和 HTTP 缓存。
- 默认情况下,OKHttp会自动处理常见的网络问题,像二次连接、SSL的握手问题。
- 如果你的应用程序中集成了OKHttp,Retrofit默认会使用OKHttp处理其他网络层请求。
- 从Android4.4开始HttpURLConnection的底层实现采用的是okHttp.
Retrofit
retrofit是由square公司开发的REST安卓客户端请求库,对于Android开发者来说,无疑是很好的选择,Retrofit的底层是基于okHttp实现的,他的优点很多:
- 性能最好,处理最快
- 使用REST API时非常方便;
- 传输层默认就使用OkHttp;
- 支持NIO;
- 拥有出色的API文档和社区支持
- 速度上比volley更快;
- 如果你的应用程序中集成了OKHttp,Retrofit默认会使用OKHttp处理其他网络层请求。
- 默认使用Gson
Retrofit不同于前几种网络请求框架,他在使用的时候,将请求地址转化成了接口,通过 注解 来指定访问方式,请求参数,请求头,返回值等信息,还可以结合okhttp实现请求相关操作,比如设置cookie,修改请求头信息,拦截信息等。
关于Retrofit的具体使用可以参考之前的文章: Retrofit初了解 在这里就不做赘述了。
- Android网络请求框架比较学习
- android开发之网络请求框架比较
- Android网络请求框架Volley学习
- Android 网络请求框架Volley学习笔记
- iOS 网络请求框架比较
- Android网络请求框架
- Android 网络请求 框架
- Android 网络框架比较
- Android网络框架比较
- Android学习 各大网络请求库的比较
- iOS网络请求框架的比较
- 各大网络请求框架的比较
- Android 的OkHttp 网络请求框架的学习封装
- Android学习--网络请求
- Android简易网络请求框架
- Android网络请求框架 Volley
- Android网络请求框架--AsyncHttpClient
- 轻量级Android网络请求框架
- 4.11 N!
- 【WebLogic使用】2.在Eclipse中添加WebLogic
- 测试工具
- linux基础2-10selinux的管理
- Java学习【知识点及代码5】
- Android网络请求框架比较学习
- 如何配置一台深度学习主机?
- BZOJ1269 文本编辑器 (Splay)
- 线性表
- 在Python中使用lambda高效操作列表的教程
- Python学习笔记(9):函数调用与定义
- 利用switch语句编写一个程序,把用数字表示的成绩转化为字母表示的等级。连续查询50次结束
- java-实现分页功能
- HDU 4858 项目管理(分桶法)