編輯:關於Android編程
大家知道Google支持和發布的Android移動操作系統,主要是為了使其迅速占領移動互聯網的市場份額,所謂移動互聯網當然也是互聯網了,凡是涉及互聯網的任何軟件任何程序都少不了聯網模塊的開發,誠然Android聯網開發也是我們開發中至關重要的一部分,那麼Android是怎麼樣進行聯網操作的呢?這篇博客就簡單的介紹一下Android常用的聯網方式,包括JDK支持的HttpUrlConnection,Apache支持的HttpClient,以及開源的一些聯網框架(譬如AsyncHttpClient)的介紹。本篇博客只講實現過程和方式,不講解原理,否則原理用文字很難以講清,其實我們知道怎麼去用,就可以解決一些基本開發需要了。
絕大多數的Android應用聯網都是基於Http協議的,也有很少是基於Socket的,我們這裡主要講解基於Http協議的聯網方式。講解實例是建立在一個模擬的登錄小模塊中進行,登錄請求數據僅僅只有username和password兩個簡單字段。
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請求 * * @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請求 * * @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 網絡訪問失敗; } }
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 網絡訪問失敗; } }
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請求 // 設置發送的實體參數 Listparameters = 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 訪問網絡失敗; } }
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)); } }); }
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)); } }); }
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.初始置換/IP置換// 初始置換表 private static final int[] IP_Table = { 58, 50, 42, 34, 26, 18, 1
Android M新控件有很多,Toolbar,TabLayout,AppBarLayout,NavigationView,CoordinatorLayout,Colla
說明:android的線程使用。android的線程無非就是Main Thread和Worker Thread。(除了主線程Main Thread之外的其他線程都是Wor
轉載請著名出處:http://blog.csdn.net/lijunhuayc 搞了這麼久android我居然不知道lint工具是干啥的,雖然每次在eclip