Android回顧系列——之HttpUrlConnect的使用
阿新 • • 發佈:2018-01-25
nco 留言 要求 idc stream extends value tput 回調
寫在前面:
最近準備一個關於Android的比賽。由於賽項要求,不得使用第三方工具、框架;故最近來溫習一下Google官方提供的原始API的使用。
說實話,用慣了第三方的庫,再回過頭來用原生的api的確令人覺得麻煩,不過也不能僅僅依賴於各種層出不窮的框架和庫,掌握相對底層的核心點,才是競爭力的來源。並且用了第三方的庫之後再來看原生,不經意間就會有好的思路產生。
那麽,今天就來簡單介紹一下HttpUrlConnect的基本使用,和筆者自己做的一個小的工具類封裝。
先來學習原生的使用:
Ps: 解釋以註釋形式寫在代碼中
* GET請求
newThread(new Runnable() { @Override public void run() { //接口地址 String url_path = "http://223.111.182.5:8080/logistics/goods/myOffer"; try{ //使用該地址創建一個 URL 對象 URL url = new URL(url_path);//使用創建的URL對象的openConnection()方法創建一個HttpURLConnection對象 HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection(); /** * 設置HttpURLConnection對象的參數 */ // 設置請求方法為 GET 請求 httpURLConnection.setRequestMethod("GET");//使用輸入流 httpURLConnection.setDoInput(true); //GET 方式,不需要使用輸出流 httpURLConnection.setDoOutput(false); //設置超時 httpURLConnection.setConnectTimeout(10000); httpURLConnection.setReadTimeout(1000); //連接 httpURLConnection.connect(); //還有很多參數設置 請自行查閱 //連接後,創建一個輸入流來讀取response BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(),"utf-8")); String line = ""; StringBuilder stringBuilder = new StringBuilder(); String response = ""; //每次讀取一行,若非空則添加至 stringBuilder while((line = bufferedReader.readLine()) != null){ stringBuilder.append(line); } //讀取所有的數據後,賦值給 response response = stringBuilder.toString().trim(); Utils.log(" 打印響應 " + response); final String finalResponse = response; //切換到ui線程更新ui runOnUiThread(new Runnable() { @Override public void run() { result.setText(finalResponse); } }); bufferedReader.close(); httpURLConnection.disconnect(); }catch (Exception e){ e.printStackTrace(); } } }).start();
* POST請求
new Thread(new Runnable() { //創建HttpURLConnection變量 HttpURLConnection httpURLConnection = null; //創建PrintWriter變量,用於向HttpURLConnection寫入請求參數 PrintWriter printWriter = null; //創建BufferedReader,來接收相應數據流 BufferedReader bufferedReader = null; //定義緩沖 StringBuilder stringBuilder = new StringBuilder(); //定義line讀取一行數據 String line = ""; //定義接口地址 String url_path = "http://xxx.xxx.xxx.xxx:8080/logistics/goods/bidCount"; //模擬參數 String para = "goodId=14"; String response = ""; @Override public void run() { try{ URL url = null; if(url_path.equals("")){ return; } //使用接口地址初始化URL對象 url = new URL(url_path); //使用URL對象創建HttpURLConnection對象 httpURLConnection = (HttpURLConnection) url.openConnection(); //設置相應參數 httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); //可以創建輸出流,將請求參數寫入 httpURLConnection.setRequestMethod("POST"); //請求方式為POST //將請求參數寫入連接的輸出流 printWriter = new PrintWriter(httpURLConnection.getOutputStream()); printWriter.print(para); printWriter.flush(); //獲取響應結果 bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(),"utf-8")); while ((line = bufferedReader.readLine()) != null){ stringBuilder.append(line); } response = stringBuilder.toString().trim(); //切換主線程更新ui runOnUiThread(new Runnable() { @Override public void run() { result.setText(response); } }); }catch (Exception e){ e.printStackTrace(); }finally { try{ /** * 關閉連接/流 */ if(printWriter != null){ printWriter.close(); } if(bufferedReader != null){ bufferedReader.close(); } if(httpURLConnection != null){ httpURLConnection.disconnect(); } }catch (Exception e){ e.printStackTrace(); } } } }).start();
下面貼一個自己寫的一個Post請求工具類:
Ps:為什麽不封裝的更完善些呢?比如支持支持Get請求、支持自定義Http頭部各參數設置,異步消息部分采用Handle或AsynTask。其實剛剛說的這些包括還沒有想到的,都可以添加上去,只是筆者時間緊迫,所以以下的工具類只提供Post方式的請求。
工具類支持:
-
- 自定義參數(傳參時,只要傳入相對應的map)
- 支持接口回調,在回調方法內寫結果處理邏輯
- 簡單的線程控制,開發者不需要手動實現線程切換
- 簡單易用的API
下面貼工具類代碼,和簡單的使用方法:
/** * 作者:LiChangXin * Created by haiyang on 2018/1/25. * 簡介: * 1.自定義參數(傳參時,只要傳入相對應的map) * 2.支持接口回調,在回調方法內寫結果處理邏輯 * 3.簡單的線程控制,開發者不需要手動實現線程切換 * 4.簡單易用的API */ public class XykjHttpPost extends Thread{ /** * 通過構造函數 * 賦值: * url - 接口地址 * form - 請求參數(map) * xykjHttpCall - 回調接口 * mactivity - 基於activity的runOnUiThread()方法的線程控制 */ private String url = ""; private Map<String,String> form; private XykjHttpCall xykjHttpCall = null; private Activity mactivity; //下面這些 與之前的例子相同 private HttpURLConnection connection = null; private PrintWriter pw = null; private BufferedReader bufferedReader = null; private String line = null; private StringBuilder response_cache = new StringBuilder(); private String response = null; private String parameter = null; //構造函數 public XykjHttpPost(XykjHttpCall xykjHttpCall,String url_p, Map<String,String> form_p, Activity activity){ url = url_p; form = form_p; this.xykjHttpCall = xykjHttpCall; mactivity = activity; } @Override public void run() { Utils.log("XYKJHTTPPOST : " + "Thread@run() 方法開始執行"); try{ if(url.equals("") || url == null){ //若url為空,結束執行 Utils.log("XYKJHTTPPOST : " + "無請求參數"); return; } URL url_path = new URL(url.trim()); connection = (HttpURLConnection) url_path.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.setRequestMethod("POST"); //獲取連接 connection.connect(); if(!form.isEmpty() && form != null){ //獲取連接輸出流,並寫入表單參數 pw = new PrintWriter(connection.getOutputStream()); parameter = formDataConnect(form); pw.print(parameter); pw.flush(); } //獲取響應 輸入流 bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream())); while ((line = bufferedReader.readLine()) != null){ response_cache.append(line); } response = response_cache.toString().trim(); Utils.log("XYKJHTTPPOST : RESPONSE -> " + response); mactivity.runOnUiThread(new Runnable() { @Override public void run() { if(response != null && !response.equals("")){ xykjHttpCall.success(response); }else { xykjHttpCall.error("Response為空"); } } }); }catch (Exception e){ mactivity.runOnUiThread(new Runnable() { @Override public void run() { xykjHttpCall.error("XYKJHTTPPOST : 網絡請求/解析異常"); } }); Utils.log("XYKJHTTPPOST : 網絡請求/解析異常"); e.printStackTrace(); }finally { try{ if(pw != null){ pw.close(); } if(bufferedReader != null){ bufferedReader.close(); } if(connection != null){ connection.disconnect(); } }catch (Exception e){ mactivity.runOnUiThread(new Runnable() { @Override public void run() { xykjHttpCall.error("XYKJHTTPPOST : 關閉連接/流異常"); } }); Utils.log("XYKJHTTPPOST : 關閉連接/流異常"); e.printStackTrace(); } } } /** * 參數轉換函數 * map -> http[post] 參數 * @param form_data * @return */ public String formDataConnect(Map<String,String> form_data){ StringBuilder url_form = new StringBuilder(); //遍歷map,按照url參數形式拼接 for(String key:form_data.keySet()){ if(url_form.length() != 0){ //從第二個參數開始,每個參數key、value前添加 & 符號 url_form.append("&"); } url_form.append(key).append("=").append(form_data.get(key)); } return url_form.toString(); } /** * 定義回調接口 */ public interface XykjHttpCall { void success(String response); void error(String error_message); } /** * 線程啟動 * 執行請求 */ public void request(){ this.start(); } }
* 使用方法:
先上業務場景,是一個用戶的登錄操作,收集 手機號碼和密碼 後進行post請求驗證。
最後調用該對象的request()方法,即可啟動post請求。
* 效果:
Ok,今天的營養目標達成。
有什麽問題或者有好的想法的可以在評論裏留言,筆者會在第一時間解答。
未來的話,如果筆者繼續搞Android,會慢慢來豐富這個工具類,屆時會開源到Github上,雖然水平一般,但開源精神還是可贊的嘛??
Android回顧系列——之HttpUrlConnect的使用