Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android基礎之十七使用網絡技術

Android基礎之十七使用網絡技術

編輯:關於Android編程

本章主要會講述如何在手機端使用HTTP協議和服務器端進行網絡交互,並對服務器返回的數據進行解析,這也是Android中最常使用到的網絡技術了,下面就讓我們一起來學習一下吧。

1 WebView的用法

 

借助它我們就可以在自己的應用程序裡嵌入一個浏覽器,從而非常輕松地展示各種各樣的網頁

WebView的用法也是相當簡單,下面我們就通過一個例子來學習一下吧。新建一個WebViewTest項目,然後修改activity_main.xml中的代碼,如下所示

	

    

可以看到,我們在布局文件中使用到了一個新的控件,WebView。這個控件當然也就是用來顯示網頁的了,這裡的寫法很簡單,給它設置了一個id,並讓它充滿整個屏幕。

然後修改MainActivity中的代碼,如下所示:

package com.example.webview;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MainActivity extends Activity {
	private WebView webview;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		webview=(WebView) findViewById(R.id.web_view);
		webview.getSettings().setJavaScriptEnabled(true);
		webview.setWebViewClient(new WebViewClient() {
			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {    
				view.loadUrl(url); // 根據傳入的參數再去加載新的網頁
				return true; // 表示當前WebView可以處理打開新網頁的請求,不用借助系統浏覽器
			}
		});
		webview.loadUrl("http://www.baidu.com");
	}
	@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;
	}
	

}

MainActivity中的代碼也很短,首先使用findViewById()方法獲取到了WebView的實例,然後調用WebView的getSettings()方法可以去設置一些浏覽器的屬性,這裡我們並不去設置過多的屬性,只是調用了setJavaScriptEnabled()方法來讓WebView支持JavaScript腳本。

接下來是非常重要的一個部分,我們調用了WebView的setWebViewClient()方法,並傳入了WebViewClient的匿名類作為參數,然後重寫了shouldOverrideUrlLoading()方法。這就表明當需要從一個網頁跳轉到另一個網頁時,我們希望目標網頁仍然在當前WebView中顯示,而不是打開系統浏覽器。


最後一步就非常簡單了,調用WebView的loadUrl()方法,並將網址傳入


另外還需要注意,由於本程序使用到了網絡功能,而訪問網絡是需要聲明權限的,因此我們還得修改AndroidManifest.xml文件,並加入權限聲明,如下所示:


    ……
    
    ……
\

 

2 使用HTTP協議訪問網絡

它的工作原理特別的簡單,就是客戶端向服務器發出一條HTTP請求,服務器收到請求之後會返回一些數據給客戶端,然後客戶端再對這些數據進行解析和處理就可以了。

 

2.1 使用HttpURLConnection

在Android上發送HTTP請求的方式一般有兩種,HttpURLConnectionHttpClient,本小節我們先來學習一下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();

下面就讓我們通過一個具體的例子來真正體驗一下HttpURLConnection的用法。新建一個NetworkTest項目,首先修改activity_main.xml中的代碼,如下所示:

 

注意這裡我們使用了一個新的控件,ScrollView,它是用來做什麼的呢?由於手機屏幕的空間一般都比較小,有些時候過多的內容一屏是顯示不下的,借助ScrollView控件的話就可以允許我們以滾動的形式查看屏幕外的那部分內容。另外,布局中還放置了一個Button和一個TextView,Button用於發送HTTP請求,TextView用於將服務器返回的數據顯示出來。

 

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

public class MainActivity extends Activity implements OnClickListener {

	public static final int SHOW_RESPONSE = 0;

	private Button sendRequest;

	private TextView responseText;

