標籤:android 網路編程 httpclient httpget
在Android開發中,Android SDK附帶了Apache的HttpClient,它是一個完善的用戶端。它提供了對HTTP協議的全面支援,可以使用HttpClient的對象來執行HTTP GET和HTTP POST調用。
HTTP工作原理:
1.用戶端(一般是指瀏覽器,這裡是指自己寫的程式)與伺服器建立串連
2.建立串連後,用戶端向伺服器發送請求
3.伺服器接收到請求後,向用戶端發送響應資訊
4.用戶端與伺服器中斷連線
HttpClient的一般使用步驟:
1.使用DefaultHttpClient類執行個體化HttpClient對象
2.建立HttpGet或HttpPost對象,將要請求的URL通過構造方法傳入HttpGet或HttpPost對象。
3.調用execute方法發送HTTP GET或HTTP POST請求,並返回HttpResponse對象。
4.通過HttpResponse介面的getEntity方法返迴響應資訊,並進行相應的處理。
最後記得要在AndroidManifest.xml檔案添加網路許可權
<uses-permission android:name="android.permission.INTERNET" />
下面以彙總資料空氣品質城市空氣PM2.5指數資料介面為例來示範使用HttpClient進行Get方式通訊,通過HttpClient建立網路連接,使用HttpGet方法讀取資料,並且通過HttpResponse擷取Entity返回值。
彙總資料空氣品質城市空氣PM2.5指數資料介面API文檔參見:http://www.juhe.cn/docs/api/id/33/aid/79
請求樣本:http://web.juhe.cn:8080/environment/air/pm?city=城市名稱&key=你申請的APPKEY值
執行個體:HttpClientGetDemo
運行效果:
代碼清單:
布局檔案:activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" ><TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="城市:" android:textSize="23sp" /><EditText android:id="@+id/city" android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="3" android:inputType="text" />" </LinearLayout> <Button android:id="@+id/query" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="查詢" android:textSize="23sp" /> <TextViewandroid:id="@+id/result"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>
Java原始碼檔案:MainActivity.java
package com.rainsong.httpclientgetdemo;import java.io.IOException;import java.net.URLEncoder;import java.util.ArrayList;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import android.os.Bundle;import android.os.StrictMode;import android.app.Activity;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity { private static final String JUHE_URL_ENVIRONMENT_AIR_PM = "http://web.juhe.cn:8080/environment/air/pm"; private static final String JUHE_APPKEY = "你申請的APPKEY值"; EditText et_city; Button btn_query; TextView tv_result; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 強制直接在UI線程中進行網路操作 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads().detectDiskWrites().detectNetwork() .penaltyLog().build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects().detectLeakedClosableObjects() .penaltyLog().penaltyDeath().build()); setContentView(R.layout.activity_main); et_city = (EditText)findViewById(R.id.city); tv_result = (TextView)findViewById(R.id.result); btn_query = (Button)findViewById(R.id.query); btn_query.setOnClickListener(new OnClickListener() { public void onClick(View view) { tv_result.setText(""); String city; city = et_city.getText().toString(); if (city.length() < 1) { Toast.makeText(MainActivity.this, "請輸入城市名", Toast.LENGTH_LONG).show(); return; } ArrayList<NameValuePair> headerList = new ArrayList<NameValuePair>(); headerList.add(new BasicNameValuePair("Content-Type", "text/html; charset=utf-8")); String targetUrl = JUHE_URL_ENVIRONMENT_AIR_PM; ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>(); paramList.add(new BasicNameValuePair("key", JUHE_APPKEY)); paramList.add(new BasicNameValuePair("dtype", "json")); paramList.add(new BasicNameValuePair("city", city)); for (int i = 0; i < paramList.size(); i++) { NameValuePair nowPair = paramList.get(i); String value = nowPair.getValue(); try { value = URLEncoder.encode(value, "UTF-8"); } catch (Exception e) { } if (i == 0) { targetUrl += ("?" + nowPair.getName() + "=" + value); } else { targetUrl += ("&" + nowPair.getName() + "=" + value); } } HttpGet httpRequest = new HttpGet(targetUrl); try { for (int i = 0; i < headerList.size(); i++) { httpRequest.addHeader(headerList.get(i).getName(), headerList.get(i).getValue()); } HttpClient httpClient = new DefaultHttpClient(); HttpResponse httpResponse = httpClient.execute(httpRequest); if (httpResponse.getStatusLine().getStatusCode() == 200) { String strResult = EntityUtils.toString(httpResponse.getEntity()); tv_result.setText(strResult); } else { Toast.makeText(MainActivity.this, "查詢失敗", Toast.LENGTH_LONG).show(); tv_result.setText(""); } } catch (IOException e) { e.printStackTrace(); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }}
註:本來不應該直接在UI線程進行網路操作,會阻塞UI,影響使用者體驗。但為了不引入其他知識點,把焦點聚集在HttpClient網路通訊上,在本例中強制直接在UI線程中進行網路操作。在下篇文章中會介紹如何避免直接在UI線程中進行網路操作。
API知識點
public interface
HttpClient
org.apache.http.client.HttpClient
Known Indirect Subclasses
AbstractHttpClient, AndroidHttpClient, DefaultHttpClient
Class Overview
Interface for an HTTP client. HTTP clients encapsulate a smorgasbord of objects required to execute HTTP requests while handling cookies, authentication, connection management, and other features. Thread safety of HTTP clients depends on the implementation and configuration of the specific client.
abstract HttpResponse
execute(HttpUriRequest request)
Executes a request using the default context.
public class
DefaultHttpClient
extends AbstractHttpClient
org.apache.http.impl.client.DefaultHttpClient
Class Overview
Default implementation of an HTTP client.
Public Constructor
DefaultHttpClient()
Creates a new HTTP client.
public class
HttpGet
extends HttpRequestBase
Inherited Methods
From class org.apache.http.client.methods.HttpRequestBase
From class org.apache.http.message.AbstractHttpMessage
From class java.lang.Object
From interface org.apache.http.HttpMessage
From interface org.apache.http.HttpRequest
From interface org.apache.http.client.methods.AbortableHttpRequest
From interface org.apache.http.client.methods.HttpUriRequest
Public Constructors
HttpGet()
HttpGet(URI uri)
HttpGet(String uri)
abstract void addHeader(String name, String value)
Adds a header to this message.
public interface
HttpResponse
implements HttpMessage
org.apache.http.HttpResponse
Class Overview
An HTTP response.
abstract HttpEntity getEntity()
Obtains the message entity of this response, if any.
abstract StatusLine getStatusLine()
Obtains the status line of this response.
public interface
NameValuePair
org.apache.http.NameValuePair
Known Indirect Subclasses
BasicNameValuePair
Class Overview
A simple class encapsulating an attribute/value pair.
Public Methods
abstract String getName()
abstract String getValue()
public class
BasicNameValuePair
extends Object
implements Cloneable NameValuePair
org.apache.http.message.BasicNameValuePair
Public Constructors
BasicNameValuePair(String name, String value)
Default Constructor taking a name and a value.
Android網路編程之使用HttpClient進行Get方式通訊