在Android中,我們可以通過使用標準的Java介面來完成Android應用程式的連網操作。但是在實際開發中,可能會需要用到更複雜的連網操作,為此,Android平台提供了Apache HttpClient介面,為用戶端的HTTP編程提供了高效、便捷、功能豐富的工具包支援。
Android平台在引入Apache HttpClient的同時,還對其進行了一些封裝和擴充,如設定預設的HTTP逾時和緩衝大小等。使用Apache HttpClient介面,我們可以建立HttpClient、HttpGet/HttpPost、HttpResponse等對象,設定串連參數,執行HTTP操作,處理伺服器返回結果等。
本文將以兩個執行個體示範在Android開發中如何使用HttpClient介面完成用戶端HTTP編程。其中,一個執行個體使用GET方式擷取伺服器上的圖片進行顯示;一個執行個體使用POST方式向伺服器提交資料,完成登入功能。
1.常用的介面和類
在講解執行個體之前,我們有必要先瞭解一下在HttpClient介面中,為我們提供了哪些常用的介面和類。
1.1 ClientConnectionManager介面
ClientConnectionManager是用戶端連線管理員介面,用於對串連到伺服器上的用戶端進行管理,主要提供了以下6個抽象方法:
(1)abstract void closeExpiredConnections();
(2)abstract void closeIdleConnections(long idletime, TimeUnit tunit);
(3)abstract SchemeRegistry getSchemeRegistry();
(4)abstract void releaseConnection(ManagedClientConnection conn, long validDuration, TimeUnit timeUnit);
(5)abstract ClientConnectionRequest requestConnection(HttpRoute route, Object state);
(6)abstract void shutdown();
其中,closeExpiredConnections()方法用於關閉所有到期的串連;closeIdleConnections()方法用於關閉所有閒置串連;getSchemeRegistry()方法用於獲得註冊方案;releaseConnection()方法用於釋放串連;requestConnection()方法用於請求一個新的串連;shutdown()方法用於關閉管理器並釋放資源。
1.2 DefaultHttpClient
DefaultHttpClient是HttpClient介面的一個直接子類,它是一個預設的HTTP用戶端,通常我們可以使用它來建立一個HTTP串連。在HttpClient介面中提供了多個重載的execute()方法,用來執行HTTP請求。
1.3 HttpRequest介面
HttpGet和HttpPost都是HttpRequest介面的直接子類,分別用於向伺服器提交GET請求和POST請求。
1.4 HttpResponse介面
HttpResponse介面提供了HTTP的響應資訊,其主要方法1所示。
圖1 HttpResponse介面提供的主要方法
其中,getEntity()方法用於擷取響應的訊息實體;getStatusLine()方法用於擷取響應的狀態行,在返回結果StatusLine對象中包含了HTTP響應的狀態代碼,可以使用方法getStatusCode()獲得。
2.使用GET方式擷取伺服器上的圖片
在該執行個體中,我們使用了在上一篇博文《Android學習筆記46:使用Post方式提交資料》中搭建好的Web工程作為伺服器,並在該工程中添加了一張名為“cat.jpg”的圖片作為我們將要擷取的對象。
使用GET方式擷取伺服器上的圖片,可以按照以下4個步驟進行:
(1)建立一個GET方式的HttpRequest請求對象。
(2)建立一個預設的HTTP用戶端,並執行該GET方式的HTTP請求。
(3)獲得伺服器的響應碼,據此判斷伺服器是否正確響應。
(4)獲得伺服器的響應內容(InputStream),轉換成Bitmap圖片。
以上4個步驟的具體實現代碼如下:
1 /* 2 * Function : 發送GET請求 3 * Author : 部落格園-依舊淡然 4 */ 5 public static Bitmap sendGetResquest(String path) { 6 Bitmap bitmap = null; 7 HttpGet httpGet = new HttpGet(path); //建立一個GET方式的HttpRequest對象 8 DefaultHttpClient httpClient = new DefaultHttpClient(); //建立一個預設的HTTP用戶端 9 try {10 HttpResponse httpResponse = httpClient.execute(httpGet); //執行GET方式的HTTP請求11 int reponseCode = httpResponse.getStatusLine().getStatusCode(); //獲得伺服器的響應碼12 if(reponseCode == HttpStatus.SC_OK) {13 InputStream inputStream = httpResponse.getEntity().getContent(); //獲得伺服器的響應內容14 bitmap = BitmapFactory.decodeStream(inputStream);15 inputStream.close();16 }17 } catch (ClientProtocolException e) {18 e.printStackTrace();19 } catch (IOException e) {20 e.printStackTrace();21 }22 return bitmap;23 }
最後,我們在Activity中通過一個Button按鈕來向伺服器發送GET請求,並調用sendGetResquest()方法將得到的Bitmap對象顯示在ImageView控制項中。具體的實現代碼如下:
1 /* 2 * Function : 點擊事件響應 3 * Author : 部落格園-依舊淡然 4 */ 5 public void onClick(View view) { 6 switch(view.getId()) { 7 case R.id.button_get: 8 String url = "http://192.168.1.101:8080/myhttp/cat.jpg"; 9 Bitmap bitmap = HttpUtils.sendGetResquest(url);10 mImageView.setImageBitmap(bitmap);11 break;12 }13 }
運行該工程,點擊“提交GET請求”按鈕後,可以看到2所示的顯示介面,在“提交GET請求”按鈕的下面所顯示的圖片正是我們從伺服器上得到的圖片。
圖2 使用GET方式擷取伺服器上的圖片
3.使用POST方式向伺服器提交資料
在該執行個體中,我們同樣使用了在上一篇博文《Android學習筆記46:使用Post方式提交資料》中搭建好的Web工程作為伺服器。運行Tomcat,在瀏覽器中訪問該Web工程,可以看到3所示的介面。
圖3 Web工程的顯示頁面
該執行個體要做的就是,使用POST方式向伺服器提交使用者名稱和密碼,類比登入過程,並獲得伺服器的驗證資訊,顯示登入是否成功。
使用POST方式向伺服器提交資料,比GET方式要稍微複雜點,具體可以按照以下5個步驟進行:
(1)對請求體參數(也就是username和password)進行封裝。
(2)建立一個POST方式的HttpRequest對象,並設定POST方式的請求體。
(3)建立一個預設的HTTP用戶端,並執行該POST方式的HTTP請求。
(4)獲得伺服器的響應碼,據此判斷伺服器是否正確響應。
(5)獲得伺服器的響應內容(InputStream),轉換成String字串進行顯示。
以上5個步驟的具體實現代碼如下:
1 /* 2 * Function : 發送POST請求 3 * Author : 部落格園-依舊淡然 4 */ 5 public static String sendPostResquest(String path, Map<String, String> params, String encoding) { 6 List<NameValuePair> list = new ArrayList<NameValuePair>(); //封裝請求體參數 7 if((params != null) && !params.isEmpty()) { 8 for(Map.Entry<String, String> param : params.entrySet()) { 9 list.add(new BasicNameValuePair(param.getKey(), param.getValue()));10 }11 }12 try {13 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, encoding); //對請求體參數進行URL編碼14 HttpPost httpPost = new HttpPost(path); //建立一個POST方式的HttpRequest對象15 httpPost.setEntity(entity); //設定POST方式的請求體16 DefaultHttpClient client = new DefaultHttpClient();17 HttpResponse httpResponse = client.execute(httpPost); //執行POST請求18 int reponseCode = httpResponse.getStatusLine().getStatusCode(); //獲得伺服器的響應碼19 if(reponseCode == HttpStatus.SC_OK) {20 String resultData = EntityUtils.toString(httpResponse.getEntity()); //獲得伺服器的響應內容21 return resultData;22 }23 } catch (IOException e) {24 e.printStackTrace();25 }26 return "";27 }
同樣的,我們在Activity中通過一個Button按鈕來向伺服器發送POST請求,並調用sendPostResquest()方法將得到的伺服器響應結果顯示在TextView控制項中。具體的實現代碼如下:
1 /* 2 * Function : 點擊事件響應 3 * Author : 部落格園-依舊淡然 4 */ 5 public void onClick(View view) { 6 switch(view.getId()) { 7 case R.id.button_submit: 8 String username = mEditText_userName.getText().toString(); 9 String password = mEditText_password.getText().toString();10 Map<String, String> params = new HashMap<String, String>();11 params.put("username", username);12 params.put("password", password);13 String url = "http://192.168.1.101:8080/myhttp/servlet/LoginAction";14 mTextView_result.setText(HttpUtils.sendPostResquest(url, params, "utf-8"));15 break;16 }17 }
運行該工程,在EditText控制項中分別輸入使用者名稱和密碼,點擊“提交資料”按鈕後,可以看到4所示的顯示介面,在“提交資料”按鈕下面的TextView控制項中可以看到伺服器返回了“Login succeeded!” 的提示資訊。