使用HTTP協議訪問網絡

1.使用HttpURLConnection

      在Android上發送HTTP請求的方式一般有兩種,HttpURLConnection和HttpClient,先學習一下HttpURLConnection的用法。

首先需要獲取到HttpURLConnection的實例,一般只需new出一個URL對象,並傳入目標的網絡地址,然後調用一下openConnection()方法即可,如下所示:

      URL url = new URL("http://www.baidu.com");

      HttpURLConnection connection=(HttpURLConnection) url.openConnection();

      得到了HttpURLConnection的實例之後,設置一下HTTP請求所使用的方法。常用的兩個方法爲get和post。get表示希望從服務器那裏獲取數據,而post則表示希望提交數據給服務器。寫法如下:

      connection.setRequestMethod("GET");

      此外就是設置連接超時,讀取超時的毫秒數,以及服務器希望得到的一些消息頭等。

      connection.setConnectTimeout(8000);

      connection.setReadTimeout(8000);

      之後就是在調用getInputStream()方法就可以獲取到服務器返回的輸入流了,剩下的任務就是對輸入流進行讀取,如下所示:

      InputStream in = connection.getInputStream();

      最後調用disconnect()方法將這個HTTP連接關閉掉,如下所示:

      connection.disconnect();

      新建一個Network項目,首先修改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/btnSendRequest"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="sendRequest"
        android:text="Send Request" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <TextView
            android:id="@+id/tvRespones"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
           
            android:text="TextView" />
    </ScrollView>

</LinearLayout>
      這裏我們用了一個新的控件ScrollView,借用ScrollView控件的話就可以允許我們以滾動的形式查看屏幕外的那部分內容。另外,佈局中還放置了一個Button和一個TextView

Button用於發送HTTP請求,TextView用於將服務器返回的數據顯示出來。

      接着修改MainActivity中的代碼,如下所示:

package com.example.nettest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
    private TextView tvResponse;
    public static final int SHOW_RESPONSE=1;
    private Handler handler=new Handler(){
    	public void handleMessage(android.os.Message msg) {
    		switch (msg.what) {
			case  SHOW_RESPONSE:
				String content=(String) msg.obj;
				tvResponse.setText(content);
				break;

			default:
				break;
			}
    	};
    };
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		tvResponse=(TextView) findViewById(R.id.tvRespones);
	}
	
	public void sendRequest(View view){
		sendRequestWithHttpUrlConnection();
	}

	private void sendRequestWithHttpUrlConnection() {
		new Thread(){
			public void run() {
				HttpURLConnection httpURLConnection=null;
		        try {//獲取HttpURLConnection的實例,new出對象,傳入目標的網絡地址,調用OpenConnection方法
					URL url=new URL("http://www.baidu.com");
					httpURLConnection=(HttpURLConnection) url.openConnection();
					httpURLConnection.setRequestMethod("GET");//get請求,從服務器那裏獲取數據
					httpURLConnection.setConnectTimeout(6000);//設置連接超時
					InputStream is=httpURLConnection.getInputStream();//獲取服務器返回的輸入流
					//下面是對獲取到的輸入流進行讀取
					BufferedReader br=new BufferedReader(new InputStreamReader(is));
					String s;
					StringBuilder sb=new StringBuilder();
					while((s=br.readLine())!=null){
						sb.append(s);
					}
					Message message=new Message();
					message.what=SHOW_RESPONSE;
					//將服務器返回的結果存放到Message中
					message.obj=sb.toString();
					handler.sendMessage(message);
					System.out.println("getContent="+sb.toString());
					
				} catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}finally{
					httpURLConnection.disconnect();//關閉Http連接
				}
			};
		}.start();
	}

}
       可以看到,我們在Send  Requset按鈕的點擊事件中調用了sendRequestWithHttpURLConnection()方法,在這個方法中先是開啓了子線程,然後在子線程中使用HttpURL-

Connection發出一條HTTP請求,請求的目標地址就是百度的首頁;接着利用BufferedReader對服務器返回的流進行讀取,並將結果存放到Message對象中。

       完整的一套流程就是這樣,在運行程序之前,不要忘了聲明一下網絡權限,修改AndroidMainifest.xml中的代碼,如下所示:

 <uses-permission android:name="android.permission.INTERNET"/>
