Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發請求網絡方式詳解

Android開發請求網絡方式詳解

編輯:關於Android編程

 

大家知道Google支持和發布的Android移動操作系統,主要是為了使其迅速占領移動互聯網的市場份額,所謂移動互聯網當然也是互聯網了,凡是涉及互聯網的任何軟件任何程序都少不了聯網模塊的開發,誠然Android聯網開發也是我們開發中至關重要的一部分,那麼Android是怎麼樣進行聯網操作的呢?這篇博客就簡單的介紹一下Android常用的聯網方式,包括JDK支持的HttpUrlConnection,Apache支持的HttpClient,以及開源的一些聯網框架(譬如AsyncHttpClient)的介紹。本篇博客只講實現過程和方式,不講解原理,否則原理用文字很難以講清,其實我們知道怎麼去用,就可以解決一些基本開發需要了。

絕大多數的Android應用聯網都是基於Http協議的,也有很少是基於Socket的,我們這裡主要講解基於Http協議的聯網方式。講解實例是建立在一個模擬的登錄小模塊中進行,登錄請求數據僅僅只有username和password兩個簡單字段。

 

HttpUrlConnection

HttpUrlConnection是JDK裡提供的聯網API,我們知道Android SDK是基於Java的,所以當然優先考慮HttpUrlConnection這種最原始最基本的API,其實大多數開源的聯網框架基本上也是基於JDK的HttpUrlConnection進行的封裝罷了,掌握HttpUrlConnection需要以下幾個步驟:

1將訪問的路徑轉換成URL。

 

URL url = new URL(path);

 

2,通過URL獲取連接。

 

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

 

3,設置請求方式。

 

conn.setRequestMethod(GET);

 

4,設置連接超時時間。

 

conn.setConnectTimeout(5000);

 

5,設置請求頭的信息。

 

conn.setRequestProperty(User-Agent, Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0));

 

6,獲取響應碼

 

int code = conn.getResponseCode();

 

7,針對不同的響應碼,做不同的操作

7.1,請求碼200,表明請求成功,獲取返回內容的輸入流

 

InputStream is = conn.getInputStream();

 

7.2,將輸入流轉換成字符串信息

 

public class StreamTools {
	/**
	 * 將輸入流轉換成字符串
	 * 
	 * @param is
	 *            從網絡獲取的輸入流
	 * @return
	 */
	public static String streamToString(InputStream is) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = is.read(buffer)) != -1) {
				baos.write(buffer, 0, len);
			}
			baos.close();
			is.close();
			byte[] byteArray = baos.toByteArray();
			return new String(byteArray);
		} catch (Exception e) {
			Log.e(tag, e.toString());
			return null;
		}
	}
}

 

7.3,若返回值400,則是返回網絡異常,做出響應的處理。

 

HttpUrlConnection發送GET請求

 

