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的詳細使用。

 

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