Android之网络----使用HttpClient发送HTTP请求(通过get方法获取数据)
【正文】
一、HTTP協(xié)議初探:
HTTP(Hypertext Transfer Protocol)中文 “超文本傳輸協(xié)議”,是一種為分布式,合作式,多媒體信息系統(tǒng)服務(wù),面向應用層的協(xié)議,是Internet上目前使用最廣泛的應用層協(xié)議,它基于傳輸層的TCP協(xié)議進行通信,HTTP協(xié)議是通用的、無狀態(tài)的協(xié)議。
這幾個名詞有一種通俗的解釋:
通訊協(xié)議:雙方對話的標準通用的:用了都說好,誰用誰知道無狀態(tài)的:翻臉不認人超文本:除了文本,還可以是音頻、視頻
HTTP協(xié)議與Android開發(fā)之間的關(guān)系:
HTTP協(xié)議的學習重點:
Http協(xié)議基礎(chǔ)概念、請求響應模型、提交請求的不同方法、響應狀態(tài)判斷、獲取響應以及解析響應、數(shù)據(jù)下載的實現(xiàn)方法、數(shù)據(jù)上傳的實現(xiàn)方法、請求頭詳細內(nèi)容、響應頭詳細內(nèi)容等
關(guān)于http協(xié)議的學習,推薦兩個鏈接:
http://www.cnblogs.com/TankXiao/archive/2012/02/13/2342672.html
http://blog.csdn.net/gueter/article/details/1524447
二、http協(xié)議概念:
1、http協(xié)議定義:
WWW是以Internet作為傳輸媒介的一個應用系統(tǒng),WWW網(wǎng)上基本的傳輸單位是Web網(wǎng)頁。WWW的工作是基于客戶機/服務(wù)器計算模型,由Web瀏覽器和Web服務(wù)器構(gòu)成,兩者之間采用超文本傳輸協(xié)議HTTP進行通信。
HTTP協(xié)議時基于TCP/IP協(xié)議之上的協(xié)議,是Web瀏覽器和Web服務(wù)器之間的應用層的協(xié)議,是通用的、無狀態(tài)的面向?qū)ο蟮膮f(xié)議。
如果要實現(xiàn)網(wǎng)絡(luò)互聯(lián)我們要思考兩個需要解決的技術(shù)問題:
第一:瀏覽器和服務(wù)器是通過什么來連接的。第二:這種連接方式是怎么實現(xiàn)的。
通過Internet去發(fā)送到服務(wù)器當中,而Internet內(nèi)部可以通過三種方式來實現(xiàn)發(fā)送信息和數(shù)據(jù):
第一種:HTTP協(xié)議,也是在工作中最常用的,是建立在TCP/IP基礎(chǔ)上實現(xiàn)的。第二種:FTP協(xié)議第三種:TCP/IP協(xié)議,它也是最底層的協(xié)議,其它的方式必須是要通過它,但是要想實現(xiàn)這種協(xié)議必須要實現(xiàn)socket編程,這種方法是用來上傳一些比較大的文件,視頻,進行斷點續(xù)傳的操作。
2、客戶端連接服務(wù)器實現(xiàn)內(nèi)部的原理如下:
分析上圖,步驟如下:
第一步:在瀏覽器客戶端中得到用戶輸入的內(nèi)容。第二步:瀏覽器得到這個網(wǎng)址之后,內(nèi)部會將這個域名發(fā)送到DNS上,進行域名解析。得到它的IP之后就會鏈接到指定的服務(wù)器上,假如服務(wù)器的地址是:221.104.13.32:80,從瀏覽器到服務(wù)器端口它使用到最底層的TCP/IP協(xié)議。第三步:實現(xiàn)TCP/IP協(xié)議用Socket來完成,使用了Socket的套接字。第四步:服務(wù)器端的80端口監(jiān)聽客戶端的鏈接,這樣客戶端到服務(wù)器就鏈接上了。服務(wù)器接收到這些內(nèi)容之后,并按照這些請求的路徑找到對應的頁面,進一步找到對應的網(wǎng)頁內(nèi)容,返回給客戶端。
通俗一點講,用戶在瀏覽器輸入網(wǎng)址,通過http協(xié)議發(fā)出去,網(wǎng)址經(jīng)過DNS域名解析,解析成指定的ip地址,并在80端口上監(jiān)聽用戶的請求。服務(wù)器監(jiān)聽到請求之后,會以三種方式返回給客戶端:HTML、XML、JASON。
HTTP返回請求數(shù)據(jù)的三種方式:
1、以HTML代碼內(nèi)容返回。2、以XML字符串的形式返回,在以后的android開發(fā)中這種形式返回數(shù)據(jù)比較多。3、以JSON對象形式返回,在網(wǎng)絡(luò)流量上考慮JSON要比XML方式要好一些,便于解析。
在Android當中,一般使用xml和Json數(shù)據(jù)解析。
三、使用HTTP協(xié)議訪問網(wǎng)絡(luò):
Android中的WebView控件已經(jīng)在后臺幫我們處理好了發(fā)送HTTP請求、接收服務(wù)響應、解析返回數(shù)據(jù),以及最終的頁面展示這幾步工作,不過由于它封裝得太好了,反而不能直觀地看出HTTP協(xié)議是如何工作的。因此接下來我們通過手動發(fā)送HTTP請求的方式,來更加深入的了解這一過程。
在Android上發(fā)送HTTP請求的方式一般有兩種:HttpURLConnection和HttpCient。我們先來學習HttpCient。
四、HttpCient:
HttpClient是Apache開源組織提供的HTTP網(wǎng)絡(luò)訪問接口(一個開源的項目),從名字上就可以看出,它是一個簡單的HTTP客戶端(并不是瀏覽器),可以發(fā)送HTTP請求,接受HTTP響應。但是不會緩存服務(wù)器的響應,不能執(zhí)行HTTP頁面中簽入嵌入的JS代碼,自然也不會對頁面內(nèi)容進行任何解析、處理,這些都是需要開發(fā)人員來完成的。
現(xiàn)在Android已經(jīng)成功集成了HttpClient,所以開發(fā)人員在Android項目中可以直接使用HttpClient來想Web站點提交請求以及接受響應,如果使用其他的Java項目,需要引入進相應的Jar包。HttpClient可以在官網(wǎng)上下載。官網(wǎng)鏈接:http://hc.apache.org/downloads.cgi
HttpClient其實是一個interface類型,HttpClient封裝了對象需要執(zhí)行的Http請求、身份驗證、連接管理和其它特性。既然HttpClient是一個接口,因此無法創(chuàng)建它的實例。從文檔上看,HttpClient有三個已知的實現(xiàn)類分別是:AbstractHttpClient,
AndroidHttpClient, DefaultHttpClient,會發(fā)現(xiàn)有一個專門為Android應用準備的實現(xiàn)類AndroidHttpClient,當然使用常規(guī)的DefaultHttpClient也可以實現(xiàn)功能。
從兩個類包所有在位置就可以看出區(qū)別,AndroidHttpClient定義在android.net.http.AndroidHttpClient包下,屬于Android原生的http訪問,而DefaultHttpClient定義在org.apache.http.impl.client.DefaultHttpClient包下,屬于對apche項目的支持。而AndroidHttpClient沒有公開的構(gòu)造函數(shù),只能通過靜態(tài)方法newInstance()方法來獲得AndroidHttpClient對象。
簡單來說,用HttpClient發(fā)送請求、接收響應都很簡單,只需要五大步驟即可:(要牢記)
創(chuàng)建代表客戶端的HttpClient對象。創(chuàng)建代表請求的對象,如果需要發(fā)送GET請求,則創(chuàng)建HttpGet對象,如果需要發(fā)送POST請求,則創(chuàng)建HttpPost對象。注:對于發(fā)送請求的參數(shù),GET和POST使用的方式不同,GET方式可以使用拼接字符串的方式,把參數(shù)拼接在URL結(jié)尾;POST方式需要使用setEntity(HttpEntity
entity)方法來設(shè)置請求參數(shù)。
調(diào)用HttpClient對象的execute(HttpUriRequest request)發(fā)送請求,執(zhí)行該方法后,將獲得服務(wù)器返回的HttpResponse對象。服務(wù)器發(fā)還給我們的數(shù)據(jù)就在這個HttpResponse相應當中。調(diào)用HttpResponse的對應方法獲取服務(wù)器的響應頭、響應內(nèi)容等。
檢查相應狀態(tài)是否正常。服務(wù)器發(fā)給客戶端的相應,有一個相應碼:相應碼為200,正常;相應碼為404,客戶端錯誤;相應碼為505,服務(wù)器端錯誤。獲得相應對象當中的數(shù)據(jù)
五、DefaultHttpClient:
根據(jù)上面的五大步驟,我們就拿DefaultHttpClient舉例來訪問網(wǎng)絡(luò)。注意這里有一條原則:在主線程中不能訪問網(wǎng)絡(luò)(在android4.0之后的加入的概念)。
【實例】點擊按鈕,獲取百度首頁的文本內(nèi)容
新建工程文件m04_http01。完整版代碼如下:
首先是布局文件,雖然比較簡單,但還是貼上吧。
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" >
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send Request" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/TextView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</ScrollView>
</LinearLayout>
布局文件中,我們用一個ScrollView來包裹TextView。借助ScrollView控件的話,就可以允許我們一滾動的形式查看屏幕外i的那部分內(nèi)容。
MainActivity.java的代碼如下:(注釋比較詳細)
1 package com.example.m04_http01;
2
3 import org.apache.http.HttpEntity;
4 import org.apache.http.HttpResponse;
5 import org.apache.http.client.HttpClient;
6 import org.apache.http.client.methods.HttpGet;
7 import org.apache.http.impl.client.DefaultHttpClient;
8 import org.apache.http.util.EntityUtils;
9 import android.app.Activity;
10 import android.os.Bundle;
11 import android.os.Handler;
12 import android.os.Message;
13 import android.view.View;
14 import android.view.View.OnClickListener;
15 import android.widget.Button;
16 import android.widget.TextView;
17
18 public class MainActivity extends Activity {
19
20 public static final int SHOW_RESPONSE = 0;
21
22 private Button button_sendRequest;
23 private TextView textView_response;
24
25 //新建Handler的對象,在這里接收Message,然后更新TextView控件的內(nèi)容
26 private Handler handler = new Handler() {
27
28 @Override
29 public void handleMessage(Message msg) {
30 super.handleMessage(msg);
31 switch (msg.what) {
32 case SHOW_RESPONSE:
33 String response = (String) msg.obj;
34 textView_response.setText(response);
35 break;
36
37 default:
38 break;
39 }
40 }
41
42 };
43
44 @Override
45 protected void onCreate(Bundle savedInstanceState) {
46 super.onCreate(savedInstanceState);
47 setContentView(R.layout.activity_main);
48 textView_response = (TextView)findViewById(R.id.TextView1);
49 button_sendRequest = (Button)findViewById(R.id.button1);
50
51 button_sendRequest.setOnClickListener(new OnClickListener() {
52
53 //點擊按鈕時,執(zhí)行sendRequestWithHttpClient()方法里面的線程
54 @Override
55 public void onClick(View v) {
56 // TODO Auto-generated method stub
57 sendRequestWithHttpClient();
58 }
59 });
60 }
61
62 //方法:發(fā)送網(wǎng)絡(luò)請求,獲取百度首頁的數(shù)據(jù)。在里面開啟線程
63 private void sendRequestWithHttpClient() {
64 new Thread(new Runnable() {
65
66 @Override
67 public void run() {
68 //用HttpClient發(fā)送請求,分為五步
69 //第一步:創(chuàng)建HttpClient對象
70 HttpClient httpCient = new DefaultHttpClient();
71 //第二步:創(chuàng)建代表請求的對象,參數(shù)是訪問的服務(wù)器地址
72 HttpGet httpGet = new HttpGet("http://www.baidu.com");
73
74 try {
75 //第三步:執(zhí)行請求,獲取服務(wù)器發(fā)還的相應對象
76 HttpResponse httpResponse = httpCient.execute(httpGet);
77 //第四步:檢查相應的狀態(tài)是否正常:檢查狀態(tài)碼的值是200表示正常
78 if (httpResponse.getStatusLine().getStatusCode() == 200) {
79 //第五步:從相應對象當中取出數(shù)據(jù),放到entity當中
80 HttpEntity entity = httpResponse.getEntity();
81 String response = EntityUtils.toString(entity,"utf-8");//將entity當中的數(shù)據(jù)轉(zhuǎn)換為字符串
82
83 //在子線程中將Message對象發(fā)出去
84 Message message = new Message();
85 message.what = SHOW_RESPONSE;
86 message.obj = response.toString();
87 handler.sendMessage(message);
88 }
89
90 } catch (Exception e) {
91 // TODO Auto-generated catch block
92 e.printStackTrace();
93 }
94
95 }
96 }).start();//這個start()方法不要忘記了
97
98 }
99 }
大致流程如下:
這里,我們添加了一個sendRequestWithHttpClient()方法(第63行),并在點擊事件中去調(diào)用這個方法。在這個方法中,先開啟了一個子線程。
69至81行:在子線程中使用HttpClient發(fā)出一條HTTP請求,請求的目標地址是百度的首頁。
83至87行:為了能讓結(jié)果在界面上顯示出來,將服務(wù)器返回的數(shù)據(jù)放到了Message對象中,并用Handler將Message發(fā)出去。
需要注意的是:
第80行的entity就是服務(wù)器發(fā)還給客戶端的數(shù)據(jù)。
最后要記得在清單文件中聲明訪問網(wǎng)絡(luò)的權(quán)限:
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" /> <uses-permission android:name="android.permission.INTERNET"/>
程序運行后,點擊按鈕,顯示結(jié)果如下:
服務(wù)器返回給我們的就是這種HTML代碼,只是通常情況下瀏覽器都會將這些代碼解析成漂亮的網(wǎng)頁后再展示出來。
參考鏈接:
http://www.cnblogs.com/plokmju/p/Android_apacheHttpClient.html
總結(jié)
以上是生活随笔為你收集整理的Android之网络----使用HttpClient发送HTTP请求(通过get方法获取数据)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CentOs7 修复 引导启动
- 下一篇: java中变量的命名规则是什么