/**
	 * 通過HttpUrlConnection發送GET請求
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	public static String loginByGet(String username, String password) {
		String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username= + username + &password= + password;
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod(GET);
			int code = conn.getResponseCode();
			if (code == 200) {
				InputStream is = conn.getInputStream(); // 字節流轉換成字符串
				return StreamTools.streamToString(is);
			} else {
				return 網絡訪問失敗;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return 網絡訪問失敗;
		}
	}

 

HttpUrlConnection發送POST請求

/**
	 * 通過HttpUrlConnection發送POST請求
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	public static String loginByPost(String username, String password) {
		String path = http://192.168.0.107:8080/WebTest/LoginServerlet;
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod(POST);
			conn.setRequestProperty(Content-Type, application/x-www-form-urlencoded);
			String data = username= + username + &password= + password;
			conn.setRequestProperty(Content-Length, data.length() + );
			// POST方式,其實就是浏覽器把數據寫給服務器
			conn.setDoOutput(true); // 設置可輸出流
			OutputStream os = conn.getOutputStream(); // 獲取輸出流
			os.write(data.getBytes()); // 將數據寫給服務器
			int code = conn.getResponseCode();
			if (code == 200) {
				InputStream is = conn.getInputStream();
				return StreamTools.streamToString(is);
			} else {
				return 網絡訪問失敗;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return 網絡訪問失敗;
		}
	}

HttpClient

HttpClient是開源組織Apache提供的Java請求網絡框架,其最早是為了方便Java服務器開發而誕生的,是對JDK中的HttpUrlConnection各API進行了封裝和簡化,提高了性能並且降低了調用API的繁瑣,Android因此也引進了這個聯網框架,我們再不需要導入任何jar或者類庫就可以直接使用,值得注意的是Android官方已經宣布不建議使用HttpClient了,我們再開發的時候盡量少用吧,但是用了也無妨!

HttpClient發送GET請求

1, 創建HttpClient對象

2,創建HttpGet對象,指定請求地址(帶參數)

3,使用HttpClient的execute(),方法執行HttpGet請求,得到HttpResponse對象

4,調用HttpResponse的getStatusLine().getStatusCode()方法得到響應碼

5,調用的HttpResponse的getEntity().getContent()得到輸入流,獲取服務端寫回的數據

/**
	 * 通過HttpClient發送GET請求
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	public static String loginByHttpClientGet(String username, String password) {
		String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username=
				+ username + &password= + password;
		HttpClient client = new DefaultHttpClient(); // 開啟網絡訪問客戶端
		HttpGet httpGet = new HttpGet(path); // 包裝一個GET請求
		try {
			HttpResponse response = client.execute(httpGet); // 客戶端執行請求
			int code = response.getStatusLine().getStatusCode(); // 獲取響應碼
			if (code == 200) {
				InputStream is = response.getEntity().getContent(); // 獲取實體內容
				String result = StreamTools.streamToString(is); // 字節流轉字符串
				return result;
			} else {
				return 網絡訪問失敗;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return 網絡訪問失敗;
		}
	}

HttpClient發送POST請求

1,創建HttpClient對象

2,創建HttpPost對象,指定請求地址

3,創建List,用來裝載參數

4,調用HttpPost對象的setEntity()方法,裝入一個UrlEncodedFormEntity對象,攜帶之前封裝好的參數

5,使用HttpClient的execute()方法執行HttpPost請求,得到HttpResponse對象

6, 調用HttpResponse的getStatusLine().getStatusCode()方法得到響應碼

7, 調用的HttpResponse的getEntity().getContent()得到輸入流,獲取服務端寫回的數據

/**
	 * 通過HttpClient發送POST請求
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	public static String loginByHttpClientPOST(String username, String password) {
		String path = http://192.168.0.107:8080/WebTest/LoginServerlet;
		try {
			HttpClient client = new DefaultHttpClient(); // 建立一個客戶端
			HttpPost httpPost = new HttpPost(path); // 包裝POST請求
			// 設置發送的實體參數
			List parameters = new ArrayList();
			parameters.add(new BasicNameValuePair(username, username));
			parameters.add(new BasicNameValuePair(password, password));
			httpPost.setEntity(new UrlEncodedFormEntity(parameters, UTF-8));
			HttpResponse response = client.execute(httpPost); // 執行POST請求
			int code = response.getStatusLine().getStatusCode();
			if (code == 200) {
				InputStream is = response.getEntity().getContent();
				String result = StreamTools.streamToString(is);
				return result;
			} else {
				return 網絡訪問失敗;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return 訪問網絡失敗;
		}
	}

其他開源聯網框架

AsyncHttpClient

除了上述Android官方推薦的聯網框架以外,在開源世界裡關於聯網框架真是太多太多了,例如afinal,xutils等等,都是一些開源大牛自己封裝的聯網框架,並且在GitHub開源社區中可以下載到,其實類似的開源聯網框架基本上也是基於HttpUrlConnection的進一步封裝,大大提高了性能,同時更加簡化了使用方法,這裡使用AsyncHttpClient作為案例,其他的聯網框架大家可以去網上找,下載使用試試便可。 AsyncHttpClient是一個非常優秀的聯網框架,不僅支持所有Http請求的方式,而且還支持文件的上傳和下載,要知道用HttpUrlConnection寫一個文件上傳和下載健全功能是很需要花費一定時間和精力的,因為請求頭實在是太多了,稍有不慎就會寫錯。但是AsyncHttpClient已經封裝好了這些“麻煩”,我們只需要下載到AsyncHttpClient的jar包或者源碼導入項目中,Http,上傳,下載等等,只需要幾個簡單的api即可搞定。 AsyncHttpClient的GitHub主頁:https://github.com/AsyncHttpClient/async-http-client/

AsyncHttpClient發送GET請求

1,將下載好的源碼拷貝到src目錄下

2,創建一個AsyncHttpClient的對象

3,調用該類的get方法發送GET請求,傳入請求資源地址URL,創建AsyncHttpResponseHandler對象

4,重寫AsyncHttpResponseHandler下的兩個方法,onSuccess和onFailure方法

 

/**
	 * 通過AsyncHttpClient發送GET請求
	 */
	public void loginByAsyncHttpGet() {
		String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username=zhangsan&password=123;
		AsyncHttpClient client = new AsyncHttpClient();
		client.get(path, new AsyncHttpResponseHandler() {

			@Override
			public void onFailure(int arg0, Header[] arg1, byte[] arg2,
					Throwable arg3) {
				// TODO Auto-generated method stub
				Log.i(TAG, 請求失敗: + new String(arg2));
			}

			@Override
			public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
				// TODO Auto-generated method stub
				Log.i(TAG, 請求成功: + new String(arg2));
			}
		});
	}

 