程序運行結果如下所示:

2.使用HttpClient

       HttpClient是Apache提供的HTTP網絡訪問接口,從一開始的時候就被引用到了Android API中。它可以完成和HttpURLConnection幾乎一模一樣的效果,但兩者之間的用法卻

有很大的差別。

       首先我們要知道,HttpClient是一個接口,因此無法創建它的實例,這裏我們創建一個DefaultHttpClient的實例,如下所示:

       HttpClient  httpClient = new DefaultHttpClient();

       接下來如果想要發起一條get請求,就可以創建一個HttpGet對象,並傳入目標的網絡地址,然後調用HttpClient的execute()方法即可:

       HttpGet  httpGet= new HttpGet("http://www.baidu.com");

       httpClient.execute(httpGet);

       如果是發起一條POST請求會比get稍微複雜一些,我們要創建一個HttpPost對象,並傳入目標的網絡地址,如下所示:

       HttpPost  httpPost = new HttpPost("http://www.baidu.com");

       然後通過一個NameValuePair集合來存放待提交的參數,並將這個參數集合傳入到一個UrlEncodedEntity中,然後調用HttpPost的setEntity()方法將構建好的UrlEncodedEntity傳入,如下所示:

       List<NameValuePair> params =new ArrayList<NameValuePair>();

       params.add(newBasicNameValuePair("username", "admin"));

       params.add(newBasicNameValuePair("password", "123456"));

       UrlEncodedFormEntity entity = newUrlEncodedFormEntity(params, "utf-8");

       httpPost.setEntity(entity);

       然後調用HttpClient的execute()方法,並將HttpPost對象傳入:

       httpClient.execute(httpPost);

       執行execute()方法之後會返回一個HttpResponse對象,服務器所返回的所有信息就會包含在這裏面。通常情況下我們都會先取出服務器返回的狀態碼,如果等於200就說明請求和響應都成功了,如下所示:

       if (httpResponse.getStatusLine().getStatusCode()== 200) {

    //請求和響應都成功了

}

      接下來在這個if判斷的內部取出服務返回的具體內容,可以調用getEntity()方法獲取到一個HttpEntity實例,然後再用EntityUtils.toString()這個靜態方法將HttpEntity轉換成字符串即可,如下所示:

       HttpEntity entity =httpResponse.getEntity();

       String response = EntityUtils.toString(entity);

       如果服務器返回的數據是帶有中文的,直接調用EntityUtils.toString()方法進行轉換會有亂碼的情況出現,這個時候只需要在轉換的時候將字符集指定成utf-8就可以了,如下所示:

       String response =EntityUtils.toString(entity, "utf-8");

       由於佈局不用改動,直接修改MainActivity中的代碼,如下所示:

public class MainActivity extends Activity implements OnClickListener {
	……
	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.send_request) {
			sendRequestWithHttpClient();
		}
	}

	private void sendRequestWithHttpClient() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					HttpClient httpClient = new DefaultHttpClient();
					HttpGet httpGet = new HttpGet("http://www.baidu.com");
					HttpResponse httpResponse = httpClient.execute(httpGet);
					if (httpResponse.getStatusLine().getStatusCode() == 200) {
						// 請求和響應都成功了
						HttpEntity entity = httpResponse.getEntity();
						String response = EntityUtils.toString(entity, "utf-8");
						Message message = new Message();
						message.what = SHOW_RESPONSE;
						// 將服務器返回的結果存放到Message中
						message.obj = response.toString();
						handler.sendMessage(message);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
	}
	……
}

      這裏我們只是添加了一個sendRequestWithHttpClient()方法,並在Send Request按鈕的點擊事件裏去調用這個方法。在這個方法中同樣還是先開啓了一個子線程,然後在子線程裏使用HttpClient發出一條HTTP請求,請求的目標地址還是百度的首頁,HttpClient的用法也正如前面所介紹的一樣。然後爲了能讓結果在界面上顯示出來,這裏仍然是將服務器返回的數據存放到了Message對象中,並用Handler將Message發送出去。

僅僅只是改了這麼多代碼,現在我們可以重新運行一下程序了。點擊Send Request按鈕後,你會看到和上一小節中同樣的運行結果,由此證明,使用HttpClient來發送HTTP請求的功能也已經成功實現了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章