	private Handler handler = new Handler() {

		public void handleMessage(Message msg) {
			switch (msg.what) {
			case SHOW_RESPONSE:
				String response = (String) msg.obj;
				// 在這裡進行UI操作,將結果顯示到界面上
				responseText.setText(response);
			}
		}

	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		sendRequest = (Button) findViewById(R.id.send_request);
		responseText = (TextView) findViewById(R.id.response_text);
		sendRequest.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.send_request) {
			sendRequestWithHttpURLConnection();
		}
	}

	private void sendRequestWithHttpURLConnection() {
		// 開啟線程來發起網絡請求
		new Thread(new Runnable() {
			@Override
			public void run() {
				HttpURLConnection connection = null;
				try {
					URL url = new URL("http://www.baidu.com");
					connection = (HttpURLConnection) url.openConnection();
					connection.setRequestMethod("GET");
					connection.setConnectTimeout(8000);
					connection.setReadTimeout(8000);
					InputStream in = connection.getInputStream();
					// 下面對獲取到的輸入流進行讀取
				BufferedReader reader = new BufferedReader(new InputStreamReader(in));	
					StringBuilder response = new StringBuilder();
					String line;
					while ((line = reader.readLine()) != null) {
						response.append(line);
					}
					Message message = new Message();
					message.what = SHOW_RESPONSE;
					// 將服務器返回的結果存放到Message中
					message.obj = response.toString();
					handler.sendMessage(message);
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					if (connection != null) {
						connection.disconnect();
					}
				}
			}
		}).start();
	}

}

以看到,我們在Send Request按鈕的點擊事件裡調用了sendRequestWithHttpURL- Connection()方法,在這個方法中先是開啟了一個子線程,然後在子線程裡使用HttpURLConnection發出一條HTTP請求,請求的目標地址就是百度的首頁。接著利用BufferedReader對服務器返回的流進行讀取,並將結果存放到了一個Message對象中。這裡為什麼要使用Message對象呢?當然是因為子線程中無法對UI進行操作了。我們希望可以將服務器返回的內容顯示到界面上,所以就創建了一個Message對象,並使用Handler將它發送出去。之後又在Handler的handleMessage()方法中對這條Message進行處理,最終取出結果並設置到TextView上。

過在開始運行之前,仍然別忘了要聲明一下網絡權限。修改AndroidManifest.xml中的代碼



    ……
    
    ……

好了,現在運行一下程序,並點擊Send Request按鈕,結果如圖2所示。

\
這是返回的 htmL格式,另外如果也可以以json數據的格式返回。

 

那麼如果是想要提交數據給服務器應該怎麼辦呢?其實也不復雜,只需要將HTTP請求的方法改成POST,並在獲取輸入流之前把要提交的數據寫出即可。注意每條數據都要以鍵值對的形式存在,數據與數據之間用&符號隔開,比如說我們想要向服務器提交用戶名和密碼,就可以這樣寫:

connection.setRequestMethod("POST");

DataOutputStream out = new DataOutputStream(connection.getOutputStream());

out.writeBytes("username=admin&password=123456");

2.2 使用HttpClient

HttpClient是Apache提供的HTTP網絡訪問接口,從一開始的時候就被引入到了Android API中。它可以完成和HttpURLConnection幾乎一模一樣的效果,但兩者之間的用法卻有較大的差別,那麼我們自然要看一下HttpClient是如何使用的了。

首先你需要知道,HttpClient是一個接口,因此無法創建它的實例,通常情況下都會創建一個DefaultHttpClient的實例,如下所示:

HttpClient httpClient = new DefaultHttpClient();

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

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

httpClient.execute(httpGet);

並傳入目標的網絡地址,如下所示:

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

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

List params = new ArrayList();

params.add(new BasicNameValuePair("username", "admin"));

params.add(new BasicNameValuePair("password", "123456"));

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

httpPost.setEntity(entity);

接下來的操作就和HttpGet一樣了,調用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");

好了,基本的用法就是如此,接下來就讓我們把NetworkTest這個項目改用HttpClient的方式再實現一遍吧。

由於布局部分完全不用改動,所以現在直接修改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();
	}
	……
}



 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved