Android網絡請求1--HttpClient與HttpURLConnection


在早期的時候,Android上還沒有像VolleyOkHttpRetrofit這些優秀的開源庫,如果想要使用網絡請求的話,就只能自己封裝HttpClientHttpURLConnection。現在我們就來看下Apache的這兩個類。

1. HttpClient

2.1 導入HttpClient

由於從Android 6.0 開始,谷歌就將HttpClient從Android中刪除了,所以若現在想使用他,還得導入依賴:
在項目的build.gradleAndroid代碼塊下加入依賴,示例:

android {
    useLibrary 'org.apache.http.legacy'
    ...
}

2.2 HttpClient的Get

首先通過DefaultHttpClient來實例化一個HttpClient,並配置好參數:

 //創建HttpClient
private HttpClient createHttpClient() {
    HttpParams mDefaultHttpParams = new BasicHttpParams();
    //設置連接超時
    HttpConnectionParams.setConnectionTimeout(mDefaultHttpParams, 15000);
    //設置請求超時
    HttpConnectionParams.setSoTimeout(mDefaultHttpParams, 15000);
    HttpConnectionParams.setTcpNoDelay(mDefaultHttpParams, true);
    HttpProtocolParams.setVersion(mDefaultHttpParams, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(mDefaultHttpParams, HTTP.UTF_8);
    //持續握手
    HttpProtocolParams.setUseExpectContinue(mDefaultHttpParams, true);
    HttpClient mHttpClient = new DefaultHttpClient(mDefaultHttpParams);
    return mHttpClient;
}

接着創建HttpGetHttpClient,請求網絡並得到HttpResponse,並對HttpResponse進行處理:

private void useHttpClientGet(String url) {
    HttpGet mHttpGet = new HttpGet(url);
    mHttpGet.addHeader("Connection", "Keep-Alive");
    try {
        HttpClient mHttpClient = createHttpClient();
        HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);
        HttpEntity mHttpEntity = mHttpResponse.getEntity();
        int code = mHttpResponse.getStatusLine().getStatusCode();
        if (null != mHttpEntity) {
            InputStream mInputStream = mHttpEntity.getContent();
            String respose = converStreamToString(mInputStream);
            Log.i("wangshu", "請求狀態碼:" + code + "\n請求結果:\n" + respose);
            mInputStream.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

converStreamToString()方法將請求結果轉換成String類型:

private String converStreamToString(InputStream is) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuffer sb = new StringBuffer();
    String line = null;
    while ((line = reader.readLine()) != null) {
        sb.append(line + "\n");
    }
    String respose = sb.toString();
    return respose;
}

最後開啓線程訪問:

new Thread(new Runnable() {
    @Override
    public void run() {
        useHttpClientGet("http://www.baidu.com");
    }
}).start();

1.3 HttpClient的POST

和GET差不多,只需要修改傳遞的參數:

private void useHttpClientPost(String url) {
    HttpPost mHttpPost = new HttpPost(url);
    mHttpPost.addHeader("Connection", "Keep-Alive");
    try {
        HttpClient mHttpClient = createHttpClient();
        List<NameValuePair> postParams = new ArrayList<>();
        //要傳遞的參數
        postParams.add(new BasicNameValuePair("username", "moon"));
        postParams.add(new BasicNameValuePair("password", "123"));
        mHttpPost.setEntity(new UrlEncodedFormEntity(postParams));
        HttpResponse mHttpResponse = mHttpClient.execute(mHttpPost);
        HttpEntity mHttpEntity = mHttpResponse.getEntity();
        int code = mHttpResponse.getStatusLine().getStatusCode();
        if (null != mHttpEntity) {
            InputStream mInputStream = mHttpEntity.getContent();
            String respose = converStreamToString(mInputStream);
            Log.i("wangshu", "請求狀態碼:" + code + "\n請求結果:\n" + respose);
            mInputStream.close();
        }
    } catch (IOException e) {
            e.printStackTrace();
    }
}

2. HttpURLConnection

HttpURLConnectionHttpClient來說更輕量,而且他API也比HttpClient簡單。特別是Android 6.0HttpClient移除之後,現在只能使用HttpURLConnection

2.1 HttpURLConnection的POST請求

首先我們創建一個UrlConnManager類,然後裏面提供getHttpURLConnection()方法用於配置默認的參數並返回HttpURLConnection:

public static HttpURLConnection getHttpURLConnection(String url){
    HttpURLConnection mHttpURLConnection=null;
    try {
        URL mUrl=new URL(url);
        mHttpURLConnection=(HttpURLConnection)mUrl.openConnection();
        //設置鏈接超時時間
        mHttpURLConnection.setConnectTimeout(15000);
        //設置讀取超時時間
        mHttpURLConnection.setReadTimeout(15000);
        //設置請求參數
        mHttpURLConnection.setRequestMethod("POST");
        //添加Header
        mHttpURLConnection.setRequestProperty("Connection","Keep-Alive");
        //接收輸入流
        mHttpURLConnection.setDoInput(true);
        //傳遞參數時需要開啓
        mHttpURLConnection.setDoOutput(true);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return mHttpURLConnection ;
}

因爲我們要發送POST請求,所以在UrlConnManager類中再寫一個postParams()方法用來組織一下請求參數並將請求參數寫入到輸出流中:

public static void postParams(OutputStream output,List<NameValuePair>paramsList) throws IOException{
    StringBuilder mStringBuilder=new StringBuilder();
    for (NameValuePair pair:paramsList){
        if(!TextUtils.isEmpty(mStringBuilder)){
            mStringBuilder.append("&");
        }
        mStringBuilder.append(URLEncoder.encode(pair.getName(),"UTF-8"));
        mStringBuilder.append("=");
        mStringBuilder.append(URLEncoder.encode(pair.getValue(),"UTF-8"));
    }
    BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(output,"UTF-8"));
    writer.write(mStringBuilder.toString());
    writer.flush();
    writer.close();
}

接下來我們添加請求參數,調用postParams()方法將請求的參數組織好傳給HttpURLConnection的輸出流,請求連接並處理返回的結果:

private void useHttpUrlConnectionPost(String url) {
    InputStream mInputStream = null;
    HttpURLConnection mHttpURLConnection = UrlConnManager.getHttpURLConnection(url);
    try {
        List<NameValuePair> postParams = new ArrayList<>();
        //要傳遞的參數
        postParams.add(new BasicNameValuePair("username", "moon"));
        postParams.add(new BasicNameValuePair("password", "123"));
        UrlConnManager.postParams(mHttpURLConnection.getOutputStream(), postParams);
        mHttpURLConnection.connect();
        mInputStream = mHttpURLConnection.getInputStream();
        int code = mHttpURLConnection.getResponseCode();
        String respose = converStreamToString(mInputStream);
        Log.i("wangshu", "請求狀態碼:" + code + "\n請求結果:\n" + respose);
        mInputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

最後開啓線程請求網絡:

private void useHttpUrlConnectionGetThread() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            useHttpUrlConnectionPost("http://www.baidu.com");
        }
    }).start();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章