AsyncHttpClient發送POST請求

1,將下載好的源碼拷貝到src目錄下

2,創建一個AsyncHttpClient的對象

3,創建請求參數,RequestParams對象

4,調用該類的post方法發POST,傳入請求資源地址URL,請求參數RequestParams,創建AsyncHttpResponseHandler對象

5,重寫AsyncHttpResponseHandler下的兩個方法,onSuccess和onFailure方法

/**
	 * 通過AsyncHttpClient發送POST請求
	 */
	public void loginByAsyncHttpPost() {
		String path = http://192.168.0.107:8080/WebTest/LoginServerlet;
		AsyncHttpClient client = new AsyncHttpClient();
		RequestParams params = new RequestParams();
		params.put(username, zhangsan);
		params.put(password, 123);
		client.post(path, params, new AsyncHttpResponseHandler() {

			@Override
			public void onFailure(int arg0, Header[] arg1, byte[] arg2,
					Throwable arg3) {
				// TODO Auto-generated method stub
				Log.i(TAG, 請求失敗: + new String(arg2));
			}

			@Override
			public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
				// TODO Auto-generated method stub
				Log.i(TAG, 請求成功: + new String(arg2));
			}
		});
	}

AsyncHttpClient上傳文件

1,將下載好的源碼拷貝到src目錄下

2,創建一個AsyncHttpClient的對象

3,創建請求參數,RequestParams對象,請求參數僅僅包含文件對象即可,例如:

 

params.put(profile_picture, new File(/sdcard/pictures/pic.jpg));

 

4,調用該類的post方法發POST,傳入請求資源地址URL,請求參數RequestParams,創建AsyncHttpResponseHandler對象

5,重寫AsyncHttpResponseHandler下的兩個方法,onSuccess和onFailure方法

 

判斷網絡連接狀態

很多時候對於手機或者平板電腦這樣的手持設備,我們是不知道它們的網絡連接狀態的,在聯網的時候我們必須得保證設備的網路是否正常,是否可以連接上互聯網,或者我們在進行大量數據上傳或者下載,例如下載網路視頻,看網路電視等等,我們必須得為用戶省錢,這樣大數據的傳輸顯然是不能使用用戶昂貴的數據流量的,而是判斷當前網絡是不是在wifi下,使用WiFi來進行大數據的傳輸,會給用戶更好的體驗,那麼下面這個工具類就是用來判斷設備網絡連接狀態的,不僅判斷了當前設置手機網絡下還是WiFi環境下,而且如果手機網絡下還需要設置運營商的代理IP和端口。

 

/**
 * 判斷網絡狀態的工具類
 * 
 */
public class NetworkUtil {

	/* 代碼IP */
	private static String PROXY_IP = null;
	/* 代理端口 */
	private static int PROXY_PORT = 0;
	/**
	 * 判斷當前是否有網絡連接
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isNetwork(Context context) {
		boolean network = isWifi(context);
		boolean mobilework = isMobile(context);
		if (!network && !mobilework) { // 無網絡連接
			Log.i(NetworkUtil, 無網路鏈接!);
			return false;
		} else if (network == true && mobilework == false) { // wifi連接
			Log.i(NetworkUtil, wifi連接!);
		} else { // 網絡連接
			Log.i(NetworkUtil, 手機網路連接,讀取代理信息!);
			readProxy(context); // 讀取代理信息
			return true;
		}
		return true;
	}

	/**
	 * 讀取網絡代理
	 * 
	 * @param context
	 */
	private static void readProxy(Context context) {
		Uri uri = Uri.parse(content://telephony/carriers/preferapn);
		ContentResolver resolver = context.getContentResolver();
		Cursor cursor = resolver.query(uri, null, null, null, null);
		if (cursor != null && cursor.moveToFirst()) {
			PROXY_IP = cursor.getString(cursor.getColumnIndex(proxy));
			PROXY_PORT = cursor.getInt(cursor.getColumnIndex(port));
		}
		cursor.close();
	}

	/**
	 * 判斷當前網絡是否是wifi局域網
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isWifi(Context context) {
		ConnectivityManager manager = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo info = manager
				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		if (info != null) {
			return info.isConnected(); // 返回網絡連接狀態
		}
		return false;
	}

	/**
	 * 判斷當前網絡是否是手機網絡
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isMobile(Context context) {
		ConnectivityManager manager = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo info = manager
				.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
		if (info != null) {
			return info.isConnected(); // 返回網絡連接狀態
		}
		return false;
	}
}

 

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