Android常用网络框架分析HttpClient、HttpURLConnection、Volley、OkHttp

一、HttpClient:

HttpClient本人用的比较少,然后进行了一些了解,主要有以下几个方面:

  1. HttpClient是Apache的一个第三方网络框架,对网络请求封装的比较完善,有众多的api,比较稳定。
  2. 扩展性不强,android5.0被废弃,6.0逐渐删除。
  3. 创建HttpClient对象,对于get请求,再创建HttpGet对象,对于post请求,再创建HttpPost对象。
  4. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HttpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
  5. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse。
  6. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。

二、HttpURLConnection

  1. HttpURLConnection比较轻量级,对网络请求的封装没有HttpClient完善,用起来也没有那么方便。
  2. HttpURLConnection对象不能直接构造,需要通过URL类中的openConnection()方法来获得。
  3. 对HttpURLConnection对象的配置需要在connect方法执行之前完成。
  4. HttpURLConnection是基于HTTP协议的,底层通过socket通信实现,需要设置请求方式和超时。
  5. HttpURLConnection通过getInputStream()返回一个输入流,从中获取服务器对于HTTP请求的返回信息。对于post请求方式,需要通过getOutputStream()流写入,写入到缓冲区中。
  6. 由于HttpURLConnection调用 close() 函数会影响连接池,导致连接复用失效,若使用需要关闭keepAlive,极大的不方便,每次HTTP请求都有。
  7. HttpUrlConnection现在的底层实现是通过Okhttp
//开启线程来发起网络请求
new Thread(new Runnable() {
    @Override
    public void run() {
        HttpURLConnection connection = null;
        try {
            URL url = new URL("https://www.baidu.com");
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(8000);
            connection.setReadTimeout(8000);
            connection.connect();
            //如果是Post方式时
//          String params = "abc";
//          OutputStream out = connection.getOutputStream();
//          out.write(params.getBytes());
//          out.flush();
//          out.close();
            InputStream in = connection.getInputStream();
            //下面对获取到的输入流进行读取
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null){
                response.append(line);
            }

            Message message = new Message();
            message.what = SHOW_RESPONSE;
            //将服务器返回的结果存放到Message中
            message.obj = response.toString();
            handler.sendMessage(message);
//                    showResponse(response.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            if(connection != null){
                connection.disconnect();
            }
        }
    }
}).start();

三、Volley

  1. Volley适合处理数据量小,通信频繁的网络操作;在处理大数据量的请求时,表现不好,因为在内部使用的是字节数组缓存池ByteArrayPool(维护了两个List集合),每次从缓冲区取空间,不必每次存数据都进行内存分配,减少GC。
  2. Volley内部封装了异步线程,可直接在主线程请求网络并处理返回的结果。
  3. 容易扩展,支持HttpClient、HttpURLConnection、甚至OkHttp,也封装了ImageLoader。
  4. Volley可以取消请求。
  5. 一个缓存线程,4个网络线程。

关于Volley的详细使用,可以去看我的另一篇文章:最简单详细的Volley使用解析

四、okhttp

  1. 谷歌官方在6.0以后移除了httpClient,加入了okhttp
  2. okhttp是专注于提升网络连接效率的http客户端,支持连接同一地址的链接重用同一个socket,避免了每次都创建socket再断开socket,通过连接池来减小响应延迟。
  3. okhttp支持SPDY(是谷歌开发的基于TCP的应用层协议,用于最小化网络延迟,提升网络速度,优化用户的网络使用体验. SPDY并不是一种替代http的协议,只是对http的一种增强)。
  4. okhttp支持http和https,支持连接池、GZIP和HTTP缓存。
  5. 成熟的网络请求解决方案,比HttpURLConnection更好用。
  6. OkHttp基于NIO和Okio,在性能上也就更快。
  7. 缺点是okhttp请求网络切换回来是在线程里面的,不是在主线程,不能直接刷新UI,需要我们手动处理。封装比较麻烦。

okhttp发起网络请求:

  • 构建 OkHttpClient 客户端
  • 构建 Request 请求
  • 创建 Call 对象,发起网络请求
  • 处理 Response 响应结果

使用:同步get请求

new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            //构建okHttp客户端
            OkHttpClient client = new OkHttpClient();
            //构建请求报文
            Request request = new Request.Builder().url("https://www.baidu.com").build();
            //发起同步请求,返回响应报文
            Response response = client.newCall(request).execute();
            //获取响应体
            String responseData = response.body().string();
            showResponse(responseData);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();

异步get请求

OkHttpClient client = new OkHttpClient.Builder()
            .readTimeout(5, TimeUnit.SECONDS).build();
    final Request request = new Request.Builder().url("https://www.baidu.com").get().build();
    Call call = client.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.i("MainActivity",e.toString());
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.i("MainActivity",Thread.currentThread().getName());
            //运行在子线程中,所以必须在主线程中更改UI
            showResponse(response.body().string());
        }
    });

番外篇:

  • Retrofit也是Square公司开发的,默认基于OkHttp封装的一套RESTful网络请求框架,可以使用不同的http客户端,同时支持RxJava,目前使用比较多的是Retrofit+OkHttp+RxJava+Dagger2
  • 对于RetrofitOkHttp来说,肯定首选Retrofit,因为Retrofit默认就是基于OkHttp进行的封装
  • IO(阻塞式IO)NIO(非阻塞式)的区别:如果从硬盘读取数据,IO就是程序会一直等,数据读完后才能继续操作;NIO是你读你的数据,程序接着往下执行,等数据处理完你再来通知我,然后再处理回调。 所以NIO当然要比IO的性能要好了。而 Okio是 Square 公司基于IO和NIO基础上做的一个更简单、高效处理数据流的一个库。
  • Retrofit2.0优化了很多地方,相比较Volley来说,Retrofit默认OkHttp,再结合RxJava的话,Retrofit应该更好一点。当然一般简单项目可以使用Volley
  • RxVolley是基于Volley框架现在又比较流行的框架。RxVolley=Volley+RxJava+OkHttp。怎么说呢,这个框架用起来还是很不错的,不过我的了解现在还不够深入,等着熟悉了之后再更新RxVolley的详细使用。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章