最近準備一個關於Android的比賽。因爲賽項要求,不得使用第三方工具、框架;故最近來溫習一下Google官方提供的原始API的使用。api
說實話,用慣了第三方的庫,再回過頭來用原生的api的確使人以爲麻煩,不過也不能僅僅依賴於各類層出不窮的框架和庫,掌握相對底層的核心點,纔是競爭力的來源。而且用了第三方的庫以後再來看原生,不經意間就會有好的思路產生。網絡
那麼,今天就來簡單介紹一下HttpUrlConnect的基本使用,和筆者本身作的一個小的工具類封裝。app
Ps: 解釋以註釋形式寫在代碼中框架
* GET請求異步
new Thread(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請求ide
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();
Ps:爲何不封裝的更完善些呢?好比支持支持Get請求、支持自定義Http頭部各參數設置,異步消息部分採用Handle或AsynTask。其實剛剛說的這些包括尚未想到的,均可以添加上去,只是筆者時間緊迫,因此如下的工具類只提供Post方式的請求。函數
工具類支持:工具
下面貼工具類代碼,和簡單的使用方法:post
/** * 做者: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上,雖然水平通常,但開源精神仍是可讚的嘛😀